claude-code-workflow 7.2.14 → 7.2.15

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.
Files changed (75) hide show
  1. package/.claude/commands/workflow/analyze-with-file.md +7 -0
  2. package/.codex/skills/analyze-with-file/SKILL.md +1181 -1182
  3. package/.codex/skills/brainstorm/SKILL.md +723 -725
  4. package/.codex/skills/brainstorm-with-file/SKILL.md +10 -5
  5. package/.codex/skills/clean/SKILL.md +33 -26
  6. package/.codex/skills/collaborative-plan-with-file/SKILL.md +830 -831
  7. package/.codex/skills/csv-wave-pipeline/SKILL.md +906 -906
  8. package/.codex/skills/issue-discover/SKILL.md +57 -50
  9. package/.codex/skills/issue-discover/phases/01-issue-new.md +18 -11
  10. package/.codex/skills/issue-discover/phases/02-discover.md +31 -26
  11. package/.codex/skills/issue-discover/phases/03-discover-by-prompt.md +13 -11
  12. package/.codex/skills/issue-discover/phases/04-quick-execute.md +32 -27
  13. package/.codex/skills/parallel-dev-cycle/SKILL.md +402 -402
  14. package/.codex/skills/project-documentation-workflow/SKILL.md +13 -3
  15. package/.codex/skills/roadmap-with-file/SKILL.md +901 -897
  16. package/.codex/skills/session-sync/SKILL.md +222 -212
  17. package/.codex/skills/spec-add/SKILL.md +620 -613
  18. package/.codex/skills/spec-generator/SKILL.md +2 -2
  19. package/.codex/skills/spec-generator/phases/01-5-requirement-clarification.md +10 -10
  20. package/.codex/skills/spec-generator/phases/01-discovery.md +11 -18
  21. package/.codex/skills/spec-generator/phases/02-product-brief.md +5 -5
  22. package/.codex/skills/spec-generator/phases/03-requirements.md +7 -7
  23. package/.codex/skills/spec-generator/phases/04-architecture.md +4 -4
  24. package/.codex/skills/spec-generator/phases/05-epics-stories.md +5 -6
  25. package/.codex/skills/spec-generator/phases/06-readiness-check.md +10 -17
  26. package/.codex/skills/spec-generator/phases/07-issue-export.md +326 -329
  27. package/.codex/skills/spec-setup/SKILL.md +669 -657
  28. package/.codex/skills/team-arch-opt/SKILL.md +50 -50
  29. package/.codex/skills/team-arch-opt/agents/completion-handler.md +3 -3
  30. package/.codex/skills/team-brainstorm/SKILL.md +724 -725
  31. package/.codex/skills/team-coordinate/SKILL.md +51 -51
  32. package/.codex/skills/team-coordinate/agents/completion-handler.md +3 -3
  33. package/.codex/skills/team-coordinate/agents/plan-reviewer.md +4 -4
  34. package/.codex/skills/team-designer/SKILL.md +691 -691
  35. package/.codex/skills/team-designer/agents/requirement-clarifier.md +11 -12
  36. package/.codex/skills/team-executor/SKILL.md +45 -45
  37. package/.codex/skills/team-frontend/SKILL.md +45 -45
  38. package/.codex/skills/team-frontend/agents/completion-handler.md +3 -3
  39. package/.codex/skills/team-frontend/agents/qa-gate-reviewer.md +4 -4
  40. package/.codex/skills/team-frontend-debug/SKILL.md +50 -50
  41. package/.codex/skills/team-frontend-debug/agents/completion-handler.md +3 -3
  42. package/.codex/skills/team-frontend-debug/agents/conditional-skip-gate.md +4 -4
  43. package/.codex/skills/team-issue/SKILL.md +751 -740
  44. package/.codex/skills/team-iterdev/SKILL.md +825 -826
  45. package/.codex/skills/team-lifecycle-v4/SKILL.md +775 -775
  46. package/.codex/skills/team-lifecycle-v4/agents/quality-gate.md +165 -165
  47. package/.codex/skills/team-lifecycle-v4/agents/requirement-clarifier.md +163 -163
  48. package/.codex/skills/team-perf-opt/SKILL.md +50 -50
  49. package/.codex/skills/team-perf-opt/agents/completion-handler.md +3 -3
  50. package/.codex/skills/team-planex-v2/SKILL.md +652 -637
  51. package/.codex/skills/team-quality-assurance/SKILL.md +51 -52
  52. package/.codex/skills/team-review/SKILL.md +40 -40
  53. package/.codex/skills/team-roadmap-dev/SKILL.md +51 -51
  54. package/.codex/skills/team-roadmap-dev/agents/roadmap-discusser.md +8 -8
  55. package/.codex/skills/team-tech-debt/SKILL.md +50 -50
  56. package/.codex/skills/team-tech-debt/agents/plan-approver.md +5 -5
  57. package/.codex/skills/team-testing/SKILL.md +51 -52
  58. package/.codex/skills/team-uidesign/SKILL.md +40 -40
  59. package/.codex/skills/team-uidesign/agents/completion-handler.md +177 -177
  60. package/.codex/skills/team-ultra-analyze/SKILL.md +786 -787
  61. package/.codex/skills/team-ultra-analyze/agents/discussion-feedback.md +8 -8
  62. package/.codex/skills/team-ux-improve/SKILL.md +51 -52
  63. package/.codex/skills/team-ux-improve/agents/ux-designer.md +2 -2
  64. package/.codex/skills/team-ux-improve/agents/ux-explorer.md +1 -1
  65. package/.codex/skills/unified-execute-with-file/SKILL.md +797 -796
  66. package/.codex/skills/workflow-execute/SKILL.md +1117 -1118
  67. package/.codex/skills/workflow-lite-planex/SKILL.md +1144 -1141
  68. package/.codex/skills/workflow-plan/SKILL.md +631 -636
  69. package/.codex/skills/workflow-tdd-plan/SKILL.md +753 -759
  70. package/.codex/skills/workflow-test-fix-cycle/SKILL.md +402 -392
  71. package/README.md +25 -0
  72. package/ccw/dist/commands/install.d.ts.map +1 -1
  73. package/ccw/dist/commands/install.js +12 -0
  74. package/ccw/dist/commands/install.js.map +1 -1
  75. package/package.json +1 -1
