claude-code-workflow 7.2.23 → 7.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ccw/workflows/cli-tools-usage.md +123 -521
- package/.claude/skills/brainstorm/SKILL.md +408 -408
- package/.claude/skills/review-cycle/SKILL.md +132 -132
- package/.claude/skills/spec-generator/SKILL.md +1 -1
- package/.claude/skills/team-designer/phases/02-scaffold-generation.md +1 -1
- package/.claude/skills/team-lifecycle-v4/SKILL.md +1 -1
- package/.claude/skills/team-review/SKILL.md +1 -1
- package/.claude/skills/team-ultra-analyze/SKILL.md +1 -1
- package/.claude/skills/workflow-multi-cli-plan/SKILL.md +1 -1
- package/.claude/skills/workflow-plan/SKILL.md +1 -1
- package/.claude/skills/workflow-test-fix/SKILL.md +1 -1
- package/.codex/skills/analyze-with-file/SKILL.md +966 -966
- package/.codex/skills/issue-discover/SKILL.md +361 -361
- package/.codex/skills/review-cycle/SKILL.md +1 -1
- package/.codex/skills/roadmap-with-file/SKILL.md +901 -901
- package/.codex/skills/spec-generator/SKILL.md +425 -425
- package/.codex/skills/spec-setup/SKILL.md +669 -669
- package/.codex/skills/team-arch-opt/SKILL.md +242 -175
- package/.codex/skills/team-arch-opt/roles/analyzer/role.md +78 -78
- package/.codex/skills/team-arch-opt/roles/coordinator/commands/analyze.md +57 -57
- package/.codex/skills/team-arch-opt/roles/coordinator/commands/monitor.md +246 -204
- package/.codex/skills/team-arch-opt/roles/coordinator/role.md +196 -184
- package/.codex/skills/team-arch-opt/roles/designer/role.md +115 -115
- package/.codex/skills/team-arch-opt/roles/refactorer/role.md +102 -102
- package/.codex/skills/team-arch-opt/roles/reviewer/role.md +111 -111
- package/.codex/skills/team-arch-opt/roles/validator/role.md +115 -115
- package/.codex/skills/team-arch-opt/specs/pipelines.md +102 -102
- package/.codex/skills/team-brainstorm/SKILL.md +72 -4
- package/.codex/skills/team-brainstorm/roles/challenger/role.md +61 -61
- package/.codex/skills/team-brainstorm/roles/coordinator/commands/analyze.md +58 -58
- package/.codex/skills/team-brainstorm/roles/coordinator/commands/monitor.md +212 -171
- package/.codex/skills/team-brainstorm/roles/coordinator/role.md +172 -160
- package/.codex/skills/team-brainstorm/roles/evaluator/role.md +56 -56
- package/.codex/skills/team-brainstorm/roles/ideator/role.md +69 -69
- package/.codex/skills/team-brainstorm/roles/synthesizer/role.md +57 -57
- package/.codex/skills/team-brainstorm/specs/pipelines.md +72 -72
- package/.codex/skills/team-coordinate/SKILL.md +71 -3
- package/.codex/skills/team-coordinate/roles/coordinator/commands/monitor.md +45 -5
- package/.codex/skills/team-coordinate/roles/coordinator/role.md +402 -389
- package/.codex/skills/team-coordinate/specs/knowledge-transfer.md +111 -111
- package/.codex/skills/team-coordinate/specs/pipelines.md +97 -97
- package/.codex/skills/team-coordinate/specs/quality-gates.md +112 -112
- package/.codex/skills/team-designer/SKILL.md +153 -153
- package/.codex/skills/team-designer/phases/01-requirements-analysis.md +250 -250
- package/.codex/skills/team-designer/phases/02-scaffold-generation.md +228 -228
- package/.codex/skills/team-designer/phases/03-content-generation.md +330 -330
- package/.codex/skills/team-designer/phases/04-validation.md +320 -320
- package/.codex/skills/team-executor/SKILL.md +29 -2
- package/.codex/skills/team-executor/roles/executor/commands/monitor.md +23 -15
- package/.codex/skills/team-frontend/SKILL.md +77 -3
- package/.codex/skills/team-frontend/roles/analyst/role.md +92 -92
- package/.codex/skills/team-frontend/roles/architect/role.md +86 -86
- package/.codex/skills/team-frontend/roles/coordinator/commands/analyze.md +52 -52
- package/.codex/skills/team-frontend/roles/coordinator/commands/monitor.md +222 -188
- package/.codex/skills/team-frontend/roles/coordinator/role.md +189 -177
- package/.codex/skills/team-frontend/roles/developer/role.md +93 -93
- package/.codex/skills/team-frontend/roles/qa/role.md +79 -79
- package/.codex/skills/team-frontend/specs/pipelines.md +76 -76
- package/.codex/skills/team-frontend-debug/SKILL.md +66 -3
- package/.codex/skills/team-frontend-debug/roles/analyzer/role.md +208 -208
- package/.codex/skills/team-frontend-debug/roles/coordinator/commands/analyze.md +174 -174
- package/.codex/skills/team-frontend-debug/roles/coordinator/commands/dispatch.md +198 -198
- package/.codex/skills/team-frontend-debug/roles/coordinator/commands/monitor.md +177 -143
- package/.codex/skills/team-frontend-debug/roles/coordinator/role.md +164 -152
- package/.codex/skills/team-frontend-debug/roles/fixer/role.md +147 -147
- package/.codex/skills/team-frontend-debug/roles/reproducer/role.md +147 -147
- package/.codex/skills/team-frontend-debug/roles/tester/role.md +231 -231
- package/.codex/skills/team-frontend-debug/roles/verifier/role.md +172 -172
- package/.codex/skills/team-frontend-debug/specs/debug-tools.md +215 -215
- package/.codex/skills/team-frontend-debug/specs/pipelines.md +94 -94
- package/.codex/skills/team-issue/SKILL.md +83 -4
- package/.codex/skills/team-issue/roles/coordinator/commands/analyze.md +64 -64
- package/.codex/skills/team-issue/roles/coordinator/commands/dispatch.md +273 -273
- package/.codex/skills/team-issue/roles/coordinator/commands/monitor.md +235 -194
- package/.codex/skills/team-issue/roles/coordinator/role.md +206 -194
- package/.codex/skills/team-issue/roles/explorer/role.md +94 -94
- package/.codex/skills/team-issue/roles/implementer/role.md +87 -87
- package/.codex/skills/team-issue/roles/integrator/role.md +84 -84
- package/.codex/skills/team-issue/roles/planner/role.md +81 -81
- package/.codex/skills/team-issue/roles/reviewer/role.md +86 -86
- package/.codex/skills/team-issue/specs/pipelines.md +124 -124
- package/.codex/skills/team-lifecycle-v4/MIGRATION-PLAN.md +6 -6
- package/.codex/skills/team-lifecycle-v4/SKILL.md +305 -242
- package/.codex/skills/team-lifecycle-v4/roles/coordinator/commands/dispatch.md +1 -1
- package/.codex/skills/team-lifecycle-v4/roles/coordinator/commands/monitor.md +66 -24
- package/.codex/skills/team-lifecycle-v4/roles/coordinator/role.md +13 -1
- package/.codex/skills/team-lifecycle-v4/roles/supervisor/role.md +1 -1
- package/.codex/skills/team-lifecycle-v4/templates/architecture.md +254 -254
- package/.codex/skills/team-lifecycle-v4/templates/epics.md +196 -196
- package/.codex/skills/team-lifecycle-v4/templates/product-brief.md +133 -133
- package/.codex/skills/team-lifecycle-v4/templates/requirements.md +224 -224
- package/.codex/skills/team-perf-opt/SKILL.md +68 -3
- package/.codex/skills/team-perf-opt/roles/benchmarker/role.md +89 -89
- package/.codex/skills/team-perf-opt/roles/coordinator/commands/analyze.md +61 -61
- package/.codex/skills/team-perf-opt/roles/coordinator/commands/monitor.md +35 -1
- package/.codex/skills/team-perf-opt/roles/coordinator/role.md +179 -167
- package/.codex/skills/team-perf-opt/roles/optimizer/role.md +97 -97
- package/.codex/skills/team-perf-opt/roles/profiler/role.md +73 -73
- package/.codex/skills/team-perf-opt/roles/reviewer/role.md +75 -75
- package/.codex/skills/team-perf-opt/roles/strategist/role.md +94 -94
- package/.codex/skills/team-perf-opt/specs/pipelines.md +65 -65
- package/.codex/skills/team-planex/SKILL.md +65 -3
- package/.codex/skills/team-planex/roles/coordinator/commands/analyze.md +52 -52
- package/.codex/skills/team-planex/roles/coordinator/commands/monitor.md +210 -164
- package/.codex/skills/team-planex/roles/coordinator/role.md +171 -159
- package/.codex/skills/team-planex/roles/executor/role.md +91 -91
- package/.codex/skills/team-planex/roles/planner/role.md +112 -112
- package/.codex/skills/team-planex/specs/pipelines.md +93 -93
- package/.codex/skills/team-quality-assurance/SKILL.md +60 -3
- package/.codex/skills/team-quality-assurance/roles/analyst/role.md +80 -80
- package/.codex/skills/team-quality-assurance/roles/coordinator/commands/analyze.md +72 -72
- package/.codex/skills/team-quality-assurance/roles/coordinator/commands/dispatch.md +108 -108
- package/.codex/skills/team-quality-assurance/roles/coordinator/commands/monitor.md +243 -209
- package/.codex/skills/team-quality-assurance/roles/coordinator/role.md +176 -164
- package/.codex/skills/team-quality-assurance/roles/executor/role.md +66 -66
- package/.codex/skills/team-quality-assurance/roles/generator/role.md +68 -68
- package/.codex/skills/team-quality-assurance/roles/scout/role.md +67 -67
- package/.codex/skills/team-quality-assurance/roles/strategist/role.md +71 -71
- package/.codex/skills/team-quality-assurance/specs/pipelines.md +115 -115
- package/.codex/skills/team-review/SKILL.md +58 -3
- package/.codex/skills/team-review/roles/coordinator/commands/analyze.md +71 -71
- package/.codex/skills/team-review/roles/coordinator/commands/dispatch.md +90 -90
- package/.codex/skills/team-review/roles/coordinator/commands/monitor.md +225 -185
- package/.codex/skills/team-review/roles/coordinator/role.md +175 -163
- package/.codex/skills/team-review/roles/fixer/role.md +76 -76
- package/.codex/skills/team-review/roles/reviewer/role.md +68 -68
- package/.codex/skills/team-review/roles/scanner/role.md +71 -71
- package/.codex/skills/team-review/specs/pipelines.md +102 -102
- package/.codex/skills/team-roadmap-dev/SKILL.md +55 -3
- package/.codex/skills/team-roadmap-dev/roles/coordinator/commands/analyze.md +61 -61
- package/.codex/skills/team-roadmap-dev/roles/coordinator/commands/monitor.md +502 -468
- package/.codex/skills/team-roadmap-dev/roles/coordinator/role.md +335 -322
- package/.codex/skills/team-roadmap-dev/roles/executor/role.md +71 -71
- package/.codex/skills/team-roadmap-dev/roles/planner/role.md +76 -76
- package/.codex/skills/team-roadmap-dev/roles/verifier/role.md +74 -74
- package/.codex/skills/team-roadmap-dev/specs/pipelines.md +93 -93
- package/.codex/skills/team-tech-debt/SKILL.md +56 -3
- package/.codex/skills/team-tech-debt/roles/assessor/role.md +69 -69
- package/.codex/skills/team-tech-debt/roles/coordinator/commands/analyze.md +47 -47
- package/.codex/skills/team-tech-debt/roles/coordinator/commands/monitor.md +272 -231
- package/.codex/skills/team-tech-debt/roles/coordinator/role.md +172 -160
- package/.codex/skills/team-tech-debt/roles/executor/role.md +76 -76
- package/.codex/skills/team-tech-debt/roles/planner/role.md +69 -69
- package/.codex/skills/team-tech-debt/roles/scanner/role.md +82 -82
- package/.codex/skills/team-tech-debt/roles/validator/role.md +75 -75
- package/.codex/skills/team-tech-debt/specs/pipelines.md +47 -47
- package/.codex/skills/team-testing/SKILL.md +72 -3
- package/.codex/skills/team-testing/roles/analyst/role.md +95 -95
- package/.codex/skills/team-testing/roles/coordinator/commands/analyze.md +70 -70
- package/.codex/skills/team-testing/roles/coordinator/commands/dispatch.md +106 -106
- package/.codex/skills/team-testing/roles/coordinator/commands/monitor.md +283 -242
- package/.codex/skills/team-testing/roles/coordinator/role.md +184 -172
- package/.codex/skills/team-testing/roles/executor/role.md +96 -96
- package/.codex/skills/team-testing/roles/generator/role.md +95 -95
- package/.codex/skills/team-testing/roles/strategist/role.md +83 -83
- package/.codex/skills/team-testing/specs/pipelines.md +101 -101
- package/.codex/skills/team-uidesign/SKILL.md +65 -3
- package/.codex/skills/team-uidesign/roles/coordinator/commands/analyze.md +59 -59
- package/.codex/skills/team-uidesign/roles/coordinator/commands/dispatch.md +156 -156
- package/.codex/skills/team-uidesign/roles/coordinator/commands/monitor.md +234 -194
- package/.codex/skills/team-uidesign/roles/coordinator/role.md +211 -199
- package/.codex/skills/team-uidesign/roles/designer/role.md +69 -69
- package/.codex/skills/team-uidesign/roles/implementer/role.md +72 -72
- package/.codex/skills/team-uidesign/roles/researcher/role.md +82 -82
- package/.codex/skills/team-uidesign/roles/reviewer/role.md +67 -67
- package/.codex/skills/team-uidesign/specs/pipelines.md +76 -76
- package/.codex/skills/team-ultra-analyze/SKILL.md +73 -3
- package/.codex/skills/team-ultra-analyze/roles/analyst/role.md +90 -90
- package/.codex/skills/team-ultra-analyze/roles/coordinator/commands/analyze.md +73 -73
- package/.codex/skills/team-ultra-analyze/roles/coordinator/commands/monitor.md +50 -9
- package/.codex/skills/team-ultra-analyze/roles/coordinator/role.md +255 -243
- package/.codex/skills/team-ultra-analyze/roles/discussant/role.md +104 -104
- package/.codex/skills/team-ultra-analyze/roles/explorer/role.md +74 -74
- package/.codex/skills/team-ultra-analyze/roles/synthesizer/role.md +78 -78
- package/.codex/skills/team-ultra-analyze/specs/pipelines.md +64 -64
- package/.codex/skills/team-ux-improve/SKILL.md +64 -3
- package/.codex/skills/team-ux-improve/roles/coordinator/commands/analyze.md +62 -62
- package/.codex/skills/team-ux-improve/roles/coordinator/commands/dispatch.md +233 -233
- package/.codex/skills/team-ux-improve/roles/coordinator/commands/monitor.md +195 -160
- package/.codex/skills/team-ux-improve/roles/coordinator/role.md +170 -158
- package/.codex/skills/team-ux-improve/roles/designer/role.md +122 -122
- package/.codex/skills/team-ux-improve/roles/diagnoser/role.md +93 -93
- package/.codex/skills/team-ux-improve/roles/explorer/role.md +77 -77
- package/.codex/skills/team-ux-improve/roles/implementer/role.md +102 -102
- package/.codex/skills/team-ux-improve/roles/scanner/role.md +93 -93
- package/.codex/skills/team-ux-improve/roles/tester/role.md +84 -84
- package/.codex/skills/team-ux-improve/specs/pipelines.md +54 -54
- package/.codex/skills/workflow-test-fix-cycle/SKILL.md +402 -402
- package/README.md +1 -0
- package/package.json +1 -1
- package/.claude/skills/team-iterdev/SKILL.md +0 -127
- package/.claude/skills/team-iterdev/roles/architect/role.md +0 -65
- package/.claude/skills/team-iterdev/roles/coordinator/commands/analyze.md +0 -62
- package/.claude/skills/team-iterdev/roles/coordinator/commands/dispatch.md +0 -234
- package/.claude/skills/team-iterdev/roles/coordinator/commands/monitor.md +0 -182
- package/.claude/skills/team-iterdev/roles/coordinator/role.md +0 -153
- package/.claude/skills/team-iterdev/roles/developer/role.md +0 -74
- package/.claude/skills/team-iterdev/roles/reviewer/role.md +0 -66
- package/.claude/skills/team-iterdev/roles/tester/role.md +0 -88
- package/.claude/skills/team-iterdev/specs/pipelines.md +0 -94
- package/.claude/skills/team-iterdev/specs/team-config.json +0 -172
- package/.codex/skills/team-iterdev/SKILL.md +0 -158
- package/.codex/skills/team-iterdev/roles/architect/role.md +0 -65
- package/.codex/skills/team-iterdev/roles/coordinator/commands/analyze.md +0 -62
- package/.codex/skills/team-iterdev/roles/coordinator/commands/dispatch.md +0 -187
- package/.codex/skills/team-iterdev/roles/coordinator/commands/monitor.md +0 -186
- package/.codex/skills/team-iterdev/roles/coordinator/role.md +0 -181
- package/.codex/skills/team-iterdev/roles/developer/role.md +0 -74
- package/.codex/skills/team-iterdev/roles/reviewer/role.md +0 -66
- package/.codex/skills/team-iterdev/roles/tester/role.md +0 -88
- package/.codex/skills/team-iterdev/specs/pipelines.md +0 -94
- package/.codex/skills/team-iterdev/specs/team-config.json +0 -172
|
@@ -1,669 +1,669 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: spec-setup
|
|
3
|
-
description: Initialize project-level state and configure specs via interactive questionnaire
|
|
4
|
-
argument-hint: "[--regenerate] [--skip-specs] [--reset]"
|
|
5
|
-
allowed-tools: spawn_agent, wait, send_input, close_agent, request_user_input, Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Workflow Spec Setup Command
|
|
9
|
-
|
|
10
|
-
## Overview
|
|
11
|
-
|
|
12
|
-
Initialize `.workflow/project-tech.json` and `.ccw/specs/*.md` with comprehensive project understanding by delegating analysis to **cli-explore-agent**, then interactively configure project guidelines through a multi-round questionnaire.
|
|
13
|
-
|
|
14
|
-
**Dual File System**:
|
|
15
|
-
- `project-tech.json`: Auto-generated technical analysis (stack, architecture, components)
|
|
16
|
-
- `specs/*.md`: User-maintained rules and constraints (created and populated interactively)
|
|
17
|
-
|
|
18
|
-
**Design Principle**: Questions are dynamically generated based on the project's tech stack, architecture, and patterns -- not generic boilerplate.
|
|
19
|
-
|
|
20
|
-
**Note**: This command may be called by other workflow commands. Upon completion, return immediately to continue the calling workflow without interrupting the task flow.
|
|
21
|
-
|
|
22
|
-
## Usage
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
$spec-setup # Initialize (skip if exists)
|
|
26
|
-
$spec-setup --regenerate # Force regeneration of project-tech.json
|
|
27
|
-
$spec-setup --skip-specs # Initialize project-tech only, skip spec initialization and questionnaire
|
|
28
|
-
$spec-setup --reset # Reset specs content before questionnaire
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Execution Process
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
Input Parsing:
|
|
35
|
-
|- Parse --regenerate flag -> regenerate = true | false
|
|
36
|
-
|- Parse --skip-specs flag -> skipSpecs = true | false
|
|
37
|
-
+- Parse --reset flag -> reset = true | false
|
|
38
|
-
|
|
39
|
-
Decision:
|
|
40
|
-
|- BOTH_EXIST + no --regenerate + no --reset -> Exit: "Already initialized"
|
|
41
|
-
|- EXISTS + --regenerate -> Backup existing -> Continue analysis
|
|
42
|
-
|- EXISTS + --reset -> Reset specs, keep project-tech -> Skip to questionnaire
|
|
43
|
-
+- NOT_FOUND -> Continue full flow
|
|
44
|
-
|
|
45
|
-
Full Flow:
|
|
46
|
-
|- Step 1: Parse input and check existing state
|
|
47
|
-
|- Step 2: Get project metadata (name, root)
|
|
48
|
-
|- Step 3: Invoke cli-explore-agent (subagent)
|
|
49
|
-
| |- Structural scan (get_modules_by_depth.sh, find, wc)
|
|
50
|
-
| |- Semantic analysis (Gemini CLI)
|
|
51
|
-
| |- Synthesis and merge
|
|
52
|
-
| +- Write .workflow/project-tech.json
|
|
53
|
-
|- Step 4: Initialize Spec System (if not --skip-specs)
|
|
54
|
-
| |- Check if specs/*.md exist
|
|
55
|
-
| |- If NOT_FOUND -> Run ccw spec init
|
|
56
|
-
| +- Run ccw spec rebuild
|
|
57
|
-
|- Step 5: Multi-Round Interactive Questionnaire (if not --skip-specs)
|
|
58
|
-
| |- Check if guidelines already populated -> Ask: "Append / Reset / Cancel"
|
|
59
|
-
| |- Load project context from project-tech.json
|
|
60
|
-
| |- Round 1: Coding Conventions (coding_style, naming_patterns)
|
|
61
|
-
| |- Round 2: File & Documentation Conventions (file_structure, documentation)
|
|
62
|
-
| |- Round 3: Architecture & Tech Constraints (architecture, tech_stack)
|
|
63
|
-
| |- Round 4: Performance & Security Constraints (performance, security)
|
|
64
|
-
| +- Round 5: Quality Rules (quality_rules)
|
|
65
|
-
|- Step 6: Write specs/*.md (if not --skip-specs)
|
|
66
|
-
+- Step 7: Display Summary
|
|
67
|
-
|
|
68
|
-
Output:
|
|
69
|
-
|- .workflow/project-tech.json (+ .backup if regenerate)
|
|
70
|
-
+- .ccw/specs/*.md (scaffold or configured, unless --skip-specs)
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Implementation
|
|
74
|
-
|
|
75
|
-
### Step 1: Parse Input and Check Existing State
|
|
76
|
-
|
|
77
|
-
**Parse flags**:
|
|
78
|
-
```javascript
|
|
79
|
-
const regenerate = $ARGUMENTS.includes('--regenerate')
|
|
80
|
-
const skipSpecs = $ARGUMENTS.includes('--skip-specs')
|
|
81
|
-
const reset = $ARGUMENTS.includes('--reset')
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Check existing state**:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
bash(test -f .workflow/project-tech.json && echo "TECH_EXISTS" || echo "TECH_NOT_FOUND")
|
|
88
|
-
bash(test -f .ccw/specs/coding-conventions.md && echo "SPECS_EXISTS" || echo "SPECS_NOT_FOUND")
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**If BOTH_EXIST and no --regenerate and no --reset**: Exit early
|
|
92
|
-
```
|
|
93
|
-
Project already initialized:
|
|
94
|
-
- Tech analysis: .workflow/project-tech.json
|
|
95
|
-
- Guidelines: .ccw/specs/*.md
|
|
96
|
-
|
|
97
|
-
Use $spec-setup --regenerate to rebuild tech analysis
|
|
98
|
-
Use $spec-setup --reset to reconfigure guidelines
|
|
99
|
-
Use $spec-add to add individual rules
|
|
100
|
-
Use $workflow-status --project to view state
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Step 2: Get Project Metadata
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
bash(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")
|
|
107
|
-
bash(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
108
|
-
bash(mkdir -p .workflow)
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Step 3: Invoke cli-explore-agent (Subagent)
|
|
112
|
-
|
|
113
|
-
**For --regenerate**: Backup and preserve existing data
|
|
114
|
-
```bash
|
|
115
|
-
bash(cp .workflow/project-tech.json .workflow/project-tech.json.backup)
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**Delegate analysis to subagent**:
|
|
119
|
-
|
|
120
|
-
```javascript
|
|
121
|
-
let exploreAgent = null
|
|
122
|
-
|
|
123
|
-
try {
|
|
124
|
-
exploreAgent = spawn_agent({
|
|
125
|
-
agent_type: "cli_explore_agent",
|
|
126
|
-
message: `
|
|
127
|
-
## TASK ASSIGNMENT
|
|
128
|
-
|
|
129
|
-
### MANDATORY FIRST STEPS (Agent Execute)
|
|
130
|
-
1. Read: .workflow/project-tech.json (if exists, for --regenerate)
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
Analyze project for workflow initialization and generate .workflow/project-tech.json.
|
|
135
|
-
|
|
136
|
-
## MANDATORY FIRST STEPS
|
|
137
|
-
1. Execute: cat ~/.ccw/workflows/cli-templates/schemas/project-tech-schema.json (get schema reference)
|
|
138
|
-
2. Execute: ccw tool exec get_modules_by_depth '{}' (get project structure)
|
|
139
|
-
|
|
140
|
-
## Task
|
|
141
|
-
Generate complete project-tech.json following the schema structure:
|
|
142
|
-
- project_name: "${projectName}"
|
|
143
|
-
- initialized_at: ISO 8601 timestamp
|
|
144
|
-
- overview: {
|
|
145
|
-
description: "Brief project description",
|
|
146
|
-
technology_stack: {
|
|
147
|
-
languages: [{name, file_count, primary}],
|
|
148
|
-
frameworks: ["string"],
|
|
149
|
-
build_tools: ["string"],
|
|
150
|
-
test_frameworks: ["string"]
|
|
151
|
-
},
|
|
152
|
-
architecture: {style, layers: [], patterns: []},
|
|
153
|
-
key_components: [{name, path, description, importance}]
|
|
154
|
-
}
|
|
155
|
-
- features: []
|
|
156
|
-
- development_index: ${regenerate ? 'preserve from backup' : '{feature: [], enhancement: [], bugfix: [], refactor: [], docs: []}'}
|
|
157
|
-
- statistics: ${regenerate ? 'preserve from backup' : '{total_features: 0, total_sessions: 0, last_updated: ISO timestamp}'}
|
|
158
|
-
- _metadata: {initialized_by: "cli-explore-agent", analysis_timestamp: ISO timestamp, analysis_mode: "deep-scan"}
|
|
159
|
-
|
|
160
|
-
## Analysis Requirements
|
|
161
|
-
|
|
162
|
-
**Technology Stack**:
|
|
163
|
-
- Languages: File counts, mark primary
|
|
164
|
-
- Frameworks: From package.json, requirements.txt, go.mod, etc.
|
|
165
|
-
- Build tools: npm, cargo, maven, webpack, vite
|
|
166
|
-
- Test frameworks: jest, pytest, go test, junit
|
|
167
|
-
|
|
168
|
-
**Architecture**:
|
|
169
|
-
- Style: MVC, microservices, layered (from structure & imports)
|
|
170
|
-
- Layers: presentation, business-logic, data-access
|
|
171
|
-
- Patterns: singleton, factory, repository
|
|
172
|
-
- Key components: 5-10 modules {name, path, description, importance}
|
|
173
|
-
|
|
174
|
-
## Execution
|
|
175
|
-
1. Structural scan: get_modules_by_depth.sh, find, wc -l
|
|
176
|
-
2. Semantic analysis: Gemini for patterns/architecture
|
|
177
|
-
3. Synthesis: Merge findings
|
|
178
|
-
4. ${regenerate ? 'Merge with preserved development_index and statistics from .workflow/project-tech.json.backup' : ''}
|
|
179
|
-
5. Write JSON: Write('.workflow/project-tech.json', jsonContent)
|
|
180
|
-
6. Report: Return brief completion summary
|
|
181
|
-
|
|
182
|
-
Project root: ${projectRoot}
|
|
183
|
-
`
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
// Wait for completion
|
|
187
|
-
const result = wait({ ids: [exploreAgent], timeout_ms: 600000 })
|
|
188
|
-
|
|
189
|
-
if (result.timed_out) {
|
|
190
|
-
send_input({ id: exploreAgent, message: 'Complete analysis now and write project-tech.json.' })
|
|
191
|
-
const retry = wait({ ids: [exploreAgent], timeout_ms: 300000 })
|
|
192
|
-
if (retry.timed_out) throw new Error('Agent timeout')
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
} finally {
|
|
196
|
-
if (exploreAgent) close_agent({ id: exploreAgent })
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### Step 4: Initialize Spec System (if not --skip-specs)
|
|
201
|
-
|
|
202
|
-
```javascript
|
|
203
|
-
// Skip spec initialization if --skip-specs flag is provided
|
|
204
|
-
if (!skipSpecs) {
|
|
205
|
-
// Initialize spec system if not already initialized
|
|
206
|
-
const specsCheck = Bash('test -f .ccw/specs/coding-conventions.md && echo EXISTS || echo NOT_FOUND')
|
|
207
|
-
if (specsCheck.includes('NOT_FOUND')) {
|
|
208
|
-
console.log('Initializing spec system...')
|
|
209
|
-
Bash('ccw spec init')
|
|
210
|
-
Bash('ccw spec rebuild')
|
|
211
|
-
}
|
|
212
|
-
} else {
|
|
213
|
-
console.log('Skipping spec initialization and questionnaire (--skip-specs)')
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
If `--skip-specs` is provided, skip directly to Step 7 (Display Summary) with limited output.
|
|
218
|
-
|
|
219
|
-
### Step 5: Multi-Round Interactive Questionnaire (if not --skip-specs)
|
|
220
|
-
|
|
221
|
-
#### Step 5.0: Check Existing Guidelines
|
|
222
|
-
|
|
223
|
-
If guidelines already have content, ask the user how to proceed:
|
|
224
|
-
|
|
225
|
-
```javascript
|
|
226
|
-
// Check if specs already have content via ccw spec list
|
|
227
|
-
const specsList = Bash('ccw spec list --json 2>/dev/null || echo "{}"')
|
|
228
|
-
const specsData = JSON.parse(specsList)
|
|
229
|
-
const isPopulated = (specsData.total || 0) > 5 // More than seed docs
|
|
230
|
-
|
|
231
|
-
if (isPopulated && !reset) {
|
|
232
|
-
const mode = request_user_input({
|
|
233
|
-
questions: [{
|
|
234
|
-
header: "Guidelines",
|
|
235
|
-
id: "mode",
|
|
236
|
-
question: "Project guidelines already contain entries. How would you like to proceed?",
|
|
237
|
-
options: [
|
|
238
|
-
{ label: "Append(Recommended)", description: "Keep existing entries and add new ones from the wizard" },
|
|
239
|
-
{ label: "Reset", description: "Clear all existing entries and start fresh" },
|
|
240
|
-
{ label: "Cancel", description: "Exit without changes" }
|
|
241
|
-
]
|
|
242
|
-
}]
|
|
243
|
-
}) // BLOCKS (wait for user response)
|
|
244
|
-
|
|
245
|
-
// If Cancel -> exit
|
|
246
|
-
// If Reset -> clear all arrays before proceeding
|
|
247
|
-
// If Append -> keep existing, wizard adds to them
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// If --reset flag was provided, clear existing entries before proceeding
|
|
251
|
-
if (reset) {
|
|
252
|
-
// Reset specs content
|
|
253
|
-
console.log('Resetting existing guidelines...')
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
#### Step 5.1: Load Project Context
|
|
258
|
-
|
|
259
|
-
```javascript
|
|
260
|
-
// Load project context via ccw spec load for planning context
|
|
261
|
-
const projectContext = Bash('ccw spec load --category planning 2>/dev/null || echo "{}"')
|
|
262
|
-
const specData = JSON.parse(projectContext)
|
|
263
|
-
|
|
264
|
-
// Extract key info from loaded specs for generating smart questions
|
|
265
|
-
const languages = specData.overview?.technology_stack?.languages || []
|
|
266
|
-
const primaryLang = languages.find(l => l.primary)?.name || languages[0]?.name || 'Unknown'
|
|
267
|
-
const frameworks = specData.overview?.technology_stack?.frameworks || []
|
|
268
|
-
const testFrameworks = specData.overview?.technology_stack?.test_frameworks || []
|
|
269
|
-
const archStyle = specData.overview?.architecture?.style || 'Unknown'
|
|
270
|
-
const archPatterns = specData.overview?.architecture?.patterns || []
|
|
271
|
-
const buildTools = specData.overview?.technology_stack?.build_tools || []
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
#### Step 5.2: Multi-Round Questionnaire
|
|
275
|
-
|
|
276
|
-
Each round uses `request_user_input` with project-aware options. The user can always select "Other" to provide custom input.
|
|
277
|
-
|
|
278
|
-
**CRITICAL**: After each round, collect the user's answers and convert them into guideline entries. Do NOT batch all rounds -- process each round's answers before proceeding to the next.
|
|
279
|
-
|
|
280
|
-
---
|
|
281
|
-
|
|
282
|
-
##### Round 1: Coding Conventions
|
|
283
|
-
|
|
284
|
-
Generate options dynamically based on detected language/framework:
|
|
285
|
-
|
|
286
|
-
```javascript
|
|
287
|
-
// Build language-specific coding style options
|
|
288
|
-
const codingStyleOptions = []
|
|
289
|
-
|
|
290
|
-
if (['TypeScript', 'JavaScript'].includes(primaryLang)) {
|
|
291
|
-
codingStyleOptions.push(
|
|
292
|
-
{ label: "Strict TypeScript", description: "Use strict mode, no 'any' type, explicit return types for public APIs" },
|
|
293
|
-
{ label: "Functional style", description: "Prefer pure functions, immutability, avoid class-based patterns where possible" },
|
|
294
|
-
{ label: "Const over let", description: "Always use const; only use let when reassignment is truly needed" }
|
|
295
|
-
)
|
|
296
|
-
} else if (primaryLang === 'Python') {
|
|
297
|
-
codingStyleOptions.push(
|
|
298
|
-
{ label: "Type hints", description: "Use type hints for all function signatures and class attributes" },
|
|
299
|
-
{ label: "Functional style", description: "Prefer pure functions, list comprehensions, avoid mutable state" },
|
|
300
|
-
{ label: "PEP 8 strict", description: "Strict PEP 8 compliance with max line length 88 (Black formatter)" }
|
|
301
|
-
)
|
|
302
|
-
} else if (primaryLang === 'Go') {
|
|
303
|
-
codingStyleOptions.push(
|
|
304
|
-
{ label: "Error wrapping", description: "Always wrap errors with context using fmt.Errorf with %w" },
|
|
305
|
-
{ label: "Interface first", description: "Define interfaces at the consumer side, not the provider" },
|
|
306
|
-
{ label: "Table-driven tests", description: "Use table-driven test pattern for all unit tests" }
|
|
307
|
-
)
|
|
308
|
-
}
|
|
309
|
-
// Add universal options
|
|
310
|
-
codingStyleOptions.push(
|
|
311
|
-
{ label: "Early returns", description: "Prefer early returns / guard clauses over deep nesting" }
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
// Round 1: Coding Conventions
|
|
315
|
-
const round1 = request_user_input({
|
|
316
|
-
questions: [
|
|
317
|
-
{
|
|
318
|
-
header: "Code Style",
|
|
319
|
-
id: "coding_style",
|
|
320
|
-
question: `Your project uses ${primaryLang}. Which coding style conventions do you follow?`,
|
|
321
|
-
options: codingStyleOptions.slice(0, 3) // Max 3 options
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
header: "Naming",
|
|
325
|
-
id: "naming",
|
|
326
|
-
question: `What naming conventions does your ${primaryLang} project use?`,
|
|
327
|
-
options: [
|
|
328
|
-
{ label: "camelCase variables", description: "Variables and functions use camelCase (e.g., getUserName)" },
|
|
329
|
-
{ label: "PascalCase types", description: "Classes, interfaces, type aliases use PascalCase (e.g., UserService)" },
|
|
330
|
-
{ label: "UPPER_SNAKE constants", description: "Constants use UPPER_SNAKE_CASE (e.g., MAX_RETRIES)" }
|
|
331
|
-
]
|
|
332
|
-
}
|
|
333
|
-
]
|
|
334
|
-
}) // BLOCKS (wait for user response)
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
**Process Round 1 answers** -> add to `conventions.coding_style` and `conventions.naming_patterns` arrays.
|
|
338
|
-
|
|
339
|
-
---
|
|
340
|
-
|
|
341
|
-
##### Round 2: File Structure & Documentation
|
|
342
|
-
|
|
343
|
-
```javascript
|
|
344
|
-
// Round 2: File Structure & Documentation
|
|
345
|
-
const round2 = request_user_input({
|
|
346
|
-
questions: [
|
|
347
|
-
{
|
|
348
|
-
header: "File Org",
|
|
349
|
-
id: "file_structure",
|
|
350
|
-
question: `Your project has a ${archStyle} architecture. What file organization rules apply?`,
|
|
351
|
-
options: [
|
|
352
|
-
{ label: "Co-located tests", description: "Test files live next to source files (e.g., foo.ts + foo.test.ts)" },
|
|
353
|
-
{ label: "Separate test dir", description: "Tests in a dedicated __tests__ or tests/ directory" },
|
|
354
|
-
{ label: "One export per file", description: "Each file exports a single main component/class/function" }
|
|
355
|
-
]
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
header: "Docs",
|
|
359
|
-
id: "documentation",
|
|
360
|
-
question: "What documentation standards does your project follow?",
|
|
361
|
-
options: [
|
|
362
|
-
{ label: "JSDoc/docstring public APIs", description: "All public functions and classes must have JSDoc/docstrings" },
|
|
363
|
-
{ label: "Inline comments for why", description: "Comments explain 'why', not 'what' -- code should be self-documenting" },
|
|
364
|
-
{ label: "No comment requirement", description: "Code should be self-explanatory; comments only for non-obvious logic" }
|
|
365
|
-
]
|
|
366
|
-
}
|
|
367
|
-
]
|
|
368
|
-
}) // BLOCKS (wait for user response)
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
**Process Round 2 answers** -> add to `conventions.file_structure` and `conventions.documentation`.
|
|
372
|
-
|
|
373
|
-
---
|
|
374
|
-
|
|
375
|
-
##### Round 3: Architecture & Tech Stack Constraints
|
|
376
|
-
|
|
377
|
-
```javascript
|
|
378
|
-
// Build architecture-specific options
|
|
379
|
-
const archOptions = []
|
|
380
|
-
|
|
381
|
-
if (archStyle.toLowerCase().includes('monolith')) {
|
|
382
|
-
archOptions.push(
|
|
383
|
-
{ label: "No circular deps", description: "Modules must not have circular dependencies" },
|
|
384
|
-
{ label: "Layer boundaries", description: "Strict layer separation: UI -> Service -> Data (no skipping layers)" }
|
|
385
|
-
)
|
|
386
|
-
} else if (archStyle.toLowerCase().includes('microservice')) {
|
|
387
|
-
archOptions.push(
|
|
388
|
-
{ label: "Service isolation", description: "Services must not share databases or internal state" },
|
|
389
|
-
{ label: "API contracts", description: "All inter-service communication through versioned API contracts" }
|
|
390
|
-
)
|
|
391
|
-
}
|
|
392
|
-
archOptions.push(
|
|
393
|
-
{ label: "Stateless services", description: "Service/business logic must be stateless (state in DB/cache only)" },
|
|
394
|
-
{ label: "Dependency injection", description: "Use dependency injection for testability, no hardcoded dependencies" }
|
|
395
|
-
)
|
|
396
|
-
|
|
397
|
-
// Round 3: Architecture & Tech Stack Constraints
|
|
398
|
-
const round3 = request_user_input({
|
|
399
|
-
questions: [
|
|
400
|
-
{
|
|
401
|
-
header: "Architecture",
|
|
402
|
-
id: "architecture",
|
|
403
|
-
question: `Your ${archStyle} architecture uses ${archPatterns.join(', ') || 'various'} patterns. What architecture constraints apply?`,
|
|
404
|
-
options: archOptions.slice(0, 3)
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
header: "Tech Stack",
|
|
408
|
-
id: "tech_stack",
|
|
409
|
-
question: `Tech stack: ${frameworks.join(', ')}. What technology constraints apply?`,
|
|
410
|
-
options: [
|
|
411
|
-
{ label: "No new deps without review", description: "Adding new dependencies requires explicit justification and review" },
|
|
412
|
-
{ label: "Pin dependency versions", description: "All dependencies must use exact versions, not ranges" },
|
|
413
|
-
{ label: "Prefer native APIs", description: "Use built-in/native APIs over third-party libraries when possible" }
|
|
414
|
-
]
|
|
415
|
-
}
|
|
416
|
-
]
|
|
417
|
-
}) // BLOCKS (wait for user response)
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
**Process Round 3 answers** -> add to `constraints.architecture` and `constraints.tech_stack`.
|
|
421
|
-
|
|
422
|
-
---
|
|
423
|
-
|
|
424
|
-
##### Round 4: Performance & Security Constraints
|
|
425
|
-
|
|
426
|
-
```javascript
|
|
427
|
-
// Round 4: Performance & Security Constraints
|
|
428
|
-
const round4 = request_user_input({
|
|
429
|
-
questions: [
|
|
430
|
-
{
|
|
431
|
-
header: "Performance",
|
|
432
|
-
id: "performance",
|
|
433
|
-
question: "What performance requirements does your project have?",
|
|
434
|
-
options: [
|
|
435
|
-
{ label: "API response time", description: "API endpoints must respond within 200ms (p95)" },
|
|
436
|
-
{ label: "Bundle size limit", description: "Frontend bundle size must stay under 500KB gzipped" },
|
|
437
|
-
{ label: "No N+1 queries", description: "Database access must avoid N+1 query patterns" }
|
|
438
|
-
]
|
|
439
|
-
},
|
|
440
|
-
{
|
|
441
|
-
header: "Security",
|
|
442
|
-
id: "security",
|
|
443
|
-
question: "What security requirements does your project enforce?",
|
|
444
|
-
options: [
|
|
445
|
-
{ label: "Input sanitization", description: "All user input must be validated and sanitized before use" },
|
|
446
|
-
{ label: "No secrets in code", description: "No API keys, passwords, or tokens in source code -- use env vars" },
|
|
447
|
-
{ label: "Auth on all endpoints", description: "All API endpoints require authentication unless explicitly public" }
|
|
448
|
-
]
|
|
449
|
-
}
|
|
450
|
-
]
|
|
451
|
-
}) // BLOCKS (wait for user response)
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
**Process Round 4 answers** -> add to `constraints.performance` and `constraints.security`.
|
|
455
|
-
|
|
456
|
-
---
|
|
457
|
-
|
|
458
|
-
##### Round 5: Quality Rules
|
|
459
|
-
|
|
460
|
-
```javascript
|
|
461
|
-
// Round 5: Quality Rules
|
|
462
|
-
const round5 = request_user_input({
|
|
463
|
-
questions: [
|
|
464
|
-
{
|
|
465
|
-
header: "Quality",
|
|
466
|
-
id: "quality",
|
|
467
|
-
question: `Testing with ${testFrameworks.join(', ') || 'your test framework'}. What quality rules apply?`,
|
|
468
|
-
options: [
|
|
469
|
-
{ label: "Min test coverage", description: "Minimum 80% code coverage for new code; no merging below threshold" },
|
|
470
|
-
{ label: "No skipped tests", description: "Tests must not be skipped (.skip/.only) in committed code" },
|
|
471
|
-
{ label: "Lint must pass", description: "All code must pass linter checks before commit (enforced by pre-commit)" }
|
|
472
|
-
]
|
|
473
|
-
}
|
|
474
|
-
]
|
|
475
|
-
}) // BLOCKS (wait for user response)
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
**Process Round 5 answers** -> add to `quality_rules` array as `{ rule, scope, enforced_by }` objects.
|
|
479
|
-
|
|
480
|
-
### Step 6: Write specs/*.md (if not --skip-specs)
|
|
481
|
-
|
|
482
|
-
For each category of collected answers, append rules to the corresponding spec MD file. Each spec file uses YAML frontmatter with `readMode`, `priority`, `category`, and `keywords`.
|
|
483
|
-
|
|
484
|
-
**Category Assignment**: Based on the round and question type:
|
|
485
|
-
- Round 1-2 (conventions): `category: general` (applies to all stages)
|
|
486
|
-
- Round 3 (architecture/tech): `category: planning` (planning phase)
|
|
487
|
-
- Round 4 (performance/security): `category: execution` (implementation phase)
|
|
488
|
-
- Round 5 (quality): `category: execution` (testing phase)
|
|
489
|
-
|
|
490
|
-
```javascript
|
|
491
|
-
// Helper: append rules to a spec MD file with category support
|
|
492
|
-
// Uses .ccw/specs/ directory (same as frontend/backend spec-index-builder)
|
|
493
|
-
function appendRulesToSpecFile(filePath, rules, defaultCategory = 'general') {
|
|
494
|
-
if (rules.length === 0) return
|
|
495
|
-
|
|
496
|
-
// Ensure .ccw/specs/ directory exists
|
|
497
|
-
const specDir = path.dirname(filePath)
|
|
498
|
-
if (!fs.existsSync(specDir)) {
|
|
499
|
-
fs.mkdirSync(specDir, { recursive: true })
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// Check if file exists
|
|
503
|
-
if (!file_exists(filePath)) {
|
|
504
|
-
// Create file with frontmatter including category
|
|
505
|
-
const frontmatter = `---
|
|
506
|
-
title: ${filePath.includes('conventions') ? 'Coding Conventions' : filePath.includes('constraints') ? 'Architecture Constraints' : 'Quality Rules'}
|
|
507
|
-
readMode: optional
|
|
508
|
-
priority: medium
|
|
509
|
-
category: ${defaultCategory}
|
|
510
|
-
scope: project
|
|
511
|
-
dimension: specs
|
|
512
|
-
keywords: [${defaultCategory}, ${filePath.includes('conventions') ? 'convention' : filePath.includes('constraints') ? 'constraint' : 'quality'}]
|
|
513
|
-
---
|
|
514
|
-
|
|
515
|
-
# ${filePath.includes('conventions') ? 'Coding Conventions' : filePath.includes('constraints') ? 'Architecture Constraints' : 'Quality Rules'}
|
|
516
|
-
|
|
517
|
-
`
|
|
518
|
-
Write(filePath, frontmatter)
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
const existing = Read(filePath)
|
|
522
|
-
// Append new rules as markdown list items after existing content
|
|
523
|
-
const newContent = existing.trimEnd() + '\n' + rules.map(r => `- ${r}`).join('\n') + '\n'
|
|
524
|
-
Write(filePath, newContent)
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// Write conventions (general category) - use .ccw/specs/ (same as frontend/backend)
|
|
528
|
-
appendRulesToSpecFile('.ccw/specs/coding-conventions.md',
|
|
529
|
-
[...newCodingStyle, ...newNamingPatterns, ...newFileStructure, ...newDocumentation],
|
|
530
|
-
'general')
|
|
531
|
-
|
|
532
|
-
// Write constraints (planning category)
|
|
533
|
-
appendRulesToSpecFile('.ccw/specs/architecture-constraints.md',
|
|
534
|
-
[...newArchitecture, ...newTechStack, ...newPerformance, ...newSecurity],
|
|
535
|
-
'planning')
|
|
536
|
-
|
|
537
|
-
// Write quality rules (execution category)
|
|
538
|
-
if (newQualityRules.length > 0) {
|
|
539
|
-
const qualityPath = '.ccw/specs/quality-rules.md'
|
|
540
|
-
if (!file_exists(qualityPath)) {
|
|
541
|
-
Write(qualityPath, `---
|
|
542
|
-
title: Quality Rules
|
|
543
|
-
readMode: required
|
|
544
|
-
priority: high
|
|
545
|
-
category: execution
|
|
546
|
-
scope: project
|
|
547
|
-
dimension: specs
|
|
548
|
-
keywords: [execution, quality, testing, coverage, lint]
|
|
549
|
-
---
|
|
550
|
-
|
|
551
|
-
# Quality Rules
|
|
552
|
-
|
|
553
|
-
`)
|
|
554
|
-
}
|
|
555
|
-
appendRulesToSpecFile(qualityPath,
|
|
556
|
-
newQualityRules.map(q => `${q.rule} (scope: ${q.scope}, enforced by: ${q.enforced_by})`),
|
|
557
|
-
'execution')
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
// Rebuild spec index after writing
|
|
561
|
-
Bash('ccw spec rebuild')
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
#### Answer Processing Rules
|
|
565
|
-
|
|
566
|
-
When converting user selections to guideline entries:
|
|
567
|
-
|
|
568
|
-
1. **Selected option** -> Use the option's `description` as the guideline string (it's more precise than the label)
|
|
569
|
-
2. **"Other" with custom text** -> Use the user's text directly as the guideline string
|
|
570
|
-
3. **Deduplication** -> Skip entries that already exist in the guidelines (exact string match)
|
|
571
|
-
4. **Quality rules** -> Convert to `{ rule: description, scope: "all", enforced_by: "code-review" }` format
|
|
572
|
-
|
|
573
|
-
### Step 7: Display Summary
|
|
574
|
-
|
|
575
|
-
```javascript
|
|
576
|
-
const projectTech = JSON.parse(Read('.workflow/project-tech.json'));
|
|
577
|
-
|
|
578
|
-
if (skipSpecs) {
|
|
579
|
-
// Minimal summary for --skip-specs mode
|
|
580
|
-
console.log(`
|
|
581
|
-
Project initialized successfully (tech analysis only)
|
|
582
|
-
|
|
583
|
-
## Project Overview
|
|
584
|
-
Name: ${projectTech.project_name}
|
|
585
|
-
Description: ${projectTech.overview.description}
|
|
586
|
-
|
|
587
|
-
### Technology Stack
|
|
588
|
-
Languages: ${projectTech.overview.technology_stack.languages.map(l => l.name).join(', ')}
|
|
589
|
-
Frameworks: ${projectTech.overview.technology_stack.frameworks.join(', ')}
|
|
590
|
-
|
|
591
|
-
### Architecture
|
|
592
|
-
Style: ${projectTech.overview.architecture.style}
|
|
593
|
-
Components: ${projectTech.overview.key_components.length} core modules
|
|
594
|
-
|
|
595
|
-
---
|
|
596
|
-
Files created:
|
|
597
|
-
- Tech analysis: .workflow/project-tech.json
|
|
598
|
-
- Specs: (skipped via --skip-specs)
|
|
599
|
-
${regenerate ? '- Backup: .workflow/project-tech.json.backup' : ''}
|
|
600
|
-
|
|
601
|
-
Next steps:
|
|
602
|
-
- Use $spec-setup (without --skip-specs) to configure guidelines
|
|
603
|
-
- Use $spec-add to create individual specs
|
|
604
|
-
- Use $workflow-plan to start planning
|
|
605
|
-
`);
|
|
606
|
-
} else {
|
|
607
|
-
// Full summary with guidelines stats
|
|
608
|
-
const countConventions = newCodingStyle.length + newNamingPatterns.length
|
|
609
|
-
+ newFileStructure.length + newDocumentation.length
|
|
610
|
-
const countConstraints = newArchitecture.length + newTechStack.length
|
|
611
|
-
+ newPerformance.length + newSecurity.length
|
|
612
|
-
const countQuality = newQualityRules.length
|
|
613
|
-
|
|
614
|
-
// Get updated spec list
|
|
615
|
-
const specsList = Bash('ccw spec list --json 2>/dev/null || echo "{}"')
|
|
616
|
-
|
|
617
|
-
console.log(`
|
|
618
|
-
Project initialized and guidelines configured
|
|
619
|
-
|
|
620
|
-
## Project Overview
|
|
621
|
-
Name: ${projectTech.project_name}
|
|
622
|
-
Description: ${projectTech.overview.description}
|
|
623
|
-
|
|
624
|
-
### Technology Stack
|
|
625
|
-
Languages: ${projectTech.overview.technology_stack.languages.map(l => l.name).join(', ')}
|
|
626
|
-
Frameworks: ${projectTech.overview.technology_stack.frameworks.join(', ')}
|
|
627
|
-
|
|
628
|
-
### Architecture
|
|
629
|
-
Style: ${projectTech.overview.architecture.style}
|
|
630
|
-
Components: ${projectTech.overview.key_components.length} core modules
|
|
631
|
-
|
|
632
|
-
### Guidelines Summary
|
|
633
|
-
- Conventions: ${countConventions} rules added to coding-conventions.md
|
|
634
|
-
- Constraints: ${countConstraints} rules added to architecture-constraints.md
|
|
635
|
-
- Quality rules: ${countQuality} rules added to quality-rules.md
|
|
636
|
-
|
|
637
|
-
Spec index rebuilt. Use \`ccw spec list\` to view all specs.
|
|
638
|
-
|
|
639
|
-
---
|
|
640
|
-
Files created:
|
|
641
|
-
- Tech analysis: .workflow/project-tech.json
|
|
642
|
-
- Specs: .ccw/specs/ (configured)
|
|
643
|
-
${regenerate ? '- Backup: .workflow/project-tech.json.backup' : ''}
|
|
644
|
-
|
|
645
|
-
Next steps:
|
|
646
|
-
- Use $spec-add to add individual rules later
|
|
647
|
-
- Specs are auto-loaded via hook on each prompt
|
|
648
|
-
- Use $workflow-plan to start planning
|
|
649
|
-
`);
|
|
650
|
-
}
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
## Error Handling
|
|
654
|
-
|
|
655
|
-
| Situation | Action |
|
|
656
|
-
|-----------|--------|
|
|
657
|
-
| **Agent Failure** | Fall back to basic initialization with placeholder overview |
|
|
658
|
-
| **Missing Tools** | Agent uses Qwen fallback or bash-only |
|
|
659
|
-
| **Empty Project** | Create minimal JSON with all gaps identified |
|
|
660
|
-
| **No project-tech.json** (when --reset without prior init) | Run full flow from Step 2 |
|
|
661
|
-
| **User cancels mid-wizard** | Save whatever was collected so far (partial is better than nothing) |
|
|
662
|
-
| **File write failure** | Report error, suggest manual edit |
|
|
663
|
-
|
|
664
|
-
## Related Commands
|
|
665
|
-
|
|
666
|
-
- `$spec-add` - Interactive wizard to create individual specs with scope selection
|
|
667
|
-
- `$session-sync` - Quick-sync session work to specs and project-tech
|
|
668
|
-
- `$workflow-plan` - Start planning with initialized project context
|
|
669
|
-
- `$workflow-status --project` - View project state and guidelines
|
|
1
|
+
---
|
|
2
|
+
name: spec-setup
|
|
3
|
+
description: Initialize project-level state and configure specs via interactive questionnaire.
|
|
4
|
+
argument-hint: "[--regenerate] [--skip-specs] [--reset]"
|
|
5
|
+
allowed-tools: spawn_agent, wait, send_input, close_agent, request_user_input, Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Workflow Spec Setup Command
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Initialize `.workflow/project-tech.json` and `.ccw/specs/*.md` with comprehensive project understanding by delegating analysis to **cli-explore-agent**, then interactively configure project guidelines through a multi-round questionnaire.
|
|
13
|
+
|
|
14
|
+
**Dual File System**:
|
|
15
|
+
- `project-tech.json`: Auto-generated technical analysis (stack, architecture, components)
|
|
16
|
+
- `specs/*.md`: User-maintained rules and constraints (created and populated interactively)
|
|
17
|
+
|
|
18
|
+
**Design Principle**: Questions are dynamically generated based on the project's tech stack, architecture, and patterns -- not generic boilerplate.
|
|
19
|
+
|
|
20
|
+
**Note**: This command may be called by other workflow commands. Upon completion, return immediately to continue the calling workflow without interrupting the task flow.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
$spec-setup # Initialize (skip if exists)
|
|
26
|
+
$spec-setup --regenerate # Force regeneration of project-tech.json
|
|
27
|
+
$spec-setup --skip-specs # Initialize project-tech only, skip spec initialization and questionnaire
|
|
28
|
+
$spec-setup --reset # Reset specs content before questionnaire
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Execution Process
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Input Parsing:
|
|
35
|
+
|- Parse --regenerate flag -> regenerate = true | false
|
|
36
|
+
|- Parse --skip-specs flag -> skipSpecs = true | false
|
|
37
|
+
+- Parse --reset flag -> reset = true | false
|
|
38
|
+
|
|
39
|
+
Decision:
|
|
40
|
+
|- BOTH_EXIST + no --regenerate + no --reset -> Exit: "Already initialized"
|
|
41
|
+
|- EXISTS + --regenerate -> Backup existing -> Continue analysis
|
|
42
|
+
|- EXISTS + --reset -> Reset specs, keep project-tech -> Skip to questionnaire
|
|
43
|
+
+- NOT_FOUND -> Continue full flow
|
|
44
|
+
|
|
45
|
+
Full Flow:
|
|
46
|
+
|- Step 1: Parse input and check existing state
|
|
47
|
+
|- Step 2: Get project metadata (name, root)
|
|
48
|
+
|- Step 3: Invoke cli-explore-agent (subagent)
|
|
49
|
+
| |- Structural scan (get_modules_by_depth.sh, find, wc)
|
|
50
|
+
| |- Semantic analysis (Gemini CLI)
|
|
51
|
+
| |- Synthesis and merge
|
|
52
|
+
| +- Write .workflow/project-tech.json
|
|
53
|
+
|- Step 4: Initialize Spec System (if not --skip-specs)
|
|
54
|
+
| |- Check if specs/*.md exist
|
|
55
|
+
| |- If NOT_FOUND -> Run ccw spec init
|
|
56
|
+
| +- Run ccw spec rebuild
|
|
57
|
+
|- Step 5: Multi-Round Interactive Questionnaire (if not --skip-specs)
|
|
58
|
+
| |- Check if guidelines already populated -> Ask: "Append / Reset / Cancel"
|
|
59
|
+
| |- Load project context from project-tech.json
|
|
60
|
+
| |- Round 1: Coding Conventions (coding_style, naming_patterns)
|
|
61
|
+
| |- Round 2: File & Documentation Conventions (file_structure, documentation)
|
|
62
|
+
| |- Round 3: Architecture & Tech Constraints (architecture, tech_stack)
|
|
63
|
+
| |- Round 4: Performance & Security Constraints (performance, security)
|
|
64
|
+
| +- Round 5: Quality Rules (quality_rules)
|
|
65
|
+
|- Step 6: Write specs/*.md (if not --skip-specs)
|
|
66
|
+
+- Step 7: Display Summary
|
|
67
|
+
|
|
68
|
+
Output:
|
|
69
|
+
|- .workflow/project-tech.json (+ .backup if regenerate)
|
|
70
|
+
+- .ccw/specs/*.md (scaffold or configured, unless --skip-specs)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Implementation
|
|
74
|
+
|
|
75
|
+
### Step 1: Parse Input and Check Existing State
|
|
76
|
+
|
|
77
|
+
**Parse flags**:
|
|
78
|
+
```javascript
|
|
79
|
+
const regenerate = $ARGUMENTS.includes('--regenerate')
|
|
80
|
+
const skipSpecs = $ARGUMENTS.includes('--skip-specs')
|
|
81
|
+
const reset = $ARGUMENTS.includes('--reset')
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Check existing state**:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
bash(test -f .workflow/project-tech.json && echo "TECH_EXISTS" || echo "TECH_NOT_FOUND")
|
|
88
|
+
bash(test -f .ccw/specs/coding-conventions.md && echo "SPECS_EXISTS" || echo "SPECS_NOT_FOUND")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**If BOTH_EXIST and no --regenerate and no --reset**: Exit early
|
|
92
|
+
```
|
|
93
|
+
Project already initialized:
|
|
94
|
+
- Tech analysis: .workflow/project-tech.json
|
|
95
|
+
- Guidelines: .ccw/specs/*.md
|
|
96
|
+
|
|
97
|
+
Use $spec-setup --regenerate to rebuild tech analysis
|
|
98
|
+
Use $spec-setup --reset to reconfigure guidelines
|
|
99
|
+
Use $spec-add to add individual rules
|
|
100
|
+
Use $workflow-status --project to view state
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Step 2: Get Project Metadata
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
bash(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")
|
|
107
|
+
bash(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
108
|
+
bash(mkdir -p .workflow)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Step 3: Invoke cli-explore-agent (Subagent)
|
|
112
|
+
|
|
113
|
+
**For --regenerate**: Backup and preserve existing data
|
|
114
|
+
```bash
|
|
115
|
+
bash(cp .workflow/project-tech.json .workflow/project-tech.json.backup)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Delegate analysis to subagent**:
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
let exploreAgent = null
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
exploreAgent = spawn_agent({
|
|
125
|
+
agent_type: "cli_explore_agent",
|
|
126
|
+
message: `
|
|
127
|
+
## TASK ASSIGNMENT
|
|
128
|
+
|
|
129
|
+
### MANDATORY FIRST STEPS (Agent Execute)
|
|
130
|
+
1. Read: .workflow/project-tech.json (if exists, for --regenerate)
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
Analyze project for workflow initialization and generate .workflow/project-tech.json.
|
|
135
|
+
|
|
136
|
+
## MANDATORY FIRST STEPS
|
|
137
|
+
1. Execute: cat ~/.ccw/workflows/cli-templates/schemas/project-tech-schema.json (get schema reference)
|
|
138
|
+
2. Execute: ccw tool exec get_modules_by_depth '{}' (get project structure)
|
|
139
|
+
|
|
140
|
+
## Task
|
|
141
|
+
Generate complete project-tech.json following the schema structure:
|
|
142
|
+
- project_name: "${projectName}"
|
|
143
|
+
- initialized_at: ISO 8601 timestamp
|
|
144
|
+
- overview: {
|
|
145
|
+
description: "Brief project description",
|
|
146
|
+
technology_stack: {
|
|
147
|
+
languages: [{name, file_count, primary}],
|
|
148
|
+
frameworks: ["string"],
|
|
149
|
+
build_tools: ["string"],
|
|
150
|
+
test_frameworks: ["string"]
|
|
151
|
+
},
|
|
152
|
+
architecture: {style, layers: [], patterns: []},
|
|
153
|
+
key_components: [{name, path, description, importance}]
|
|
154
|
+
}
|
|
155
|
+
- features: []
|
|
156
|
+
- development_index: ${regenerate ? 'preserve from backup' : '{feature: [], enhancement: [], bugfix: [], refactor: [], docs: []}'}
|
|
157
|
+
- statistics: ${regenerate ? 'preserve from backup' : '{total_features: 0, total_sessions: 0, last_updated: ISO timestamp}'}
|
|
158
|
+
- _metadata: {initialized_by: "cli-explore-agent", analysis_timestamp: ISO timestamp, analysis_mode: "deep-scan"}
|
|
159
|
+
|
|
160
|
+
## Analysis Requirements
|
|
161
|
+
|
|
162
|
+
**Technology Stack**:
|
|
163
|
+
- Languages: File counts, mark primary
|
|
164
|
+
- Frameworks: From package.json, requirements.txt, go.mod, etc.
|
|
165
|
+
- Build tools: npm, cargo, maven, webpack, vite
|
|
166
|
+
- Test frameworks: jest, pytest, go test, junit
|
|
167
|
+
|
|
168
|
+
**Architecture**:
|
|
169
|
+
- Style: MVC, microservices, layered (from structure & imports)
|
|
170
|
+
- Layers: presentation, business-logic, data-access
|
|
171
|
+
- Patterns: singleton, factory, repository
|
|
172
|
+
- Key components: 5-10 modules {name, path, description, importance}
|
|
173
|
+
|
|
174
|
+
## Execution
|
|
175
|
+
1. Structural scan: get_modules_by_depth.sh, find, wc -l
|
|
176
|
+
2. Semantic analysis: Gemini for patterns/architecture
|
|
177
|
+
3. Synthesis: Merge findings
|
|
178
|
+
4. ${regenerate ? 'Merge with preserved development_index and statistics from .workflow/project-tech.json.backup' : ''}
|
|
179
|
+
5. Write JSON: Write('.workflow/project-tech.json', jsonContent)
|
|
180
|
+
6. Report: Return brief completion summary
|
|
181
|
+
|
|
182
|
+
Project root: ${projectRoot}
|
|
183
|
+
`
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
// Wait for completion
|
|
187
|
+
const result = wait({ ids: [exploreAgent], timeout_ms: 600000 })
|
|
188
|
+
|
|
189
|
+
if (result.timed_out) {
|
|
190
|
+
send_input({ id: exploreAgent, message: 'Complete analysis now and write project-tech.json.' })
|
|
191
|
+
const retry = wait({ ids: [exploreAgent], timeout_ms: 300000 })
|
|
192
|
+
if (retry.timed_out) throw new Error('Agent timeout')
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
} finally {
|
|
196
|
+
if (exploreAgent) close_agent({ id: exploreAgent })
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Step 4: Initialize Spec System (if not --skip-specs)
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
// Skip spec initialization if --skip-specs flag is provided
|
|
204
|
+
if (!skipSpecs) {
|
|
205
|
+
// Initialize spec system if not already initialized
|
|
206
|
+
const specsCheck = Bash('test -f .ccw/specs/coding-conventions.md && echo EXISTS || echo NOT_FOUND')
|
|
207
|
+
if (specsCheck.includes('NOT_FOUND')) {
|
|
208
|
+
console.log('Initializing spec system...')
|
|
209
|
+
Bash('ccw spec init')
|
|
210
|
+
Bash('ccw spec rebuild')
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
console.log('Skipping spec initialization and questionnaire (--skip-specs)')
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
If `--skip-specs` is provided, skip directly to Step 7 (Display Summary) with limited output.
|
|
218
|
+
|
|
219
|
+
### Step 5: Multi-Round Interactive Questionnaire (if not --skip-specs)
|
|
220
|
+
|
|
221
|
+
#### Step 5.0: Check Existing Guidelines
|
|
222
|
+
|
|
223
|
+
If guidelines already have content, ask the user how to proceed:
|
|
224
|
+
|
|
225
|
+
```javascript
|
|
226
|
+
// Check if specs already have content via ccw spec list
|
|
227
|
+
const specsList = Bash('ccw spec list --json 2>/dev/null || echo "{}"')
|
|
228
|
+
const specsData = JSON.parse(specsList)
|
|
229
|
+
const isPopulated = (specsData.total || 0) > 5 // More than seed docs
|
|
230
|
+
|
|
231
|
+
if (isPopulated && !reset) {
|
|
232
|
+
const mode = request_user_input({
|
|
233
|
+
questions: [{
|
|
234
|
+
header: "Guidelines",
|
|
235
|
+
id: "mode",
|
|
236
|
+
question: "Project guidelines already contain entries. How would you like to proceed?",
|
|
237
|
+
options: [
|
|
238
|
+
{ label: "Append(Recommended)", description: "Keep existing entries and add new ones from the wizard" },
|
|
239
|
+
{ label: "Reset", description: "Clear all existing entries and start fresh" },
|
|
240
|
+
{ label: "Cancel", description: "Exit without changes" }
|
|
241
|
+
]
|
|
242
|
+
}]
|
|
243
|
+
}) // BLOCKS (wait for user response)
|
|
244
|
+
|
|
245
|
+
// If Cancel -> exit
|
|
246
|
+
// If Reset -> clear all arrays before proceeding
|
|
247
|
+
// If Append -> keep existing, wizard adds to them
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// If --reset flag was provided, clear existing entries before proceeding
|
|
251
|
+
if (reset) {
|
|
252
|
+
// Reset specs content
|
|
253
|
+
console.log('Resetting existing guidelines...')
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### Step 5.1: Load Project Context
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
// Load project context via ccw spec load for planning context
|
|
261
|
+
const projectContext = Bash('ccw spec load --category planning 2>/dev/null || echo "{}"')
|
|
262
|
+
const specData = JSON.parse(projectContext)
|
|
263
|
+
|
|
264
|
+
// Extract key info from loaded specs for generating smart questions
|
|
265
|
+
const languages = specData.overview?.technology_stack?.languages || []
|
|
266
|
+
const primaryLang = languages.find(l => l.primary)?.name || languages[0]?.name || 'Unknown'
|
|
267
|
+
const frameworks = specData.overview?.technology_stack?.frameworks || []
|
|
268
|
+
const testFrameworks = specData.overview?.technology_stack?.test_frameworks || []
|
|
269
|
+
const archStyle = specData.overview?.architecture?.style || 'Unknown'
|
|
270
|
+
const archPatterns = specData.overview?.architecture?.patterns || []
|
|
271
|
+
const buildTools = specData.overview?.technology_stack?.build_tools || []
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
#### Step 5.2: Multi-Round Questionnaire
|
|
275
|
+
|
|
276
|
+
Each round uses `request_user_input` with project-aware options. The user can always select "Other" to provide custom input.
|
|
277
|
+
|
|
278
|
+
**CRITICAL**: After each round, collect the user's answers and convert them into guideline entries. Do NOT batch all rounds -- process each round's answers before proceeding to the next.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
##### Round 1: Coding Conventions
|
|
283
|
+
|
|
284
|
+
Generate options dynamically based on detected language/framework:
|
|
285
|
+
|
|
286
|
+
```javascript
|
|
287
|
+
// Build language-specific coding style options
|
|
288
|
+
const codingStyleOptions = []
|
|
289
|
+
|
|
290
|
+
if (['TypeScript', 'JavaScript'].includes(primaryLang)) {
|
|
291
|
+
codingStyleOptions.push(
|
|
292
|
+
{ label: "Strict TypeScript", description: "Use strict mode, no 'any' type, explicit return types for public APIs" },
|
|
293
|
+
{ label: "Functional style", description: "Prefer pure functions, immutability, avoid class-based patterns where possible" },
|
|
294
|
+
{ label: "Const over let", description: "Always use const; only use let when reassignment is truly needed" }
|
|
295
|
+
)
|
|
296
|
+
} else if (primaryLang === 'Python') {
|
|
297
|
+
codingStyleOptions.push(
|
|
298
|
+
{ label: "Type hints", description: "Use type hints for all function signatures and class attributes" },
|
|
299
|
+
{ label: "Functional style", description: "Prefer pure functions, list comprehensions, avoid mutable state" },
|
|
300
|
+
{ label: "PEP 8 strict", description: "Strict PEP 8 compliance with max line length 88 (Black formatter)" }
|
|
301
|
+
)
|
|
302
|
+
} else if (primaryLang === 'Go') {
|
|
303
|
+
codingStyleOptions.push(
|
|
304
|
+
{ label: "Error wrapping", description: "Always wrap errors with context using fmt.Errorf with %w" },
|
|
305
|
+
{ label: "Interface first", description: "Define interfaces at the consumer side, not the provider" },
|
|
306
|
+
{ label: "Table-driven tests", description: "Use table-driven test pattern for all unit tests" }
|
|
307
|
+
)
|
|
308
|
+
}
|
|
309
|
+
// Add universal options
|
|
310
|
+
codingStyleOptions.push(
|
|
311
|
+
{ label: "Early returns", description: "Prefer early returns / guard clauses over deep nesting" }
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
// Round 1: Coding Conventions
|
|
315
|
+
const round1 = request_user_input({
|
|
316
|
+
questions: [
|
|
317
|
+
{
|
|
318
|
+
header: "Code Style",
|
|
319
|
+
id: "coding_style",
|
|
320
|
+
question: `Your project uses ${primaryLang}. Which coding style conventions do you follow?`,
|
|
321
|
+
options: codingStyleOptions.slice(0, 3) // Max 3 options
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
header: "Naming",
|
|
325
|
+
id: "naming",
|
|
326
|
+
question: `What naming conventions does your ${primaryLang} project use?`,
|
|
327
|
+
options: [
|
|
328
|
+
{ label: "camelCase variables", description: "Variables and functions use camelCase (e.g., getUserName)" },
|
|
329
|
+
{ label: "PascalCase types", description: "Classes, interfaces, type aliases use PascalCase (e.g., UserService)" },
|
|
330
|
+
{ label: "UPPER_SNAKE constants", description: "Constants use UPPER_SNAKE_CASE (e.g., MAX_RETRIES)" }
|
|
331
|
+
]
|
|
332
|
+
}
|
|
333
|
+
]
|
|
334
|
+
}) // BLOCKS (wait for user response)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Process Round 1 answers** -> add to `conventions.coding_style` and `conventions.naming_patterns` arrays.
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
##### Round 2: File Structure & Documentation
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
// Round 2: File Structure & Documentation
|
|
345
|
+
const round2 = request_user_input({
|
|
346
|
+
questions: [
|
|
347
|
+
{
|
|
348
|
+
header: "File Org",
|
|
349
|
+
id: "file_structure",
|
|
350
|
+
question: `Your project has a ${archStyle} architecture. What file organization rules apply?`,
|
|
351
|
+
options: [
|
|
352
|
+
{ label: "Co-located tests", description: "Test files live next to source files (e.g., foo.ts + foo.test.ts)" },
|
|
353
|
+
{ label: "Separate test dir", description: "Tests in a dedicated __tests__ or tests/ directory" },
|
|
354
|
+
{ label: "One export per file", description: "Each file exports a single main component/class/function" }
|
|
355
|
+
]
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
header: "Docs",
|
|
359
|
+
id: "documentation",
|
|
360
|
+
question: "What documentation standards does your project follow?",
|
|
361
|
+
options: [
|
|
362
|
+
{ label: "JSDoc/docstring public APIs", description: "All public functions and classes must have JSDoc/docstrings" },
|
|
363
|
+
{ label: "Inline comments for why", description: "Comments explain 'why', not 'what' -- code should be self-documenting" },
|
|
364
|
+
{ label: "No comment requirement", description: "Code should be self-explanatory; comments only for non-obvious logic" }
|
|
365
|
+
]
|
|
366
|
+
}
|
|
367
|
+
]
|
|
368
|
+
}) // BLOCKS (wait for user response)
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Process Round 2 answers** -> add to `conventions.file_structure` and `conventions.documentation`.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
##### Round 3: Architecture & Tech Stack Constraints
|
|
376
|
+
|
|
377
|
+
```javascript
|
|
378
|
+
// Build architecture-specific options
|
|
379
|
+
const archOptions = []
|
|
380
|
+
|
|
381
|
+
if (archStyle.toLowerCase().includes('monolith')) {
|
|
382
|
+
archOptions.push(
|
|
383
|
+
{ label: "No circular deps", description: "Modules must not have circular dependencies" },
|
|
384
|
+
{ label: "Layer boundaries", description: "Strict layer separation: UI -> Service -> Data (no skipping layers)" }
|
|
385
|
+
)
|
|
386
|
+
} else if (archStyle.toLowerCase().includes('microservice')) {
|
|
387
|
+
archOptions.push(
|
|
388
|
+
{ label: "Service isolation", description: "Services must not share databases or internal state" },
|
|
389
|
+
{ label: "API contracts", description: "All inter-service communication through versioned API contracts" }
|
|
390
|
+
)
|
|
391
|
+
}
|
|
392
|
+
archOptions.push(
|
|
393
|
+
{ label: "Stateless services", description: "Service/business logic must be stateless (state in DB/cache only)" },
|
|
394
|
+
{ label: "Dependency injection", description: "Use dependency injection for testability, no hardcoded dependencies" }
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
// Round 3: Architecture & Tech Stack Constraints
|
|
398
|
+
const round3 = request_user_input({
|
|
399
|
+
questions: [
|
|
400
|
+
{
|
|
401
|
+
header: "Architecture",
|
|
402
|
+
id: "architecture",
|
|
403
|
+
question: `Your ${archStyle} architecture uses ${archPatterns.join(', ') || 'various'} patterns. What architecture constraints apply?`,
|
|
404
|
+
options: archOptions.slice(0, 3)
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
header: "Tech Stack",
|
|
408
|
+
id: "tech_stack",
|
|
409
|
+
question: `Tech stack: ${frameworks.join(', ')}. What technology constraints apply?`,
|
|
410
|
+
options: [
|
|
411
|
+
{ label: "No new deps without review", description: "Adding new dependencies requires explicit justification and review" },
|
|
412
|
+
{ label: "Pin dependency versions", description: "All dependencies must use exact versions, not ranges" },
|
|
413
|
+
{ label: "Prefer native APIs", description: "Use built-in/native APIs over third-party libraries when possible" }
|
|
414
|
+
]
|
|
415
|
+
}
|
|
416
|
+
]
|
|
417
|
+
}) // BLOCKS (wait for user response)
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Process Round 3 answers** -> add to `constraints.architecture` and `constraints.tech_stack`.
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
##### Round 4: Performance & Security Constraints
|
|
425
|
+
|
|
426
|
+
```javascript
|
|
427
|
+
// Round 4: Performance & Security Constraints
|
|
428
|
+
const round4 = request_user_input({
|
|
429
|
+
questions: [
|
|
430
|
+
{
|
|
431
|
+
header: "Performance",
|
|
432
|
+
id: "performance",
|
|
433
|
+
question: "What performance requirements does your project have?",
|
|
434
|
+
options: [
|
|
435
|
+
{ label: "API response time", description: "API endpoints must respond within 200ms (p95)" },
|
|
436
|
+
{ label: "Bundle size limit", description: "Frontend bundle size must stay under 500KB gzipped" },
|
|
437
|
+
{ label: "No N+1 queries", description: "Database access must avoid N+1 query patterns" }
|
|
438
|
+
]
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
header: "Security",
|
|
442
|
+
id: "security",
|
|
443
|
+
question: "What security requirements does your project enforce?",
|
|
444
|
+
options: [
|
|
445
|
+
{ label: "Input sanitization", description: "All user input must be validated and sanitized before use" },
|
|
446
|
+
{ label: "No secrets in code", description: "No API keys, passwords, or tokens in source code -- use env vars" },
|
|
447
|
+
{ label: "Auth on all endpoints", description: "All API endpoints require authentication unless explicitly public" }
|
|
448
|
+
]
|
|
449
|
+
}
|
|
450
|
+
]
|
|
451
|
+
}) // BLOCKS (wait for user response)
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
**Process Round 4 answers** -> add to `constraints.performance` and `constraints.security`.
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
##### Round 5: Quality Rules
|
|
459
|
+
|
|
460
|
+
```javascript
|
|
461
|
+
// Round 5: Quality Rules
|
|
462
|
+
const round5 = request_user_input({
|
|
463
|
+
questions: [
|
|
464
|
+
{
|
|
465
|
+
header: "Quality",
|
|
466
|
+
id: "quality",
|
|
467
|
+
question: `Testing with ${testFrameworks.join(', ') || 'your test framework'}. What quality rules apply?`,
|
|
468
|
+
options: [
|
|
469
|
+
{ label: "Min test coverage", description: "Minimum 80% code coverage for new code; no merging below threshold" },
|
|
470
|
+
{ label: "No skipped tests", description: "Tests must not be skipped (.skip/.only) in committed code" },
|
|
471
|
+
{ label: "Lint must pass", description: "All code must pass linter checks before commit (enforced by pre-commit)" }
|
|
472
|
+
]
|
|
473
|
+
}
|
|
474
|
+
]
|
|
475
|
+
}) // BLOCKS (wait for user response)
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**Process Round 5 answers** -> add to `quality_rules` array as `{ rule, scope, enforced_by }` objects.
|
|
479
|
+
|
|
480
|
+
### Step 6: Write specs/*.md (if not --skip-specs)
|
|
481
|
+
|
|
482
|
+
For each category of collected answers, append rules to the corresponding spec MD file. Each spec file uses YAML frontmatter with `readMode`, `priority`, `category`, and `keywords`.
|
|
483
|
+
|
|
484
|
+
**Category Assignment**: Based on the round and question type:
|
|
485
|
+
- Round 1-2 (conventions): `category: general` (applies to all stages)
|
|
486
|
+
- Round 3 (architecture/tech): `category: planning` (planning phase)
|
|
487
|
+
- Round 4 (performance/security): `category: execution` (implementation phase)
|
|
488
|
+
- Round 5 (quality): `category: execution` (testing phase)
|
|
489
|
+
|
|
490
|
+
```javascript
|
|
491
|
+
// Helper: append rules to a spec MD file with category support
|
|
492
|
+
// Uses .ccw/specs/ directory (same as frontend/backend spec-index-builder)
|
|
493
|
+
function appendRulesToSpecFile(filePath, rules, defaultCategory = 'general') {
|
|
494
|
+
if (rules.length === 0) return
|
|
495
|
+
|
|
496
|
+
// Ensure .ccw/specs/ directory exists
|
|
497
|
+
const specDir = path.dirname(filePath)
|
|
498
|
+
if (!fs.existsSync(specDir)) {
|
|
499
|
+
fs.mkdirSync(specDir, { recursive: true })
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Check if file exists
|
|
503
|
+
if (!file_exists(filePath)) {
|
|
504
|
+
// Create file with frontmatter including category
|
|
505
|
+
const frontmatter = `---
|
|
506
|
+
title: ${filePath.includes('conventions') ? 'Coding Conventions' : filePath.includes('constraints') ? 'Architecture Constraints' : 'Quality Rules'}
|
|
507
|
+
readMode: optional
|
|
508
|
+
priority: medium
|
|
509
|
+
category: ${defaultCategory}
|
|
510
|
+
scope: project
|
|
511
|
+
dimension: specs
|
|
512
|
+
keywords: [${defaultCategory}, ${filePath.includes('conventions') ? 'convention' : filePath.includes('constraints') ? 'constraint' : 'quality'}]
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
# ${filePath.includes('conventions') ? 'Coding Conventions' : filePath.includes('constraints') ? 'Architecture Constraints' : 'Quality Rules'}
|
|
516
|
+
|
|
517
|
+
`
|
|
518
|
+
Write(filePath, frontmatter)
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const existing = Read(filePath)
|
|
522
|
+
// Append new rules as markdown list items after existing content
|
|
523
|
+
const newContent = existing.trimEnd() + '\n' + rules.map(r => `- ${r}`).join('\n') + '\n'
|
|
524
|
+
Write(filePath, newContent)
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Write conventions (general category) - use .ccw/specs/ (same as frontend/backend)
|
|
528
|
+
appendRulesToSpecFile('.ccw/specs/coding-conventions.md',
|
|
529
|
+
[...newCodingStyle, ...newNamingPatterns, ...newFileStructure, ...newDocumentation],
|
|
530
|
+
'general')
|
|
531
|
+
|
|
532
|
+
// Write constraints (planning category)
|
|
533
|
+
appendRulesToSpecFile('.ccw/specs/architecture-constraints.md',
|
|
534
|
+
[...newArchitecture, ...newTechStack, ...newPerformance, ...newSecurity],
|
|
535
|
+
'planning')
|
|
536
|
+
|
|
537
|
+
// Write quality rules (execution category)
|
|
538
|
+
if (newQualityRules.length > 0) {
|
|
539
|
+
const qualityPath = '.ccw/specs/quality-rules.md'
|
|
540
|
+
if (!file_exists(qualityPath)) {
|
|
541
|
+
Write(qualityPath, `---
|
|
542
|
+
title: Quality Rules
|
|
543
|
+
readMode: required
|
|
544
|
+
priority: high
|
|
545
|
+
category: execution
|
|
546
|
+
scope: project
|
|
547
|
+
dimension: specs
|
|
548
|
+
keywords: [execution, quality, testing, coverage, lint]
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
# Quality Rules
|
|
552
|
+
|
|
553
|
+
`)
|
|
554
|
+
}
|
|
555
|
+
appendRulesToSpecFile(qualityPath,
|
|
556
|
+
newQualityRules.map(q => `${q.rule} (scope: ${q.scope}, enforced by: ${q.enforced_by})`),
|
|
557
|
+
'execution')
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Rebuild spec index after writing
|
|
561
|
+
Bash('ccw spec rebuild')
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
#### Answer Processing Rules
|
|
565
|
+
|
|
566
|
+
When converting user selections to guideline entries:
|
|
567
|
+
|
|
568
|
+
1. **Selected option** -> Use the option's `description` as the guideline string (it's more precise than the label)
|
|
569
|
+
2. **"Other" with custom text** -> Use the user's text directly as the guideline string
|
|
570
|
+
3. **Deduplication** -> Skip entries that already exist in the guidelines (exact string match)
|
|
571
|
+
4. **Quality rules** -> Convert to `{ rule: description, scope: "all", enforced_by: "code-review" }` format
|
|
572
|
+
|
|
573
|
+
### Step 7: Display Summary
|
|
574
|
+
|
|
575
|
+
```javascript
|
|
576
|
+
const projectTech = JSON.parse(Read('.workflow/project-tech.json'));
|
|
577
|
+
|
|
578
|
+
if (skipSpecs) {
|
|
579
|
+
// Minimal summary for --skip-specs mode
|
|
580
|
+
console.log(`
|
|
581
|
+
Project initialized successfully (tech analysis only)
|
|
582
|
+
|
|
583
|
+
## Project Overview
|
|
584
|
+
Name: ${projectTech.project_name}
|
|
585
|
+
Description: ${projectTech.overview.description}
|
|
586
|
+
|
|
587
|
+
### Technology Stack
|
|
588
|
+
Languages: ${projectTech.overview.technology_stack.languages.map(l => l.name).join(', ')}
|
|
589
|
+
Frameworks: ${projectTech.overview.technology_stack.frameworks.join(', ')}
|
|
590
|
+
|
|
591
|
+
### Architecture
|
|
592
|
+
Style: ${projectTech.overview.architecture.style}
|
|
593
|
+
Components: ${projectTech.overview.key_components.length} core modules
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
Files created:
|
|
597
|
+
- Tech analysis: .workflow/project-tech.json
|
|
598
|
+
- Specs: (skipped via --skip-specs)
|
|
599
|
+
${regenerate ? '- Backup: .workflow/project-tech.json.backup' : ''}
|
|
600
|
+
|
|
601
|
+
Next steps:
|
|
602
|
+
- Use $spec-setup (without --skip-specs) to configure guidelines
|
|
603
|
+
- Use $spec-add to create individual specs
|
|
604
|
+
- Use $workflow-plan to start planning
|
|
605
|
+
`);
|
|
606
|
+
} else {
|
|
607
|
+
// Full summary with guidelines stats
|
|
608
|
+
const countConventions = newCodingStyle.length + newNamingPatterns.length
|
|
609
|
+
+ newFileStructure.length + newDocumentation.length
|
|
610
|
+
const countConstraints = newArchitecture.length + newTechStack.length
|
|
611
|
+
+ newPerformance.length + newSecurity.length
|
|
612
|
+
const countQuality = newQualityRules.length
|
|
613
|
+
|
|
614
|
+
// Get updated spec list
|
|
615
|
+
const specsList = Bash('ccw spec list --json 2>/dev/null || echo "{}"')
|
|
616
|
+
|
|
617
|
+
console.log(`
|
|
618
|
+
Project initialized and guidelines configured
|
|
619
|
+
|
|
620
|
+
## Project Overview
|
|
621
|
+
Name: ${projectTech.project_name}
|
|
622
|
+
Description: ${projectTech.overview.description}
|
|
623
|
+
|
|
624
|
+
### Technology Stack
|
|
625
|
+
Languages: ${projectTech.overview.technology_stack.languages.map(l => l.name).join(', ')}
|
|
626
|
+
Frameworks: ${projectTech.overview.technology_stack.frameworks.join(', ')}
|
|
627
|
+
|
|
628
|
+
### Architecture
|
|
629
|
+
Style: ${projectTech.overview.architecture.style}
|
|
630
|
+
Components: ${projectTech.overview.key_components.length} core modules
|
|
631
|
+
|
|
632
|
+
### Guidelines Summary
|
|
633
|
+
- Conventions: ${countConventions} rules added to coding-conventions.md
|
|
634
|
+
- Constraints: ${countConstraints} rules added to architecture-constraints.md
|
|
635
|
+
- Quality rules: ${countQuality} rules added to quality-rules.md
|
|
636
|
+
|
|
637
|
+
Spec index rebuilt. Use \`ccw spec list\` to view all specs.
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
Files created:
|
|
641
|
+
- Tech analysis: .workflow/project-tech.json
|
|
642
|
+
- Specs: .ccw/specs/ (configured)
|
|
643
|
+
${regenerate ? '- Backup: .workflow/project-tech.json.backup' : ''}
|
|
644
|
+
|
|
645
|
+
Next steps:
|
|
646
|
+
- Use $spec-add to add individual rules later
|
|
647
|
+
- Specs are auto-loaded via hook on each prompt
|
|
648
|
+
- Use $workflow-plan to start planning
|
|
649
|
+
`);
|
|
650
|
+
}
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
## Error Handling
|
|
654
|
+
|
|
655
|
+
| Situation | Action |
|
|
656
|
+
|-----------|--------|
|
|
657
|
+
| **Agent Failure** | Fall back to basic initialization with placeholder overview |
|
|
658
|
+
| **Missing Tools** | Agent uses Qwen fallback or bash-only |
|
|
659
|
+
| **Empty Project** | Create minimal JSON with all gaps identified |
|
|
660
|
+
| **No project-tech.json** (when --reset without prior init) | Run full flow from Step 2 |
|
|
661
|
+
| **User cancels mid-wizard** | Save whatever was collected so far (partial is better than nothing) |
|
|
662
|
+
| **File write failure** | Report error, suggest manual edit |
|
|
663
|
+
|
|
664
|
+
## Related Commands
|
|
665
|
+
|
|
666
|
+
- `$spec-add` - Interactive wizard to create individual specs with scope selection
|
|
667
|
+
- `$session-sync` - Quick-sync session work to specs and project-tech
|
|
668
|
+
- `$workflow-plan` - Start planning with initialized project context
|
|
669
|
+
- `$workflow-status --project` - View project state and guidelines
|