Skip to main content
ClaudeWave
Slash Command89 repo starsupdated 1mo ago

spec

Generate complete feature specification with research, requirements analysis, and quality validation

Install in Claude Code
Copy
mkdir -p ~/.claude/commands && curl -fsSL https://raw.githubusercontent.com/marcusgoll/Spec-Flow/HEAD/.claude/commands/phases/spec.md -o ~/.claude/commands/spec.md
Then start a new Claude Code session; the slash command loads automatically.

spec.md

# /spec — Feature Specification Generator (Thin Wrapper)

> **v11.0 Architecture**: This command is now a thin wrapper that spawns the isolated `spec-phase-agent` via Task(). All specification logic runs in an isolated context with question batching for user interaction.

<context>
**User Input**: $ARGUMENTS

**Active Feature**: !`ls -td specs/[0-9]*-* 2>/dev/null | head -1 || echo "none"`

**Interaction State**: !`cat specs/*/interaction-state.yaml 2>/dev/null | head -10 || echo "none"`
</context>

<objective>
Spawn isolated spec-phase-agent to generate production-grade feature specification.

**Architecture (v11.0 - Full Phase Isolation):**

```
/spec command (this file)
    │
    ▼
┌──────────────────────────────────────────────────────┐
│ 1. Detect feature directory                          │
│ 2. Initialize interaction-state.yaml if needed       │
│ 3. Check for pending answers from previous session   │
│ 4. Spawn Task(spec-phase-agent)                      │
│ 5. Handle agent result:                              │
│    - needs_input → AskUserQuestion → re-spawn        │
│    - completed → update state.yaml                   │
│    - failed → log error, pause workflow              │
└──────────────────────────────────────────────────────┘
```

**Benefits:**
- Main context stays lightweight (no spec details in memory)
- Unlimited specification complexity
- Resumable at any point
- Observable Q&A history in interaction-state.yaml

**Workflow position**: `spec → clarify? → plan → tasks → implement → optimize → ship`
</objective>

<process>

## Step 0: Ultrathink Checkpoint — Think Different

> **Philosophy**: "Is this solving the real problem or a symptom?"

Before generating any specification, pause to question assumptions.

**Display thinking prompt:**

```
┌─────────────────────────────────────────────────────────────┐
│ 💭 ULTRATHINK CHECKPOINT: Think Different                   │
├─────────────────────────────────────────────────────────────┤
│ Before specifying, consider:                                │
│                                                             │
│ • Is this the REAL problem or just a symptom?               │
│ • What assumptions are we making about users?               │
│ • What would the simplest solution look like?               │
│ • Is this a feature, or a symptom of a missing feature?     │
└─────────────────────────────────────────────────────────────┘
```

**Create assumption inventory** (inline in spec.md):

```markdown
## Assumption Inventory

| # | Assumption | Source | Challenge | Status |
|---|------------|--------|-----------|--------|
| 1 | [assumption from user input] | User request | [challenge question] | [validated/changed/removed] |
```

**Complexity check** - determine thinking depth:

```bash
# Check ultrathink config
ULTRATHINK_CONFIG=".spec-flow/config/ultrathink-integration.yaml"

# For spec phase, checkpoint always triggers (lightweight)
# but assumption inventory depth varies:
# - Trivial: Skip inventory, just proceed
# - Standard: Inline inventory in spec.md
# - Complex/Epic: Separate assumption-inventory.md artifact
```

**Quick assumption questions** (ask if ambiguity detected):

```json
{
  "question": "Before we specify, let's validate the core assumption. What problem is this REALLY solving?",
  "header": "Real Problem",
  "multiSelect": false,
  "options": [
    {"label": "As stated", "description": "The user's description captures the real problem"},
    {"label": "Symptom of larger issue", "description": "This is a symptom - we should address the root cause"},
    {"label": "Needs reframing", "description": "The problem statement needs to be reframed"}
  ]
}
```

**If "Symptom" or "Needs reframing" selected**, prompt for clarification before proceeding.

---

## Step 1: Detect Feature Directory

```bash
FEATURE_DIR=$(ls -td specs/[0-9]*-* 2>/dev/null | head -1)
STATE_FILE="$FEATURE_DIR/state.yaml"
INTERACTION_FILE="$FEATURE_DIR/interaction-state.yaml"

# For new features, FEATURE_DIR may not exist yet
# The spec-phase-agent will create it
if [ -z "$FEATURE_DIR" ]; then
    echo "📋 Creating new feature specification..."
    FEATURE_DIR="specs/NEW"  # Placeholder, agent will create actual directory
fi
```

## Step 2: Initialize Interaction State

```bash
# Initialize interaction state if feature exists but no interaction file
if [ -d "$FEATURE_DIR" ] && [ ! -f "$INTERACTION_FILE" ]; then
    bash .spec-flow/scripts/bash/interaction-manager.sh init "$FEATURE_DIR"
fi
```

## Step 3: Check for Pending Answers

```bash
# Check for pending questions from previous session
PENDING=$(bash .spec-flow/scripts/bash/interaction-manager.sh get-pending "$FEATURE_DIR" 2>/dev/null)
if [ -n "$PENDING" ] && [ "$PENDING" != "null" ]; then
    echo "📋 Resuming with pending answers from previous session"
    HAS_ANSWERS=true
else
    HAS_ANSWERS=false
fi
```

## Step 4: Spawn Spec Phase Agent

```javascript
// Spawn isolated spec-phase-agent via Task()
const agentResult = await Task({
  subagent_type: "spec-phase-agent",
  prompt: `
    Execute SPEC phase for feature:

    User input: $ARGUMENTS
    Feature directory: ${FEATURE_DIR}
    ${HAS_ANSWERS ? `
    Resume from: ${pendingAnswers.resume_from}
    Answers provided: ${JSON.stringify(pendingAnswers.answers)}
    ` : ''}

    Generate complete feature specification with requirements and quality validation.
    Return structured phase_result with status, artifacts, and any questions.
  `
});

const result = agentResult.phase_result;
```

## Step 5: Handle Agent Result

```javascript
// === CASE 1: Agent needs user input ===
if (result.status === "needs_input") {
  console.log(`\n📋 Specification needs user input`);

  // Save questions to interaction-state.yaml
  await Bash(`bash .spec-flow/scripts/bash/interaction-manager.sh save-questions "${FEATURE_DIR}" "spec" '${JSON.stringify(result)}'`);

  // Ask user via AskUserQuestion
  const userAnswers = await AskUserQuestion({
    questions: