feat: add multi-mode workflow planning skill with session management and task generation

This commit is contained in:
catlog22
2026-03-02 15:25:56 +08:00
parent 2c2b9d6e29
commit 121e834459
28 changed files with 6478 additions and 533 deletions

View File

@@ -0,0 +1,725 @@
---
name: brainstorm
description: |
Dual-mode brainstorming pipeline. Auto mode: framework generation → parallel role analysis
(spawn_agents_on_csv) → cross-role synthesis. Single role mode: individual role analysis.
CSV-driven parallel coordination with NDJSON discovery board.
argument-hint: "[-y|--yes] [--count N] [--session ID] [--skip-questions] [--style-skill PKG] \"topic\" | <role-name> [--session ID]"
allowed-tools: spawn_agents_on_csv, spawn_agent, wait, send_input, close_agent, AskUserQuestion, Read, Write, Edit, Bash, Glob, Grep
---
## Auto Mode
When `--yes` or `-y`: Auto-select auto mode, auto-select recommended roles, skip all clarification questions, use defaults.
# Brainstorm
## Usage
```bash
$brainstorm "Build real-time collaboration platform" --count 3
$brainstorm -y "Design payment system" --count 5
$brainstorm "Build notification system" --style-skill material-design
$brainstorm system-architect --session WFS-xxx
$brainstorm ux-expert --include-questions
```
**Flags**:
- `-y, --yes`: Skip all confirmations (auto mode)
- `--count N`: Number of roles to select (default: 3, max: 9)
- `--session ID`: Use existing session
- `--skip-questions / --include-questions`: Control interactive Q&A per role
- `--style-skill PKG`: Style skill package for ui-designer
- `--update`: Update existing role analysis
---
## Overview
Dual-mode brainstorming with CSV-driven parallel role analysis. Auto mode runs a full pipeline; single role mode runs one role analysis independently.
```
┌──────────────────────────────────────────────────────────────────┐
│ BRAINSTORM PIPELINE │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Phase 1: Mode Detection & Routing │
│ ├─ Parse flags and arguments │
│ └─ Route to Auto Mode or Single Role Mode │
│ │
│ ═══ Auto Mode ═══ │
│ │
│ Phase 2: Interactive Framework Generation │
│ ├─ Context collection → Topic analysis → Role selection │
│ ├─ Generate guidance-specification.md │
│ ├─ Generate roles.csv (1 row per selected role) │
│ └─ User validates (skip if -y) │
│ │
│ Phase 3: Wave Role Analysis (spawn_agents_on_csv) │
│ ├─ spawn_agents_on_csv(role instruction template) │
│ ├─ Each role agent produces analysis.md + sub-documents │
│ └─ discoveries.ndjson shared across role agents │
│ │
│ Phase 4: Synthesis Integration │
│ ├─ Read all role analyses (read-only) │
│ ├─ Cross-role analysis → conflict detection │
│ ├─ Feature spec generation │
│ └─ Output: feature-specs/ + feature-index.json │
│ │
│ ═══ Single Role Mode ═══ │
│ │
│ Phase 3S: Single Role Analysis (spawn_agent) │
│ ├─ spawn_agent(conceptual-planning-agent) │
│ └─ Output: {role}/analysis*.md │
│ │
└──────────────────────────────────────────────────────────────────┘
```
---
## Context Flow
```
roles.csv feature-specs/
┌──────────────┐ ┌──────────────────┐
│ R1: sys-arch │──findings───→│ F-001-auth.md │
│ analysis.md │ │ (cross-role spec) │
├──────────────┤ ├──────────────────┤
│ R2: ui-design│──findings───→│ F-002-ui.md │
│ analysis.md │ │ (cross-role spec) │
├──────────────┤ ├──────────────────┤
│ R3: test-str │──findings───→│ F-003-test.md │
│ analysis.md │ │ (cross-role spec) │
└──────────────┘ └──────────────────┘
Two context channels:
1. Directed: role findings → synthesis → feature specs
2. Broadcast: discoveries.ndjson (append-only shared board)
```
---
## CSV Schema
### roles.csv
```csv
id,role,title,focus,deps,wave,status,findings,output_files,error
"R1","system-architect","系统架构师","Technical architecture, scalability","","1","pending","","",""
"R2","ui-designer","UI设计师","Visual design, mockups","","1","pending","","",""
"R3","test-strategist","测试策略师","Test strategy, quality","","1","pending","","",""
```
**Columns**:
| Column | Phase | Description |
|--------|-------|-------------|
| `id` | Input | Role ID: R1, R2, ... |
| `role` | Input | Role identifier (e.g., system-architect) |
| `title` | Input | Role display title |
| `focus` | Input | Role focus areas and keywords |
| `deps` | Input | Dependency IDs (usually empty — all wave 1) |
| `wave` | Computed | Wave number (usually 1 for all roles) |
| `status` | Output | `pending``completed` / `failed` |
| `findings` | Output | Key discoveries (max 800 chars) |
| `output_files` | Output | Generated analysis files (semicolon-separated) |
| `error` | Output | Error message if failed |
---
## Available Roles
| Role ID | Title | Focus Area |
|---------|-------|------------|
| `data-architect` | 数据架构师 | Data models, storage strategies, data flow |
| `product-manager` | 产品经理 | Product strategy, roadmap, prioritization |
| `product-owner` | 产品负责人 | Backlog management, user stories, acceptance criteria |
| `scrum-master` | 敏捷教练 | Process facilitation, impediment removal |
| `subject-matter-expert` | 领域专家 | Domain knowledge, business rules, compliance |
| `system-architect` | 系统架构师 | Technical architecture, scalability, integration |
| `test-strategist` | 测试策略师 | Test strategy, quality assurance |
| `ui-designer` | UI设计师 | Visual design, mockups, design systems |
| `ux-expert` | UX专家 | User research, information architecture, journey |
---
## Session Structure
```
.workflow/active/WFS-{topic}/
├── workflow-session.json # Session metadata
├── .process/
│ └── context-package.json # Phase 0 context
├── roles.csv # Role analysis state (Phase 2-3)
├── discoveries.ndjson # Shared discovery board
└── .brainstorming/
├── guidance-specification.md # Framework (Phase 2)
├── feature-index.json # Feature index (Phase 4)
├── synthesis-changelog.md # Synthesis audit trail (Phase 4)
├── feature-specs/ # Feature specs (Phase 4)
│ ├── F-001-{slug}.md
│ └── F-00N-{slug}.md
└── {role}/ # Role analyses (Phase 3, immutable)
├── {role}-context.md # Interactive Q&A
├── analysis.md # Main/index document
├── analysis-cross-cutting.md # Cross-feature
└── analysis-F-{id}-{slug}.md # Per-feature
```
---
## Implementation
### Session Initialization
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
// Parse flags
const AUTO_YES = $ARGUMENTS.includes('--yes') || $ARGUMENTS.includes('-y')
const countMatch = $ARGUMENTS.match(/--count\s+(\d+)/)
const roleCount = countMatch ? Math.min(parseInt(countMatch[1]), 9) : 3
const sessionMatch = $ARGUMENTS.match(/--session\s+(\S+)/)
const existingSessionId = sessionMatch ? sessionMatch[1] : null
const skipQuestions = $ARGUMENTS.includes('--skip-questions')
const includeQuestions = $ARGUMENTS.includes('--include-questions')
const styleSkillMatch = $ARGUMENTS.match(/--style-skill\s+(\S+)/)
const styleSkill = styleSkillMatch ? styleSkillMatch[1] : null
const updateMode = $ARGUMENTS.includes('--update')
// Role detection
const VALID_ROLES = [
'data-architect', 'product-manager', 'product-owner', 'scrum-master',
'subject-matter-expert', 'system-architect', 'test-strategist',
'ui-designer', 'ux-expert'
]
const cleanArgs = $ARGUMENTS
.replace(/--yes|-y|--count\s+\d+|--session\s+\S+|--skip-questions|--include-questions|--style-skill\s+\S+|--update/g, '')
.trim()
const firstArg = cleanArgs.split(/\s+/)[0]
const isRole = VALID_ROLES.includes(firstArg)
// Mode detection
let executionMode
if (AUTO_YES) {
executionMode = 'auto'
} else if (isRole) {
executionMode = 'single-role'
} else if (cleanArgs) {
executionMode = 'auto'
} else {
executionMode = null // Ask user
}
const topic = isRole
? cleanArgs.replace(firstArg, '').trim()
: cleanArgs.replace(/^["']|["']$/g, '')
```
---
### Phase 1: Mode Detection & Routing
**Objective**: Parse arguments, determine execution mode, prepare session.
**Steps**:
1. **Detect Mode**
```javascript
if (executionMode === null) {
const modeAnswer = AskUserQuestion({
questions: [{
question: "Choose brainstorming mode:",
header: "Mode",
multiSelect: false,
options: [
{ label: "Auto Mode (Recommended)", description: "Full pipeline: framework → parallel roles → synthesis" },
{ label: "Single Role", description: "Run one role analysis independently" }
]
}]
})
executionMode = modeAnswer.Mode.startsWith('Auto') ? 'auto' : 'single-role'
}
```
2. **Session Setup**
```javascript
let sessionId, sessionFolder
if (existingSessionId) {
sessionId = existingSessionId
sessionFolder = `.workflow/active/${sessionId}`
} else if (executionMode === 'auto') {
const slug = topic.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, '-').substring(0, 40)
sessionId = `WFS-${slug}`
sessionFolder = `.workflow/active/${sessionId}`
Bash(`mkdir -p "${sessionFolder}/.brainstorming" "${sessionFolder}/.process"`)
// Initialize workflow-session.json
Write(`${sessionFolder}/workflow-session.json`, JSON.stringify({
session_id: sessionId,
topic: topic,
status: 'brainstorming',
execution_mode: executionMode,
created_at: getUtc8ISOString()
}, null, 2))
} else {
// Single role mode requires existing session
const existing = Bash(`ls -d .workflow/active/WFS-* 2>/dev/null | head -1`).trim()
if (!existing) {
console.log('ERROR: No active session found. Run auto mode first to create a session.')
return
}
sessionId = existing.split('/').pop()
sessionFolder = existing
}
```
**Route**:
- `executionMode === 'auto'` → Phase 2
- `executionMode === 'single-role'` → Phase 3S
---
### Phase 2: Interactive Framework Generation (Auto Mode)
**Objective**: Analyze topic, select roles, generate guidance-specification.md and roles.csv.
**Steps**:
1. **Analyze Topic & Select Roles**
```javascript
Bash({
command: `ccw cli -p "PURPOSE: Analyze brainstorming topic and recommend ${roleCount} expert roles for multi-perspective analysis. Success = well-matched roles with clear focus areas.
TASK:
• Analyze topic domain, complexity, and key dimensions
• Select ${roleCount} roles from: data-architect, product-manager, product-owner, scrum-master, subject-matter-expert, system-architect, test-strategist, ui-designer, ux-expert
• For each role: define focus area, key questions, and analysis scope
• Identify potential cross-role conflicts or synergies
• Generate feature decomposition if topic has distinct components
MODE: analysis
CONTEXT: @**/*
EXPECTED: JSON: {analysis: {domain, complexity, dimensions[]}, roles: [{id, role, title, focus, key_questions[]}], features: [{id, title, description}]}
CONSTRAINTS: Select exactly ${roleCount} roles | Each role must have distinct perspective | Roles must cover topic comprehensively
TOPIC: ${topic}" --tool gemini --mode analysis --rule planning-breakdown-task-steps`,
run_in_background: true
})
// Wait for CLI completion → { analysis, roles[], features[] }
```
2. **User Validation** (skip if AUTO_YES)
```javascript
if (!AUTO_YES) {
console.log(`\n## Brainstorm Framework\n`)
console.log(`Topic: ${topic}`)
console.log(`Domain: ${analysis.domain} | Complexity: ${analysis.complexity}`)
console.log(`\nSelected Roles (${roles.length}):`)
roles.forEach(r => console.log(` - [${r.id}] ${r.title}: ${r.focus}`))
if (features.length > 0) {
console.log(`\nFeatures (${features.length}):`)
features.forEach(f => console.log(` - [${f.id}] ${f.title}`))
}
const answer = AskUserQuestion({
questions: [{
question: "Approve brainstorm framework?",
header: "Validate",
multiSelect: false,
options: [
{ label: "Approve", description: "Proceed with role analysis" },
{ label: "Modify Roles", description: "Change role selection" },
{ label: "Cancel", description: "Abort" }
]
}]
})
if (answer.Validate === "Cancel") return
if (answer.Validate === "Modify Roles") {
// Allow user to adjust via AskUserQuestion
const roleAnswer = AskUserQuestion({
questions: [{
question: "Select roles for analysis:",
header: "Roles",
multiSelect: true,
options: VALID_ROLES.map(r => ({
label: r,
description: roles.find(sel => sel.role === r)?.focus || ''
}))
}]
})
// Rebuild roles[] from selection
}
}
```
3. **Generate Guidance Specification**
```javascript
const guidanceContent = `# Guidance Specification
## Topic
${topic}
## Analysis
- **Domain**: ${analysis.domain}
- **Complexity**: ${analysis.complexity}
- **Dimensions**: ${analysis.dimensions.join(', ')}
## Selected Roles
${roles.map(r => `### ${r.title} (${r.role})
- **Focus**: ${r.focus}
- **Key Questions**: ${r.key_questions.join('; ')}`).join('\n\n')}
## Features
${features.map(f => `- **[${f.id}] ${f.title}**: ${f.description}`).join('\n')}
`
Write(`${sessionFolder}/.brainstorming/guidance-specification.md`, guidanceContent)
```
4. **Generate roles.csv**
```javascript
const header = 'id,role,title,focus,deps,wave,status,findings,output_files,error'
const rows = roles.map(r =>
[r.id, r.role, r.title, r.focus, '', '1', 'pending', '', '', '']
.map(v => `"${String(v).replace(/"/g, '""')}"`)
.join(',')
)
Write(`${sessionFolder}/roles.csv`, [header, ...rows].join('\n'))
```
Update workflow-session.json with selected_roles.
---
### Phase 3: Wave Role Analysis (spawn_agents_on_csv) — Auto Mode
**Objective**: Execute parallel role analysis via `spawn_agents_on_csv`. Each role agent produces analysis documents.
**Steps**:
1. **Role Analysis Wave**
```javascript
const rolesCSV = parseCsv(Read(`${sessionFolder}/roles.csv`))
console.log(`\n## Phase 3: Parallel Role Analysis (${rolesCSV.length} roles)\n`)
spawn_agents_on_csv({
csv_path: `${sessionFolder}/roles.csv`,
id_column: "id",
instruction: buildRoleInstruction(sessionFolder, topic, features),
max_concurrency: Math.min(rolesCSV.length, 4),
max_runtime_seconds: 600,
output_csv_path: `${sessionFolder}/roles-results.csv`,
output_schema: {
type: "object",
properties: {
id: { type: "string" },
status: { type: "string", enum: ["completed", "failed"] },
findings: { type: "string" },
output_files: { type: "array", items: { type: "string" } },
error: { type: "string" }
},
required: ["id", "status", "findings"]
}
})
// Merge results into roles.csv
const roleResults = parseCsv(Read(`${sessionFolder}/roles-results.csv`))
for (const result of roleResults) {
updateMasterCsvRow(`${sessionFolder}/roles.csv`, result.id, {
status: result.status,
findings: result.findings || '',
output_files: Array.isArray(result.output_files) ? result.output_files.join(';') : (result.output_files || ''),
error: result.error || ''
})
console.log(` [${result.id}] ${result.status === 'completed' ? '✓' : '✗'} ${rolesCSV.find(r => r.id === result.id)?.role}`)
}
Bash(`rm -f "${sessionFolder}/roles-results.csv"`)
```
2. **Role Instruction Template**
```javascript
function buildRoleInstruction(sessionFolder, topic, features) {
const featureList = features.length > 0
? features.map(f => `- [${f.id}] ${f.title}: ${f.description}`).join('\n')
: 'No feature decomposition — analyze topic holistically.'
return `
## ROLE ANALYSIS ASSIGNMENT
### MANDATORY FIRST STEPS
1. Read guidance specification: ${sessionFolder}/.brainstorming/guidance-specification.md
2. Read shared discoveries: ${sessionFolder}/discoveries.ndjson (if exists)
3. Read project context: .workflow/project-tech.json (if exists)
---
## Your Role
**Role ID**: {id}
**Role**: {role}
**Title**: {title}
**Focus**: {focus}
---
## Topic
${topic}
## Features to Analyze
${featureList}
---
## Analysis Protocol
1. **Read guidance**: Load guidance-specification.md for full context
2. **Read discoveries**: Load discoveries.ndjson for shared findings from other roles
3. **Analyze from your perspective**: Apply your role expertise to the topic
4. **Per-feature analysis** (if features exist):
- Create \`${sessionFolder}/.brainstorming/{role}/analysis-{feature-id}-{slug}.md\` per feature
- Create \`${sessionFolder}/.brainstorming/{role}/analysis-cross-cutting.md\` for cross-feature concerns
5. **Create index document**: \`${sessionFolder}/.brainstorming/{role}/analysis.md\`
- Summary of all findings
- Links to sub-documents
- Key recommendations
6. **Share discoveries**: Append findings to shared board:
\`\`\`bash
echo '{"ts":"<ISO8601>","worker":"{id}","type":"<type>","data":{...}}' >> ${sessionFolder}/discoveries.ndjson
\`\`\`
7. **Report result**: Return JSON via report_agent_job_result
### Document Constraints
- Main analysis.md: < 3000 words
- Sub-documents: < 2000 words each, max 5
- Total per role: < 15000 words
### Discovery Types to Share
- \`design_pattern\`: {name, rationale, applicability} — recommended patterns
- \`risk\`: {area, severity, mitigation} — identified risks
- \`requirement\`: {title, priority, source} — derived requirements
- \`constraint\`: {type, description, impact} — discovered constraints
- \`synergy\`: {roles[], area, description} — cross-role opportunities
---
## Output (report_agent_job_result)
Return JSON:
{
"id": "{id}",
"status": "completed" | "failed",
"findings": "Key insights from {role} perspective (max 800 chars)",
"output_files": ["path/to/analysis.md", "path/to/analysis-F-001.md"],
"error": ""
}
`
}
```
---
### Phase 3S: Single Role Analysis (spawn_agent) — Single Role Mode
**Objective**: Run one role analysis via spawn_agent with optional interactive Q&A.
```javascript
if (executionMode === 'single-role') {
const roleName = firstArg
const roleDir = `${sessionFolder}/.brainstorming/${roleName}`
Bash(`mkdir -p "${roleDir}"`)
const agentId = spawn_agent({
agent: `~/.codex/agents/conceptual-planning-agent.md`,
instruction: `
Perform a ${roleName} analysis for the brainstorming session.
**Session**: ${sessionFolder}
**Role**: ${roleName}
**Topic**: Read from ${sessionFolder}/.brainstorming/guidance-specification.md
${includeQuestions ? '**Mode**: Interactive — ask clarification questions before analysis' : ''}
${skipQuestions ? '**Mode**: Skip questions — proceed directly to analysis' : ''}
${styleSkill ? `**Style Skill**: ${styleSkill} — load .claude/skills/style-${styleSkill}/ for design reference` : ''}
${updateMode ? '**Update Mode**: Read existing analysis and enhance/update it' : ''}
**Output**: Create analysis documents in ${roleDir}/
- ${roleDir}/analysis.md (main index)
- ${roleDir}/analysis-*.md (sub-documents as needed)
Follow the same analysis protocol as wave role analysis but with interactive refinement.
`
})
wait({ id: agentId })
close_agent({ id: agentId })
console.log(`\n✓ ${roleName} analysis complete: ${roleDir}/analysis.md`)
}
```
---
### Phase 4: Synthesis Integration (Auto Mode)
**Objective**: Read all role analyses, cross-reference, generate feature specs.
**Steps**:
1. **Collect Role Findings**
```javascript
const rolesCSV = parseCsv(Read(`${sessionFolder}/roles.csv`))
const completedRoles = rolesCSV.filter(r => r.status === 'completed')
// Read all analysis.md index files (optimized: skip sub-docs for token efficiency)
const roleAnalyses = {}
for (const role of completedRoles) {
const indexPath = `${sessionFolder}/.brainstorming/${role.role}/analysis.md`
const content = Read(indexPath)
if (content) roleAnalyses[role.role] = content
}
// Read discoveries
const discoveriesPath = `${sessionFolder}/discoveries.ndjson`
const discoveries = Read(discoveriesPath) || ''
```
2. **Synthesis via Agent**
```javascript
const synthesisAgent = spawn_agent({
agent: `~/.codex/agents/conceptual-planning-agent.md`,
instruction: `
## SYNTHESIS ASSIGNMENT
Synthesize ${completedRoles.length} role analyses into unified feature specifications.
**Session**: ${sessionFolder}
**Role Analyses**: ${completedRoles.map(r => `${sessionFolder}/.brainstorming/${r.role}/analysis.md`).join(', ')}
**Discoveries**: ${discoveriesPath}
### Synthesis Protocol
1. **Read all role analyses** (analysis.md files only — these are index documents)
2. **Cross-reference findings**: Identify agreements, conflicts, and unique insights
3. **Generate feature specs**: For each feature in guidance-specification.md:
- Create ${sessionFolder}/.brainstorming/feature-specs/F-{id}-{slug}.md
- Consolidate perspectives from all relevant roles
- Note conflicts and recommended resolutions
4. **Generate feature index**: ${sessionFolder}/.brainstorming/feature-index.json
- Array of {id, title, slug, roles_contributing[], conflict_count, priority}
5. **Generate changelog**: ${sessionFolder}/.brainstorming/synthesis-changelog.md
- Decisions made, conflicts resolved, trade-offs accepted
### Complexity Assessment
Evaluate complexity score (0-8):
- Feature count (≤2: 0, 3-4: 1, ≥5: 2)
- Unresolved conflicts (0: 0, 1-2: 1, ≥3: 2)
- Participating roles (≤2: 0, 3-4: 1, ≥5: 2)
- Cross-feature dependencies (0: 0, 1-2: 1, ≥3: 2)
### Output Files
- feature-specs/F-{id}-{slug}.md (one per feature)
- feature-index.json
- synthesis-changelog.md
`
})
wait({ id: synthesisAgent })
close_agent({ id: synthesisAgent })
```
3. **Completion Summary**
```javascript
const featureIndex = JSON.parse(Read(`${sessionFolder}/.brainstorming/feature-index.json`) || '[]')
console.log(`
## Brainstorm Complete
Session: ${sessionId}
Roles analyzed: ${completedRoles.length}
Features synthesized: ${featureIndex.length}
### Feature Specs
${featureIndex.map(f => ` - [${f.id}] ${f.title} (${f.roles_contributing?.length || 0} roles, ${f.conflict_count || 0} conflicts)`).join('\n')}
### Next Steps
- /workflow-plan --session ${sessionId} → Generate implementation plan
- Review: ${sessionFolder}/.brainstorming/feature-specs/
`)
```
---
## Utility Functions
### CSV Parser
```javascript
function parseCsv(content) {
const lines = content.trim().split('\n')
if (lines.length < 2) return []
const headers = parseCSVLine(lines[0])
return lines.slice(1).map(line => {
const values = parseCSVLine(line)
const row = {}
headers.forEach((h, i) => row[h] = values[i] || '')
return row
})
}
```
### CSV Row Updater
```javascript
function updateMasterCsvRow(csvPath, id, updates) {
const content = Read(csvPath)
const lines = content.trim().split('\n')
const headers = parseCSVLine(lines[0])
const idIdx = headers.indexOf('id')
for (let i = 1; i < lines.length; i++) {
const values = parseCSVLine(lines[i])
if (values[idIdx]?.replace(/"/g, '') === id) {
Object.entries(updates).forEach(([key, val]) => {
const idx = headers.indexOf(key)
if (idx >= 0) values[idx] = `"${String(val).replace(/"/g, '""')}"`
})
lines[i] = values.join(',')
break
}
}
Write(csvPath, lines.join('\n'))
}
```
---
## Error Handling
| Error | Recovery |
|-------|----------|
| Invalid role name | Show valid roles list, prompt again |
| No active session (single role) | Guide user to run auto mode first |
| Role agent failure | Mark failed in roles.csv, continue with remaining |
| Synthesis overflow (>100KB) | Read only analysis.md index files |
| Context compression | Re-read guidance-specification.md and roles.csv |
---
## Compact Protection
> **COMPACT DIRECTIVE**: If context compression occurs mid-execution, re-read the current phase's state:
> - Phase 2: Re-read `guidance-specification.md`
> - Phase 3: Re-read `roles.csv` for progress state
> - Phase 4: Re-read `feature-index.json` and `roles.csv`

View File

@@ -831,14 +831,14 @@ ${selectedMode === 'progressive' ? `**Progressive Mode**:
case 'done':
// Output paths and end
console.log(`
Roadmap saved: ${sessionFolder}/roadmap.md
Issues created: ${issueIds.length}
To execute later:
$team-planex ${issueIds.slice(0, 3).join(' ')}...
ccw issue list --session ${sessionId}
`)
console.log([
`Roadmap saved: ${sessionFolder}/roadmap.md`,
`Issues created: ${issueIds.length}`,
'',
'To execute later:',
` $team-planex ${issueIds.slice(0, 3).join(' ')}...`,
` ccw issue list --session ${sessionId}`
].join('\n'))
break
}
```
@@ -897,3 +897,7 @@ To execute later:
| Collaborative multi-agent planning | `$collaborative-plan-with-file` |
| Full specification documents | `$spec-generator` |
| Code implementation from existing plan | `$workflow-lite-planex` |
---
**Now execute roadmap-with-file for**: $ARGUMENTS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,636 @@
---
name: workflow-plan
description: |
Planning pipeline with multi-mode routing (plan/verify/replan). Session discovery →
context gathering (spawn_agent) → conditional conflict resolution → task generation
(spawn_agent or N+1 parallel agents) → plan verification → interactive replan.
Produces IMPL_PLAN.md, task JSONs, TODO_LIST.md.
argument-hint: "[-y|--yes] [--session ID] \"task description\" | verify [--session ID] | replan [--session ID] [IMPL-N] \"changes\""
allowed-tools: spawn_agent, wait, send_input, close_agent, AskUserQuestion, Read, Write, Edit, Bash, Glob, Grep
---
## Auto Mode
When `--yes` or `-y`: Skip all confirmations, use defaults, auto-verify, auto-continue to execute if PROCEED.
# Workflow Plan
## Usage
```bash
# Plan mode (default)
$workflow-plan "Build authentication system with JWT and OAuth"
$workflow-plan -y "Add rate limiting to API endpoints"
$workflow-plan --session WFS-auth "Extend with 2FA support"
# Verify mode
$workflow-plan verify --session WFS-auth
$workflow-plan verify
# Replan mode
$workflow-plan replan --session WFS-auth "Change from JWT to session-based auth"
$workflow-plan replan --session WFS-auth IMPL-3 "Split into two smaller tasks"
```
**Flags**:
- `-y, --yes`: Skip all confirmations (auto mode)
- `--session ID`: Use specific session
---
## Overview
Multi-mode planning pipeline using subagent coordination. Plan mode runs 4 sequential phases with conditional branching; verify and replan modes operate on existing plans.
```
┌──────────────────────────────────────────────────────────────────┐
│ WORKFLOW PLAN PIPELINE │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Mode Detection: plan | verify | replan │
│ │
│ ═══ Plan Mode (default) ═══ │
│ │
│ Phase 1: Session Discovery │
│ ├─ Create or find workflow session │
│ └─ Initialize planning-notes.md │
│ │
│ Phase 2: Context Gathering (spawn_agent: context-search-agent) │
│ ├─ Codebase analysis → context-package.json │
│ └─ Conflict risk assessment │
│ │
│ Phase 3: Conflict Resolution (conditional: risk ≥ medium) │
│ ├─ CLI-driven conflict analysis │
│ └─ User-selected resolution strategies │
│ │
│ Phase 4: Task Generation (spawn_agent: action-planning-agent) │
│ ├─ Single module → 1 agent │
│ ├─ Multi-module → N+1 parallel agents │
│ └─ Output: IMPL_PLAN.md + task JSONs + TODO_LIST.md │
│ │
│ Plan Confirmation Gate │
│ ├─ "Verify Plan" → Phase 5 │
│ ├─ "Start Execution" → workflow-execute │
│ └─ "Review Status" → Display inline │
│ │
│ ═══ Verify Mode ═══ │
│ Phase 5: Plan Verification (spawn_agent: cli-explore-agent) │
│ └─ 10-dimension analysis → PLAN_VERIFICATION.md │
│ │
│ ═══ Replan Mode ═══ │
│ Phase 6: Interactive Replan │
│ └─ Clarification → Impact → Backup → Apply → Verify │
│ │
└──────────────────────────────────────────────────────────────────┘
```
---
## Data Flow
```
User Input (task description)
↓ [Convert to GOAL/SCOPE/CONTEXT]
Phase 1 ──→ sessionId, planning-notes.md
Phase 2 ──→ context-package.json, conflictRisk
├── conflictRisk ≥ medium ──→ Phase 3 ──→ modified artifacts
└── conflictRisk < medium ──→ skip Phase 3
Phase 4 ──→ IMPL_PLAN.md, plan.json, task JSONs, TODO_LIST.md
├── Verify → Phase 5 → PLAN_VERIFICATION.md
├── Execute → workflow-execute skill
└── Review → inline display
```
---
## Session Structure
```
.workflow/active/WFS-{session}/
├── workflow-session.json # Session metadata
├── planning-notes.md # Accumulated context across phases
├── IMPL_PLAN.md # Implementation plan (human-readable)
├── plan.json # Structured plan overview (machine-readable)
├── TODO_LIST.md # Task checklist
├── .task/ # Task definitions
│ ├── IMPL-1.json
│ └── IMPL-N.json
└── .process/
├── context-package.json # Phase 2 output
├── conflict-resolution.json # Phase 3 output (conditional)
├── PLAN_VERIFICATION.md # Phase 5 output
└── backup/ # Phase 6 backups
```
---
## Implementation
### Session Initialization
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
// Parse flags
const AUTO_YES = $ARGUMENTS.includes('--yes') || $ARGUMENTS.includes('-y')
const sessionMatch = $ARGUMENTS.match(/--session\s+(\S+)/)
const existingSessionId = sessionMatch ? sessionMatch[1] : null
// Mode detection
const cleanArgs = $ARGUMENTS
.replace(/--yes|-y|--session\s+\S+/g, '').trim()
let mode = 'plan'
if (cleanArgs.startsWith('verify')) mode = 'verify'
else if (cleanArgs.startsWith('replan')) mode = 'replan'
const taskDescription = cleanArgs
.replace(/^(verify|replan)\s*/, '')
.replace(/^["']|["']$/g, '')
.trim()
// Extract replan task ID if present
const replanTaskMatch = taskDescription.match(/^(IMPL-\d+(?:\.\d+)?)\s+(.+)/)
const replanTaskId = replanTaskMatch ? replanTaskMatch[1] : null
const replanDescription = replanTaskMatch ? replanTaskMatch[2] : taskDescription
```
---
### Phase 1: Session Discovery (Plan Mode)
**Objective**: Create or find workflow session, initialize planning notes.
```javascript
if (mode !== 'plan') {
// verify/replan: locate existing session
// → Jump to Phase 5 or Phase 6
}
let sessionId, sessionFolder
if (existingSessionId) {
sessionId = existingSessionId
sessionFolder = `.workflow/active/${sessionId}`
if (!Bash(`test -d "${sessionFolder}" && echo yes`).trim()) {
console.log(`ERROR: Session ${sessionId} not found`)
return
}
} else {
// Auto-detect from .workflow/active/ or create new
const sessions = Bash(`ls -d .workflow/active/WFS-* 2>/dev/null`).trim().split('\n').filter(Boolean)
if (sessions.length === 0 || taskDescription) {
// Create new session
const slug = taskDescription.toLowerCase()
.replace(/[^a-z0-9\u4e00-\u9fa5]+/g, '-').substring(0, 40)
sessionId = `WFS-${slug}`
sessionFolder = `.workflow/active/${sessionId}`
Bash(`mkdir -p "${sessionFolder}/.task" "${sessionFolder}/.process" "${sessionFolder}/.summaries"`)
Write(`${sessionFolder}/workflow-session.json`, JSON.stringify({
session_id: sessionId,
status: 'planning',
created_at: getUtc8ISOString(),
task_description: taskDescription
}, null, 2))
} else if (sessions.length === 1) {
sessionId = sessions[0].split('/').pop()
sessionFolder = sessions[0]
} else {
// Multiple sessions — ask user
if (AUTO_YES) {
sessionFolder = sessions[0]
sessionId = sessions[0].split('/').pop()
} else {
const answer = AskUserQuestion({
questions: [{
question: "Multiple sessions found. Select one:",
header: "Session",
multiSelect: false,
options: sessions.slice(0, 4).map(s => ({
label: s.split('/').pop(),
description: s
}))
}]
})
sessionId = answer.Session
sessionFolder = `.workflow/active/${sessionId}`
}
}
}
// Initialize planning-notes.md
const structuredDesc = `GOAL: ${taskDescription}\nSCOPE: Core implementation\nCONTEXT: New development`
Write(`${sessionFolder}/planning-notes.md`, `# Planning Notes\n\n## User Intent\n${structuredDesc}\n`)
console.log(`Session: ${sessionId}`)
```
---
### Phase 2: Context Gathering (spawn_agent)
**Objective**: Gather project context, assess conflict risk.
```javascript
console.log(`\n## Phase 2: Context Gathering\n`)
const ctxAgent = spawn_agent({
agent: `~/.codex/agents/context-search-agent.md`,
instruction: `
Gather implementation context for planning.
**Session**: ${sessionFolder}
**Task**: ${taskDescription}
**Mode**: PLAN
### Steps
1. Analyze project structure (package.json, tsconfig, etc.)
2. Search for existing similar implementations
3. Identify integration points and dependencies
4. Assess conflict risk with existing code
5. Generate context package
### Output
Write context package to: ${sessionFolder}/.process/context-package.json
Format: {
"critical_files": [...],
"patterns": [...],
"dependencies": [...],
"integration_points": [...],
"conflict_risk": "none" | "low" | "medium" | "high",
"conflict_areas": [...],
"constraints": [...]
}
`
})
wait({ id: ctxAgent })
close_agent({ id: ctxAgent })
// Parse outputs
const contextPkg = JSON.parse(Read(`${sessionFolder}/.process/context-package.json`) || '{}')
const conflictRisk = contextPkg.conflict_risk || 'none'
const contextPath = `${sessionFolder}/.process/context-package.json`
// Update planning-notes.md
Edit(`${sessionFolder}/planning-notes.md`, {
oldText: '## User Intent',
newText: `## Context Findings
- Critical files: ${(contextPkg.critical_files || []).join(', ')}
- Conflict risk: ${conflictRisk}
- Constraints: ${(contextPkg.constraints || []).join('; ')}
## User Intent`
})
console.log(` Context gathered. Conflict risk: ${conflictRisk}`)
```
---
### Phase 3: Conflict Resolution (Conditional)
**Objective**: Detect and resolve conflicts when risk ≥ medium.
```javascript
if (['medium', 'high'].includes(conflictRisk)) {
console.log(`\n## Phase 3: Conflict Resolution (risk: ${conflictRisk})\n`)
Bash({
command: `ccw cli -p "PURPOSE: Analyze and resolve conflicts between planned changes and existing codebase.
TASK:
• Read context package for conflict areas
• Analyze each conflict area in detail
• Propose resolution strategies (refactor, adapt, isolate, defer)
• For each conflict: assess impact and recommend approach
MODE: analysis
CONTEXT: @**/*
EXPECTED: JSON: {conflicts: [{area, severity, description, strategy, impact}], summary: string}
CONSTRAINTS: Focus on ${(contextPkg.conflict_areas || []).join(', ')}
TASK DESCRIPTION: ${taskDescription}" --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause`,
run_in_background: true
})
// Wait for CLI → conflicts[]
if (!AUTO_YES && conflicts.length > 0) {
// Present conflicts and let user select strategies
console.log(`\n### Conflicts Found: ${conflicts.length}\n`)
conflicts.forEach((c, i) => {
console.log(`${i + 1}. [${c.severity}] ${c.area}: ${c.description}`)
console.log(` Strategy: ${c.strategy} | Impact: ${c.impact}`)
})
const answer = AskUserQuestion({
questions: [{
question: "Accept conflict resolution strategies?",
header: "Conflicts",
multiSelect: false,
options: [
{ label: "Accept All", description: "Apply all recommended strategies" },
{ label: "Review Each", description: "Approve strategies individually" },
{ label: "Skip", description: "Proceed without resolving" }
]
}]
})
}
// Write resolution
Write(`${sessionFolder}/.process/conflict-resolution.json`,
JSON.stringify({ conflicts, resolved_at: getUtc8ISOString() }, null, 2))
// Update planning-notes
// Append conflict decisions to planning-notes.md
} else {
console.log(` Conflict risk: ${conflictRisk} — skipping Phase 3`)
}
```
---
### Phase 4: Task Generation (spawn_agent)
**Objective**: Generate IMPL_PLAN.md, task JSONs, TODO_LIST.md.
**Steps**:
1. **Determine Planning Strategy**
```javascript
console.log(`\n## Phase 4: Task Generation\n`)
// Detect module count from context
const modules = contextPkg.integration_points?.map(p => p.module).filter(Boolean) || []
const uniqueModules = [...new Set(modules)]
const isMultiModule = uniqueModules.length >= 2
```
2. **Single Module → One Agent**
```javascript
if (!isMultiModule) {
const planAgent = spawn_agent({
agent: `~/.codex/agents/action-planning-agent.md`,
instruction: `
Generate implementation plan and task JSONs.
**Session**: ${sessionFolder}
**Task**: ${taskDescription}
**Context**: ${contextPath}
**Planning Notes**: ${sessionFolder}/planning-notes.md
${contextPkg.conflict_risk === 'medium' || contextPkg.conflict_risk === 'high'
? `**Conflict Resolution**: ${sessionFolder}/.process/conflict-resolution.json` : ''}
### Output Requirements
1. **IMPL_PLAN.md** at ${sessionFolder}/IMPL_PLAN.md
- Section 1: Requirements Summary
- Section 2: Architecture Decisions
- Section 3: Task Breakdown (with dependencies)
- Section 4: Implementation Strategy (Sequential/Parallel/Phased)
- Section 5: Risk Assessment
2. **plan.json** at ${sessionFolder}/plan.json
- {task_ids[], recommended_execution, complexity, shared_context}
3. **Task JSONs** at ${sessionFolder}/.task/IMPL-{N}.json
- {id, title, description, depends_on[], convergence, meta: {type, agent}}
4. **TODO_LIST.md** at ${sessionFolder}/TODO_LIST.md
- Checkbox format: - [ ] IMPL-{N}: {title}
`
})
wait({ id: planAgent })
close_agent({ id: planAgent })
}
```
3. **Multi-Module → N+1 Parallel Agents**
```javascript
if (isMultiModule) {
const prefixes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const moduleAgents = []
// Spawn N module planners in parallel
for (let i = 0; i < uniqueModules.length; i++) {
const prefix = prefixes[i]
const mod = uniqueModules[i]
const agentId = spawn_agent({
agent: `~/.codex/agents/action-planning-agent.md`,
instruction: `
Plan module: ${mod} (prefix: ${prefix})
**Session**: ${sessionFolder}
**Module**: ${mod}
**Context**: ${contextPath}
**Task ID prefix**: ${prefix} (e.g., ${prefix}1, ${prefix}2, ...)
Generate task JSONs for this module only.
Output to: ${sessionFolder}/.task/${prefix}{N}.json
Mark cross-module dependencies as CROSS::${'{module}'}::${'{task}'}
`
})
moduleAgents.push({ id: agentId, module: mod, prefix })
}
// Wait for all module planners
wait({ ids: moduleAgents.map(a => a.id) })
moduleAgents.forEach(a => close_agent({ id: a.id }))
// +1 Coordinator: integrate all modules
const coordAgent = spawn_agent({
agent: `~/.codex/agents/action-planning-agent.md`,
instruction: `
Integrate ${uniqueModules.length} module plans into unified IMPL_PLAN.md.
**Session**: ${sessionFolder}
**Modules**: ${uniqueModules.join(', ')}
**Task Directory**: ${sessionFolder}/.task/
### Steps
1. Read all module task JSONs from .task/
2. Resolve CROSS:: dependencies (replace with actual task IDs)
3. Generate unified IMPL_PLAN.md, plan.json, TODO_LIST.md
4. Renumber task IDs to sequential IMPL-1, IMPL-2, ...
`
})
wait({ id: coordAgent })
close_agent({ id: coordAgent })
}
```
4. **Plan Confirmation Gate**
```javascript
// Validate outputs exist
const planExists = Bash(`test -f "${sessionFolder}/IMPL_PLAN.md" && echo yes`).trim() === 'yes'
const taskCount = parseInt(Bash(`ls ${sessionFolder}/.task/IMPL-*.json 2>/dev/null | wc -l`).trim()) || 0
console.log(`\n## Plan Generated\n`)
console.log(` Tasks: ${taskCount}`)
console.log(` Plan: ${sessionFolder}/IMPL_PLAN.md`)
if (AUTO_YES) {
// Auto-verify then auto-execute if PROCEED
console.log(` [--yes] Auto-verifying plan...`)
// → Fall through to Phase 5, then Phase 5 result determines next step
} else {
const nextStep = AskUserQuestion({
questions: [{
question: "Plan generated. What's next?",
header: "Next Step",
multiSelect: false,
options: [
{ label: "Verify Plan (Recommended)", description: "Run quality verification before execution" },
{ label: "Start Execution", description: "Proceed to workflow-execute" },
{ label: "Review Status", description: "Display plan summary inline" }
]
}]
})
if (nextStep['Next Step'] === 'Start Execution') {
console.log(`\nReady to execute. Run: $workflow-execute --session ${sessionId}`)
return
}
if (nextStep['Next Step'] === 'Review Status') {
const plan = Read(`${sessionFolder}/IMPL_PLAN.md`)
console.log(plan)
return
}
// Verify → continue to Phase 5
}
```
---
### Phase 5: Plan Verification (Verify Mode)
**Objective**: Read-only multi-dimensional plan analysis.
```javascript
if (mode === 'verify' || /* auto-verify from Phase 4 */) {
console.log(`\n## Phase 5: Plan Verification\n`)
// Find session if in verify mode entry
if (mode === 'verify' && !sessionFolder) {
// Session discovery (same logic as Phase 1)
}
Bash({
command: `ccw cli -p "PURPOSE: Verify implementation plan quality across 10 dimensions. Read-only analysis. Success = actionable quality gate recommendation.
TASK:
• A: User Intent Alignment — does plan match original goal?
• B: Requirements Coverage — are all requirements addressed?
• C: Consistency Validation — internal consistency of plan
• D: Dependency Integrity — valid dependency chain
• E: Synthesis Alignment — matches brainstorm artifacts (if exist)
• F: Task Specification Quality — clear, actionable, testable
• G: Duplication Detection — no overlapping tasks
• H: Feasibility Assessment — realistic scope and effort
• I: Constraints Compliance — respects stated constraints
• J: Context Validation — planning-notes consistent with plan
MODE: analysis
CONTEXT: @${sessionFolder}/IMPL_PLAN.md @${sessionFolder}/.task/**/*.json @${sessionFolder}/planning-notes.md @${sessionFolder}/TODO_LIST.md
EXPECTED: Structured report with: per-dimension score (PASS/WARN/FAIL), issues list, quality gate (BLOCK_EXECUTION/PROCEED_WITH_FIXES/PROCEED_WITH_CAUTION/PROCEED)
CONSTRAINTS: Read-only | No file modifications | Be specific about issues" --tool gemini --mode analysis --rule analysis-review-architecture --cd "${sessionFolder}"`,
run_in_background: true
})
// Wait for CLI → verification report
Write(`${sessionFolder}/.process/PLAN_VERIFICATION.md`, verificationReport)
console.log(` Quality gate: ${qualityGate}`)
console.log(` Report: ${sessionFolder}/.process/PLAN_VERIFICATION.md`)
if (AUTO_YES && qualityGate === 'PROCEED') {
console.log(` [--yes] Plan verified. Ready for execution.`)
console.log(` Run: $workflow-execute --session ${sessionId}`)
}
}
```
---
### Phase 6: Interactive Replan (Replan Mode)
**Objective**: Modify existing plan based on new requirements.
```javascript
if (mode === 'replan') {
console.log(`\n## Phase 6: Interactive Replan\n`)
// Find session
if (!sessionFolder) {
// Session discovery logic
}
const scope = replanTaskId ? 'task' : 'session'
console.log(` Scope: ${scope}${replanTaskId ? ` (${replanTaskId})` : ''}`)
console.log(` Changes: ${replanDescription}`)
// 1. Backup current plan
Bash(`mkdir -p "${sessionFolder}/.process/backup" && cp "${sessionFolder}/IMPL_PLAN.md" "${sessionFolder}/.process/backup/IMPL_PLAN-$(date +%Y%m%d%H%M%S).md"`)
// 2. Replan via agent
const replanAgent = spawn_agent({
agent: `~/.codex/agents/action-planning-agent.md`,
instruction: `
Replan ${scope === 'task' ? `task ${replanTaskId}` : 'entire session'}.
**Session**: ${sessionFolder}
**Current Plan**: ${sessionFolder}/IMPL_PLAN.md
**Current Tasks**: ${sessionFolder}/.task/
**Changes Requested**: ${replanDescription}
${replanTaskId ? `**Target Task**: ${sessionFolder}/.task/${replanTaskId}.json` : ''}
### Steps
1. Read current plan and task JSONs
2. Analyze impact of requested changes
3. Modify affected tasks (update/add/remove)
4. Update IMPL_PLAN.md with change annotations
5. Update TODO_LIST.md
6. Generate change summary
### Constraints
- Preserve completed tasks
- Minimize changes to unaffected tasks
- Maintain dependency integrity
`
})
wait({ id: replanAgent })
close_agent({ id: replanAgent })
console.log(` Replan complete. Review: ${sessionFolder}/IMPL_PLAN.md`)
}
```
---
## Error Handling
| Error | Recovery |
|-------|----------|
| No active session | Guide: run `$workflow-plan "description"` first |
| Context gathering timeout | Retry with reduced scope |
| Conflict analysis failure | Skip Phase 3, proceed with warning |
| Task generation failure | Retry agent with simplified context |
| Plan verification failure | Display partial results |
| Session not found (verify/replan) | List available sessions |
---
## Compact Protection
> **COMPACT DIRECTIVE**: If context compression occurs:
> - Re-read `planning-notes.md` for accumulated context
> - Re-read `workflow-session.json` for session state
> - Phase 4 is the most token-intensive — if compressed, re-read task JSONs on demand