@@ -1,657 +1,669 @@
1
- ---
2
- name: spec-setup
3
- description: Initialize project-level state and configure specs via interactive questionnaire using cli-explore-agent
4
- argument-hint: "[--regenerate] [--skip-specs] [--reset]"
5
- allowed-tools: spawn_agent, wait, send_input, close_agent, AskUserQuestion, 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
- message: `
126
- ## TASK ASSIGNMENT
127
-
128
- ### MANDATORY FIRST STEPS (Agent Execute)
129
- 1. **Read role definition**: ~/.codex/agents/cli-explore-agent.md (MUST read first)
130
- 2. 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 = ASK_USER([
233
- {
234
- id: "mode", type: "select",
235
- prompt: "Project guidelines already contain entries. How would you like to proceed?",
236
- options: [
237
- { label: "Append", description: "Keep existing entries and add new ones from the wizard" },
238
- { label: "Reset", description: "Clear all existing entries and start fresh" },
239
- { label: "Cancel", description: "Exit without changes" }
240
- ],
241
- default: "Append"
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 `ASK_USER` 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 = ASK_USER([
316
- {
317
- id: "coding_style", type: "multi-select",
318
- prompt: `Your project uses ${primaryLang}. Which coding style conventions do you follow?`,
319
- options: codingStyleOptions.slice(0, 4) // Max 4 options
320
- },
321
- {
322
- id: "naming", type: "multi-select",
323
- prompt: `What naming conventions does your ${primaryLang} project use?`,
324
- options: [
325
- { label: "camelCase variables", description: "Variables and functions use camelCase (e.g., getUserName)" },
326
- { label: "PascalCase types", description: "Classes, interfaces, type aliases use PascalCase (e.g., UserService)" },
327
- { label: "UPPER_SNAKE constants", description: "Constants use UPPER_SNAKE_CASE (e.g., MAX_RETRIES)" },
328
- { label: "Prefix interfaces", description: "Prefix interfaces with 'I' (e.g., IUserService)" }
329
- ]
330
- }
331
- ]) // BLOCKS (wait for user response)
332
- ```
333
-
334
- **Process Round 1 answers** -> add to `conventions.coding_style` and `conventions.naming_patterns` arrays.
335
-
336
- ---
337
-
338
- ##### Round 2: File Structure & Documentation
339
-
340
- ```javascript
341
- // Round 2: File Structure & Documentation
342
- const round2 = ASK_USER([
343
- {
344
- id: "file_structure", type: "multi-select",
345
- prompt: `Your project has a ${archStyle} architecture. What file organization rules apply?`,
346
- options: [
347
- { label: "Co-located tests", description: "Test files live next to source files (e.g., foo.ts + foo.test.ts)" },
348
- { label: "Separate test dir", description: "Tests in a dedicated __tests__ or tests/ directory" },
349
- { label: "One export per file", description: "Each file exports a single main component/class/function" },
350
- { label: "Index barrels", description: "Use index.ts barrel files for clean imports from directories" }
351
- ]
352
- },
353
- {
354
- id: "documentation", type: "multi-select",
355
- prompt: "What documentation standards does your project follow?",
356
- options: [
357
- { label: "JSDoc/docstring public APIs", description: "All public functions and classes must have JSDoc/docstrings" },
358
- { label: "README per module", description: "Each major module/package has its own README" },
359
- { label: "Inline comments for why", description: "Comments explain 'why', not 'what' -- code should be self-documenting" },
360
- { label: "No comment requirement", description: "Code should be self-explanatory; comments only for non-obvious logic" }
361
- ]
362
- }
363
- ]) // BLOCKS (wait for user response)
364
- ```
365
-
366
- **Process Round 2 answers** -> add to `conventions.file_structure` and `conventions.documentation`.
367
-
368
- ---
369
-
370
- ##### Round 3: Architecture & Tech Stack Constraints
371
-
372
- ```javascript
373
- // Build architecture-specific options
374
- const archOptions = []
375
-
376
- if (archStyle.toLowerCase().includes('monolith')) {
377
- archOptions.push(
378
- { label: "No circular deps", description: "Modules must not have circular dependencies" },
379
- { label: "Layer boundaries", description: "Strict layer separation: UI -> Service -> Data (no skipping layers)" }
380
- )
381
- } else if (archStyle.toLowerCase().includes('microservice')) {
382
- archOptions.push(
383
- { label: "Service isolation", description: "Services must not share databases or internal state" },
384
- { label: "API contracts", description: "All inter-service communication through versioned API contracts" }
385
- )
386
- }
387
- archOptions.push(
388
- { label: "Stateless services", description: "Service/business logic must be stateless (state in DB/cache only)" },
389
- { label: "Dependency injection", description: "Use dependency injection for testability, no hardcoded dependencies" }
390
- )
391
-
392
- // Round 3: Architecture & Tech Stack Constraints
393
- const round3 = ASK_USER([
394
- {
395
- id: "architecture", type: "multi-select",
396
- prompt: `Your ${archStyle} architecture uses ${archPatterns.join(', ') || 'various'} patterns. What architecture constraints apply?`,
397
- options: archOptions.slice(0, 4)
398
- },
399
- {
400
- id: "tech_stack", type: "multi-select",
401
- prompt: `Tech stack: ${frameworks.join(', ')}. What technology constraints apply?`,
402
- options: [
403
- { label: "No new deps without review", description: "Adding new dependencies requires explicit justification and review" },
404
- { label: "Pin dependency versions", description: "All dependencies must use exact versions, not ranges" },
405
- { label: "Prefer native APIs", description: "Use built-in/native APIs over third-party libraries when possible" },
406
- { label: "Framework conventions", description: `Follow official ${frameworks[0] || 'framework'} conventions and best practices` }
407
- ]
408
- }
409
- ]) // BLOCKS (wait for user response)
410
- ```
411
-
412
- **Process Round 3 answers** -> add to `constraints.architecture` and `constraints.tech_stack`.
413
-
414
- ---
415
-
416
- ##### Round 4: Performance & Security Constraints
417
-
418
- ```javascript
419
- // Round 4: Performance & Security Constraints
420
- const round4 = ASK_USER([
421
- {
422
- id: "performance", type: "multi-select",
423
- prompt: "What performance requirements does your project have?",
424
- options: [
425
- { label: "API response time", description: "API endpoints must respond within 200ms (p95)" },
426
- { label: "Bundle size limit", description: "Frontend bundle size must stay under 500KB gzipped" },
427
- { label: "Lazy loading", description: "Large modules/routes must use lazy loading / code splitting" },
428
- { label: "No N+1 queries", description: "Database access must avoid N+1 query patterns" }
429
- ]
430
- },
431
- {
432
- id: "security", type: "multi-select",
433
- prompt: "What security requirements does your project enforce?",
434
- options: [
435
- { label: "Input sanitization", description: "All user input must be validated and sanitized before use" },
436
- { label: "No secrets in code", description: "No API keys, passwords, or tokens in source code -- use env vars" },
437
- { label: "Auth on all endpoints", description: "All API endpoints require authentication unless explicitly public" },
438
- { label: "Parameterized queries", description: "All database queries must use parameterized/prepared statements" }
439
- ]
440
- }
441
- ]) // BLOCKS (wait for user response)
442
- ```
443
-
444
- **Process Round 4 answers** -> add to `constraints.performance` and `constraints.security`.
445
-
446
- ---
447
-
448
- ##### Round 5: Quality Rules
449
-
450
- ```javascript
451
- // Round 5: Quality Rules
452
- const round5 = ASK_USER([
453
- {
454
- id: "quality", type: "multi-select",
455
- prompt: `Testing with ${testFrameworks.join(', ') || 'your test framework'}. What quality rules apply?`,
456
- options: [
457
- { label: "Min test coverage", description: "Minimum 80% code coverage for new code; no merging below threshold" },
458
- { label: "No skipped tests", description: "Tests must not be skipped (.skip/.only) in committed code" },
459
- { label: "Lint must pass", description: "All code must pass linter checks before commit (enforced by pre-commit)" },
460
- { label: "Type check must pass", description: "Full type checking (tsc --noEmit) must pass with zero errors" }
461
- ]
462
- }
463
- ]) // BLOCKS (wait for user response)
464
- ```
465
-
466
- **Process Round 5 answers** -> add to `quality_rules` array as `{ rule, scope, enforced_by }` objects.
467
-
468
- ### Step 6: Write specs/*.md (if not --skip-specs)
469
-
470
- 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`.
471
-
472
- **Category Assignment**: Based on the round and question type:
473
- - Round 1-2 (conventions): `category: general` (applies to all stages)
474
- - Round 3 (architecture/tech): `category: planning` (planning phase)
475
- - Round 4 (performance/security): `category: execution` (implementation phase)
476
- - Round 5 (quality): `category: execution` (testing phase)
477
-
478
- ```javascript
479
- // Helper: append rules to a spec MD file with category support
480
- // Uses .ccw/specs/ directory (same as frontend/backend spec-index-builder)
481
- function appendRulesToSpecFile(filePath, rules, defaultCategory = 'general') {
482
- if (rules.length === 0) return
483
-
484
- // Ensure .ccw/specs/ directory exists
485
- const specDir = path.dirname(filePath)
486
- if (!fs.existsSync(specDir)) {
487
- fs.mkdirSync(specDir, { recursive: true })
488
- }
489
-
490
- // Check if file exists
491
- if (!file_exists(filePath)) {
492
- // Create file with frontmatter including category
493
- const frontmatter = `---
494
- title: ${filePath.includes('conventions') ? 'Coding Conventions' : filePath.includes('constraints') ? 'Architecture Constraints' : 'Quality Rules'}
495
- readMode: optional
496
- priority: medium
497
- category: ${defaultCategory}
498
- scope: project
499
- dimension: specs
500
- keywords: [${defaultCategory}, ${filePath.includes('conventions') ? 'convention' : filePath.includes('constraints') ? 'constraint' : 'quality'}]
501
- ---
502
-
503
- # ${filePath.includes('conventions') ? 'Coding Conventions' : filePath.includes('constraints') ? 'Architecture Constraints' : 'Quality Rules'}
504
-
505
- `
506
- Write(filePath, frontmatter)
507
- }
508
-
509
- const existing = Read(filePath)
510
- // Append new rules as markdown list items after existing content
511
- const newContent = existing.trimEnd() + '\n' + rules.map(r => `- ${r}`).join('\n') + '\n'
512
- Write(filePath, newContent)
513
- }
514
-
515
- // Write conventions (general category) - use .ccw/specs/ (same as frontend/backend)
516
- appendRulesToSpecFile('.ccw/specs/coding-conventions.md',
517
- [...newCodingStyle, ...newNamingPatterns, ...newFileStructure, ...newDocumentation],
518
- 'general')
519
-
520
- // Write constraints (planning category)
521
- appendRulesToSpecFile('.ccw/specs/architecture-constraints.md',
522
- [...newArchitecture, ...newTechStack, ...newPerformance, ...newSecurity],
523
- 'planning')
524
-
525
- // Write quality rules (execution category)
526
- if (newQualityRules.length > 0) {
527
- const qualityPath = '.ccw/specs/quality-rules.md'
528
- if (!file_exists(qualityPath)) {
529
- Write(qualityPath, `---
530
- title: Quality Rules
531
- readMode: required
532
- priority: high
533
- category: execution
534
- scope: project
535
- dimension: specs
536
- keywords: [execution, quality, testing, coverage, lint]
537
- ---
538
-
539
- # Quality Rules
540
-
541
- `)
542
- }
543
- appendRulesToSpecFile(qualityPath,
544
- newQualityRules.map(q => `${q.rule} (scope: ${q.scope}, enforced by: ${q.enforced_by})`),
545
- 'execution')
546
- }
547
-
548
- // Rebuild spec index after writing
549
- Bash('ccw spec rebuild')
550
- ```
551
-
552
- #### Answer Processing Rules
553
-
554
- When converting user selections to guideline entries:
555
-
556
- 1. **Selected option** -> Use the option's `description` as the guideline string (it's more precise than the label)
557
- 2. **"Other" with custom text** -> Use the user's text directly as the guideline string
558
- 3. **Deduplication** -> Skip entries that already exist in the guidelines (exact string match)
559
- 4. **Quality rules** -> Convert to `{ rule: description, scope: "all", enforced_by: "code-review" }` format
560
-
561
- ### Step 7: Display Summary
562
-
563
- ```javascript
564
- const projectTech = JSON.parse(Read('.workflow/project-tech.json'));
565
-
566
- if (skipSpecs) {
567
- // Minimal summary for --skip-specs mode
568
- console.log(`
569
- Project initialized successfully (tech analysis only)
570
-
571
- ## Project Overview
572
- Name: ${projectTech.project_name}
573
- Description: ${projectTech.overview.description}
574
-
575
- ### Technology Stack
576
- Languages: ${projectTech.overview.technology_stack.languages.map(l => l.name).join(', ')}
577
- Frameworks: ${projectTech.overview.technology_stack.frameworks.join(', ')}
578
-
579
- ### Architecture
580
- Style: ${projectTech.overview.architecture.style}
581
- Components: ${projectTech.overview.key_components.length} core modules
582
-
583
- ---
584
- Files created:
585
- - Tech analysis: .workflow/project-tech.json
586
- - Specs: (skipped via --skip-specs)
587
- ${regenerate ? '- Backup: .workflow/project-tech.json.backup' : ''}
588
-
589
- Next steps:
590
- - Use $spec-setup (without --skip-specs) to configure guidelines
591
- - Use $spec-add to create individual specs
592
- - Use $workflow-plan to start planning
593
- `);
594
- } else {
595
- // Full summary with guidelines stats
596
- const countConventions = newCodingStyle.length + newNamingPatterns.length
597
- + newFileStructure.length + newDocumentation.length
598
- const countConstraints = newArchitecture.length + newTechStack.length
599
- + newPerformance.length + newSecurity.length
600
- const countQuality = newQualityRules.length
601
-
602
- // Get updated spec list
603
- const specsList = Bash('ccw spec list --json 2>/dev/null || echo "{}"')
604
-
605
- console.log(`
606
- Project initialized and guidelines configured
607
-
608
- ## Project Overview
609
- Name: ${projectTech.project_name}
610
- Description: ${projectTech.overview.description}
611
-
612
- ### Technology Stack
613
- Languages: ${projectTech.overview.technology_stack.languages.map(l => l.name).join(', ')}
614
- Frameworks: ${projectTech.overview.technology_stack.frameworks.join(', ')}
615
-
616
- ### Architecture
617
- Style: ${projectTech.overview.architecture.style}
618
- Components: ${projectTech.overview.key_components.length} core modules
619
-
620
- ### Guidelines Summary
621
- - Conventions: ${countConventions} rules added to coding-conventions.md
622
- - Constraints: ${countConstraints} rules added to architecture-constraints.md
623
- - Quality rules: ${countQuality} rules added to quality-rules.md
624
-
625
- Spec index rebuilt. Use \`ccw spec list\` to view all specs.
626
-
627
- ---
628
- Files created:
629
- - Tech analysis: .workflow/project-tech.json
630
- - Specs: .ccw/specs/ (configured)
631
- ${regenerate ? '- Backup: .workflow/project-tech.json.backup' : ''}
632
-
633
- Next steps:
634
- - Use $spec-add to add individual rules later
635
- - Specs are auto-loaded via hook on each prompt
636
- - Use $workflow-plan to start planning
637
- `);
638
- }
639
- ```
640
-
641
- ## Error Handling
642
-
643
- | Situation | Action |
644
- |-----------|--------|
645
- | **Agent Failure** | Fall back to basic initialization with placeholder overview |
646
- | **Missing Tools** | Agent uses Qwen fallback or bash-only |
647
- | **Empty Project** | Create minimal JSON with all gaps identified |
648
- | **No project-tech.json** (when --reset without prior init) | Run full flow from Step 2 |
649
- | **User cancels mid-wizard** | Save whatever was collected so far (partial is better than nothing) |
650
- | **File write failure** | Report error, suggest manual edit |
651
-
652
- ## Related Commands
653
-
654
- - `$spec-add` - Interactive wizard to create individual specs with scope selection
655
- - `$session-sync` - Quick-sync session work to specs and project-tech
656
- - `$workflow-plan` - Start planning with initialized project context
657
- - `$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 using cli-explore-agent
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
+ message: `
126
+ ## TASK ASSIGNMENT
127
+
128
+ ### MANDATORY FIRST STEPS (Agent Execute)
129
+ 1. **Read role definition**: ~/.codex/agents/cli-explore-agent.md (MUST read first)
130
+ 2. 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