Compare commits

...
Author SHA1 Message Date
Tabish Bidiwale 5ee9e56305 feat: add /opsx:explore command for exploratory thinking
Wire up the explore skill and slash command templates to the
artifact-experimental-setup command. This adds /opsx:explore as
a thinking partner mode for exploring ideas, investigating problems,
and clarifying requirements before committing to a change.

Changes:
- Add imports for getExploreSkillTemplate and getOpsxExploreCommandTemplate
- Add explore skill to skills array (generates openspec-explore/SKILL.md)
- Add explore command to commands array (generates opsx/explore.md)
- Add /opsx:explore to CLI usage message
- Update docs/experimental-workflow.md with explore command
2026-01-09 20:12:05 -08:00
3 changed files with 498 additions and 21 deletions
+8
View File
@@ -82,6 +82,7 @@ This creates skills in `.claude/skills/` that Claude Code auto-detects.
| Command | What it does |
|---------|--------------|
| `/opsx:explore` | Think through ideas, investigate problems, clarify requirements |
| `/opsx:new` | Start a new change |
| `/opsx:continue` | Create the next artifact (based on what's ready) |
| `/opsx:ff` | Fast-forward — create all planning artifacts at once |
@@ -91,6 +92,12 @@ This creates skills in `.claude/skills/` that Claude Code auto-detects.
## Usage
### Explore an idea
```
/opsx:explore
```
Think through ideas, investigate problems, compare options. No structure required - just a thinking partner. When insights crystallize, transition to `/opsx:new` or `/opsx:ff`.
### Start a new change
```
/opsx:new
@@ -520,6 +527,7 @@ Run `openspec schemas` to see available schemas.
## Tips
- Use `/opsx:explore` to think through an idea before committing to a change
- `/opsx:ff` when you know what you want, `/opsx:continue` when exploring
- During `/opsx:apply`, if something's wrong — fix the artifact, then continue
- Tasks track progress via checkboxes in `tasks.md`
+6 -1
View File
@@ -28,7 +28,7 @@ import {
type SchemaInfo,
} from '../core/artifact-graph/index.js';
import { createChange, validateChangeName } from '../utils/change-utils.js';
import { getNewChangeSkillTemplate, getContinueChangeSkillTemplate, getApplyChangeSkillTemplate, getFfChangeSkillTemplate, getSyncSpecsSkillTemplate, getArchiveChangeSkillTemplate, getOpsxNewCommandTemplate, getOpsxContinueCommandTemplate, getOpsxApplyCommandTemplate, getOpsxFfCommandTemplate, getOpsxSyncCommandTemplate, getOpsxArchiveCommandTemplate } from '../core/templates/skill-templates.js';
import { getExploreSkillTemplate, getNewChangeSkillTemplate, getContinueChangeSkillTemplate, getApplyChangeSkillTemplate, getFfChangeSkillTemplate, getSyncSpecsSkillTemplate, getArchiveChangeSkillTemplate, getOpsxExploreCommandTemplate, getOpsxNewCommandTemplate, getOpsxContinueCommandTemplate, getOpsxApplyCommandTemplate, getOpsxFfCommandTemplate, getOpsxSyncCommandTemplate, getOpsxArchiveCommandTemplate } from '../core/templates/skill-templates.js';
import { FileSystemUtils } from '../utils/file-system.js';
// -----------------------------------------------------------------------------
@@ -793,6 +793,7 @@ async function artifactExperimentalSetupCommand(): Promise<void> {
const commandsDir = path.join(projectRoot, '.claude', 'commands', 'opsx');
// Get skill templates
const exploreSkill = getExploreSkillTemplate();
const newChangeSkill = getNewChangeSkillTemplate();
const continueChangeSkill = getContinueChangeSkillTemplate();
const applyChangeSkill = getApplyChangeSkillTemplate();
@@ -801,6 +802,7 @@ async function artifactExperimentalSetupCommand(): Promise<void> {
const archiveChangeSkill = getArchiveChangeSkillTemplate();
// Get command templates
const exploreCommand = getOpsxExploreCommandTemplate();
const newCommand = getOpsxNewCommandTemplate();
const continueCommand = getOpsxContinueCommandTemplate();
const applyCommand = getOpsxApplyCommandTemplate();
@@ -810,6 +812,7 @@ async function artifactExperimentalSetupCommand(): Promise<void> {
// Create skill directories and SKILL.md files
const skills = [
{ template: exploreSkill, dirName: 'openspec-explore' },
{ template: newChangeSkill, dirName: 'openspec-new-change' },
{ template: continueChangeSkill, dirName: 'openspec-continue-change' },
{ template: applyChangeSkill, dirName: 'openspec-apply-change' },
@@ -840,6 +843,7 @@ ${template.instructions}
// Create slash command files
const commands = [
{ template: exploreCommand, fileName: 'explore.md' },
{ template: newCommand, fileName: 'new.md' },
{ template: continueCommand, fileName: 'continue.md' },
{ template: applyCommand, fileName: 'apply.md' },
@@ -898,6 +902,7 @@ ${template.content}
console.log(' • "Implement the tasks for this change"');
console.log();
console.log(' ' + chalk.cyan('Slash Commands') + ' for explicit invocation:');
console.log(' • /opsx:explore - Think through ideas, investigate problems');
console.log(' • /opsx:new - Start a new change');
console.log(' • /opsx:continue - Create the next artifact');
console.log(' • /opsx:apply - Implement tasks');
+484 -20
View File
@@ -14,6 +14,292 @@ export interface SkillTemplate {
instructions: string;
}
/**
* Template for openspec-explore skill
* Explore mode - adaptive thinking partner for exploring ideas and problems
*/
export function getExploreSkillTemplate(): SkillTemplate {
return {
name: 'openspec-explore',
description: 'Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change.',
instructions: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
---
## The Stance
- **Curious, not prescriptive** - Ask questions that emerge naturally, don't follow a script
- **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
- **Adaptive** - Follow interesting threads, pivot when new information emerges
- **Patient** - Don't rush to conclusions, let the shape of the problem emerge
- **Grounded** - Explore the actual codebase when relevant, don't just theorize
---
## What You Might Do
Depending on what the user brings, you might:
**Explore the problem space**
- Ask clarifying questions that emerge from what they said
- Challenge assumptions
- Reframe the problem
- Find analogies
**Investigate the codebase**
- Map existing architecture relevant to the discussion
- Find integration points
- Identify patterns already in use
- Surface hidden complexity
**Compare options**
- Brainstorm multiple approaches
- Build comparison tables
- Sketch tradeoffs
- Recommend a path (if asked)
**Visualize**
\`\`\`
┌─────────────────────────────────────────┐
│ Use ASCII diagrams liberally │
├─────────────────────────────────────────┤
│ │
│ ┌────────┐ ┌────────┐ │
│ │ State │────────▶│ State │ │
│ │ A │ │ B │ │
│ └────────┘ └────────┘ │
│ │
│ System diagrams, state machines, │
│ data flows, architecture sketches, │
│ dependency graphs, comparison tables │
│ │
└─────────────────────────────────────────┘
\`\`\`
**Surface risks and unknowns**
- Identify what could go wrong
- Find gaps in understanding
- Suggest spikes or investigations
---
## OpenSpec Awareness
You have full context of the OpenSpec system. Use it naturally, don't force it.
### Check for context
At the start, quickly check what exists:
\`\`\`bash
openspec list --json
\`\`\`
This tells you:
- If there are active changes
- Their names, schemas, and status
- What the user might be working on
### When no change exists
Think freely. When insights crystallize, you might offer:
- "This feels solid enough to start a change. Want me to create one?"
→ Can transition to \`/opsx:new\` or \`/opsx:ff\`
- Or keep exploring - no pressure to formalize
### When a change exists
If the user mentions a change or you detect one is relevant:
1. **Read existing artifacts for context**
- \`openspec/changes/<name>/proposal.md\`
- \`openspec/changes/<name>/design.md\`
- \`openspec/changes/<name>/tasks.md\`
- etc.
2. **Reference them naturally in conversation**
- "Your design mentions using Redis, but we just realized SQLite fits better..."
- "The proposal scopes this to premium users, but we're now thinking everyone..."
3. **Offer to capture when decisions are made**
| Insight Type | Where to Capture |
|--------------|------------------|
| New requirement discovered | \`specs/<capability>/spec.md\` |
| Requirement changed | \`specs/<capability>/spec.md\` |
| Design decision made | \`design.md\` |
| Scope changed | \`proposal.md\` |
| New work identified | \`tasks.md\` |
| Assumption invalidated | Relevant artifact |
Example offers:
- "That's a design decision. Capture it in design.md?"
- "This is a new requirement. Add it to specs?"
- "This changes scope. Update the proposal?"
4. **The user decides** - Offer and move on. Don't pressure. Don't auto-capture.
---
## What You Don't Have To Do
- Follow a script
- Ask the same questions every time
- Produce a specific artifact
- Reach a conclusion
- Stay on topic if a tangent is valuable
- Be brief (this is thinking time)
---
## Handling Different Entry Points
**User brings a vague idea:**
\`\`\`
User: I'm thinking about adding real-time collaboration
You: Real-time collab is a big space. Let me think about this...
COLLABORATION SPECTRUM
════════════════════════════════════════════
Awareness Coordination Sync
│ │ │
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│Presence│ │Cursors │ │ CRDT │
│ "3 │ │ Multi │ │Conflict│
│online" │ │ select │ │ free │
└────────┘ └────────┘ └────────┘
│ │ │
trivial moderate complex
Where's your head at?
\`\`\`
**User brings a specific problem:**
\`\`\`
User: The auth system is a mess
You: [reads codebase]
┌─────────────────────────────────────────────┐
│ CURRENT AUTH FLOW │
└─────────────────────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Google │ │ GitHub │ │ Email │
│ OAuth │ │ OAuth │ │ Magic │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└─────────────┼─────────────┘
▼
┌───────────┐
│ Session │
└─────┬─────┘
│
▼
┌───────────┐
│ Perms │
└───────────┘
I see three tangles. Which one's burning?
\`\`\`
**User is stuck mid-implementation:**
\`\`\`
User: /opsx:explore add-auth-system
The OAuth integration is more complex than expected
You: [reads change artifacts]
You're on task 4: "Implement OAuth flow"
Let me trace what's involved...
[draws diagram, explores options, suggests paths]
Want to update the design to reflect this?
Or add a spike task to investigate?
\`\`\`
**User wants to compare options:**
\`\`\`
User: Should we use Postgres or SQLite?
You: Generic answer is boring. What's the context?
User: A CLI tool that tracks local dev environments
You: That changes everything.
┌─────────────────────────────────────────────────┐
│ CLI TOOL DATA STORAGE │
└─────────────────────────────────────────────────┘
Key constraints:
• No daemon running
• Must work offline
• Single user
SQLite Postgres
Deployment embedded ✓ needs server ✗
Offline yes ✓ no ✗
Single file yes ✓ no ✗
SQLite. Not even close.
Unless... is there a sync component?
\`\`\`
---
## Ending Discovery
There's no required ending. Discovery might:
- **Flow into action**: "Ready to start? /opsx:new or /opsx:ff"
- **Result in artifact updates**: "Updated design.md with these decisions"
- **Just provide clarity**: User has what they need, moves on
- **Continue later**: "We can pick this up anytime"
When it feels like things are crystallizing, you might summarize:
\`\`\`
## What We Figured Out
**The problem**: [crystallized understanding]
**The approach**: [if one emerged]
**Open questions**: [if any remain]
**Next steps** (if ready):
- Create a change: /opsx:new <name>
- Fast-forward to tasks: /opsx:ff <name>
- Keep exploring: just keep talking
\`\`\`
But this summary is optional. Sometimes the thinking IS the value.
---
## Guardrails
- **Don't fake understanding** - If something is unclear, dig deeper
- **Don't rush** - Discovery is thinking time, not task time
- **Don't force structure** - Let patterns emerge naturally
- **Don't auto-capture** - Offer to save insights, don't just do it
- **Do visualize** - A good diagram is worth many paragraphs
- **Do explore the codebase** - Ground discussions in reality
- **Do question assumptions** - Including the user's and your own`
};
}
/**
* Template for openspec-new-change skill
* Based on /opsx:new command
@@ -37,21 +323,22 @@ export function getNewChangeSkillTemplate(): SkillTemplate {
**IMPORTANT**: Do NOT proceed without understanding what the user wants to build.
2. **Select a workflow schema**
2. **Determine the workflow schema**
Run \`openspec schemas --json\` to get available schemas with descriptions.
Use the default schema (omit \`--schema\`) unless the user explicitly requests a different workflow.
Use the **AskUserQuestion tool** to let the user choose a workflow:
- Present each schema with its description
- Mark \`spec-driven\` as "(default)" if it's available
- Example options: "spec-driven - proposal → specs → design → tasks (default)", "tdd - tests → implementation → docs"
**Use a different schema only if the user mentions:**
- "tdd" or "test-driven" → use \`--schema tdd\`
- A specific schema name → use \`--schema <name>\`
- "show workflows" or "what workflows" → run \`openspec schemas --json\` and let them choose
If user doesn't have a preference, default to \`spec-driven\`.
**Otherwise**: Omit \`--schema\` to use the default.
3. **Create the change directory**
\`\`\`bash
openspec new change "<name>" --schema "<selected-schema>"
openspec new change "<name>"
\`\`\`
Add \`--schema <name>\` only if the user requested a specific workflow.
This creates a scaffolded change at \`openspec/changes/<name>/\` with the selected schema.
4. **Show the artifact status**
@@ -74,7 +361,7 @@ export function getNewChangeSkillTemplate(): SkillTemplate {
After completing the steps, summarize:
- Change name and location
- Selected schema/workflow and its artifact sequence
- Schema/workflow being used and its artifact sequence
- Current status (0/N artifacts complete)
- The template for the first artifact
- Prompt: "Ready to create the first artifact? Just describe what this change is about and I'll draft it, or ask me to continue."
@@ -84,7 +371,7 @@ After completing the steps, summarize:
- Do NOT advance beyond showing the first artifact template
- If the name is invalid (not kebab-case), ask for a valid name
- If a change with that name already exists, suggest continuing that change instead
- Always pass --schema to preserve the user's workflow choice`
- Pass --schema if using a non-default workflow`
};
}
@@ -605,6 +892,182 @@ export interface CommandTemplate {
content: string;
}
/**
* Template for /opsx:explore slash command
* Explore mode - adaptive thinking partner
*/
export function getOpsxExploreCommandTemplate(): CommandTemplate {
return {
name: 'OPSX: Explore',
description: 'Enter explore mode - think through ideas, investigate problems, clarify requirements',
category: 'Workflow',
tags: ['workflow', 'explore', 'experimental', 'thinking'],
content: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
**Input**: The argument after \`/opsx:explore\` is whatever the user wants to think about. Could be:
- A vague idea: "real-time collaboration"
- A specific problem: "the auth system is getting unwieldy"
- A change name: "add-dark-mode" (to explore in context of that change)
- A comparison: "postgres vs sqlite for this"
- Nothing (just enter explore mode)
---
## The Stance
- **Curious, not prescriptive** - Ask questions that emerge naturally, don't follow a script
- **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
- **Adaptive** - Follow interesting threads, pivot when new information emerges
- **Patient** - Don't rush to conclusions, let the shape of the problem emerge
- **Grounded** - Explore the actual codebase when relevant, don't just theorize
---
## What You Might Do
Depending on what the user brings, you might:
**Explore the problem space**
- Ask clarifying questions that emerge from what they said
- Challenge assumptions
- Reframe the problem
- Find analogies
**Investigate the codebase**
- Map existing architecture relevant to the discussion
- Find integration points
- Identify patterns already in use
- Surface hidden complexity
**Compare options**
- Brainstorm multiple approaches
- Build comparison tables
- Sketch tradeoffs
- Recommend a path (if asked)
**Visualize**
\`\`\`
┌─────────────────────────────────────────┐
│ Use ASCII diagrams liberally │
├─────────────────────────────────────────┤
│ │
│ ┌────────┐ ┌────────┐ │
│ │ State │────────▶│ State │ │
│ │ A │ │ B │ │
│ └────────┘ └────────┘ │
│ │
│ System diagrams, state machines, │
│ data flows, architecture sketches, │
│ dependency graphs, comparison tables │
│ │
└─────────────────────────────────────────┘
\`\`\`
**Surface risks and unknowns**
- Identify what could go wrong
- Find gaps in understanding
- Suggest spikes or investigations
---
## OpenSpec Awareness
You have full context of the OpenSpec system. Use it naturally, don't force it.
### Check for context
At the start, quickly check what exists:
\`\`\`bash
openspec list --json
\`\`\`
This tells you:
- If there are active changes
- Their names, schemas, and status
- What the user might be working on
If the user mentioned a specific change name, read its artifacts for context.
### When no change exists
Think freely. When insights crystallize, you might offer:
- "This feels solid enough to start a change. Want me to create one?"
→ Can transition to \`/opsx:new\` or \`/opsx:ff\`
- Or keep exploring - no pressure to formalize
### When a change exists
If the user mentions a change or you detect one is relevant:
1. **Read existing artifacts for context**
- \`openspec/changes/<name>/proposal.md\`
- \`openspec/changes/<name>/design.md\`
- \`openspec/changes/<name>/tasks.md\`
- etc.
2. **Reference them naturally in conversation**
- "Your design mentions using Redis, but we just realized SQLite fits better..."
- "The proposal scopes this to premium users, but we're now thinking everyone..."
3. **Offer to capture when decisions are made**
| Insight Type | Where to Capture |
|--------------|------------------|
| New requirement discovered | \`specs/<capability>/spec.md\` |
| Requirement changed | \`specs/<capability>/spec.md\` |
| Design decision made | \`design.md\` |
| Scope changed | \`proposal.md\` |
| New work identified | \`tasks.md\` |
| Assumption invalidated | Relevant artifact |
Example offers:
- "That's a design decision. Capture it in design.md?"
- "This is a new requirement. Add it to specs?"
- "This changes scope. Update the proposal?"
4. **The user decides** - Offer and move on. Don't pressure. Don't auto-capture.
---
## What You Don't Have To Do
- Follow a script
- Ask the same questions every time
- Produce a specific artifact
- Reach a conclusion
- Stay on topic if a tangent is valuable
- Be brief (this is thinking time)
---
## Ending Discovery
There's no required ending. Discovery might:
- **Flow into action**: "Ready to start? \`/opsx:new\` or \`/opsx:ff\`"
- **Result in artifact updates**: "Updated design.md with these decisions"
- **Just provide clarity**: User has what they need, moves on
- **Continue later**: "We can pick this up anytime"
When things crystallize, you might offer a summary - but it's optional. Sometimes the thinking IS the value.
---
## Guardrails
- **Don't fake understanding** - If something is unclear, dig deeper
- **Don't rush** - Discovery is thinking time, not task time
- **Don't force structure** - Let patterns emerge naturally
- **Don't auto-capture** - Offer to save insights, don't just do it
- **Do visualize** - A good diagram is worth many paragraphs
- **Do explore the codebase** - Ground discussions in reality
- **Do question assumptions** - Including the user's and your own`
};
}
/**
* Template for /opsx:new slash command
*/
@@ -629,21 +1092,22 @@ export function getOpsxNewCommandTemplate(): CommandTemplate {
**IMPORTANT**: Do NOT proceed without understanding what the user wants to build.
2. **Select a workflow schema**
2. **Determine the workflow schema**
Run \`openspec schemas --json\` to get available schemas with descriptions.
Use the default schema (omit \`--schema\`) unless the user explicitly requests a different workflow.
Use the **AskUserQuestion tool** to let the user choose a workflow:
- Present each schema with its description
- Mark \`spec-driven\` as "(default)" if it's available
- Example options: "spec-driven - proposal → specs → design → tasks (default)", "tdd - tests → implementation → docs"
**Use a different schema only if the user mentions:**
- "tdd" or "test-driven" → use \`--schema tdd\`
- A specific schema name → use \`--schema <name>\`
- "show workflows" or "what workflows" → run \`openspec schemas --json\` and let them choose
If user doesn't have a preference, default to \`spec-driven\`.
**Otherwise**: Omit \`--schema\` to use the default.
3. **Create the change directory**
\`\`\`bash
openspec new change "<name>" --schema "<selected-schema>"
openspec new change "<name>"
\`\`\`
Add \`--schema <name>\` only if the user requested a specific workflow.
This creates a scaffolded change at \`openspec/changes/<name>/\` with the selected schema.
4. **Show the artifact status**
@@ -665,7 +1129,7 @@ export function getOpsxNewCommandTemplate(): CommandTemplate {
After completing the steps, summarize:
- Change name and location
- Selected schema/workflow and its artifact sequence
- Schema/workflow being used and its artifact sequence
- Current status (0/N artifacts complete)
- The template for the first artifact
- Prompt: "Ready to create the first artifact? Run \`/opsx:continue\` or just describe what this change is about and I'll draft it."
@@ -675,7 +1139,7 @@ After completing the steps, summarize:
- Do NOT advance beyond showing the first artifact template
- If the name is invalid (not kebab-case), ask for a valid name
- If a change with that name already exists, suggest using \`/opsx:continue\` instead
- Always pass --schema to preserve the user's workflow choice`
- Pass --schema if using a non-default workflow`
};
}