cc-devflow 2.4.6 → 4.1.0

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 (191) hide show
  1. package/.claude/CLAUDE.md +1065 -48
  2. package/.claude/agents/dev-implementer.md +195 -0
  3. package/.claude/commands/{flow-archive.md → flow/archive.md} +46 -11
  4. package/.claude/commands/flow/context.md +150 -0
  5. package/.claude/commands/flow/delta.md +245 -0
  6. package/.claude/commands/{flow-dev.md → flow/dev.md} +112 -11
  7. package/.claude/commands/flow/init.md +45 -0
  8. package/.claude/commands/flow/quality.md +159 -0
  9. package/.claude/commands/flow/spec.md +186 -0
  10. package/.claude/commands/flow/workspace.md +146 -0
  11. package/.claude/commands/{cancel-ralph.md → util/cancel-ralph.md} +1 -0
  12. package/.claude/config/quality-gates.yml +305 -0
  13. package/.claude/docs/guides/TEAM_MODE_GUIDE.md +313 -0
  14. package/.claude/docs/templates/DELTA_SPEC_TEMPLATE.md +91 -0
  15. package/.claude/docs/templates/DESIGN_DECISIONS_TEMPLATE.md +151 -0
  16. package/.claude/docs/templates/JOURNAL_TEMPLATE.md +75 -0
  17. package/.claude/docs/templates/_shared/CLAUDE.md +36 -0
  18. package/.claude/docs/templates/_shared/CONSTITUTION_CHECK.md +125 -0
  19. package/.claude/docs/templates/_shared/VALIDATION_CHECKLIST.md +187 -0
  20. package/.claude/docs/templates/_shared/YAML_FRONTMATTER.md +164 -0
  21. package/.claude/docs/templates/context/dev.jsonl.template +6 -0
  22. package/.claude/docs/templates/context/epic.jsonl.template +5 -0
  23. package/.claude/docs/templates/context/prd.jsonl.template +4 -0
  24. package/.claude/docs/templates/context/research.jsonl.template +4 -0
  25. package/.claude/docs/templates/context/review.jsonl.template +5 -0
  26. package/.claude/docs/templates/context/tech.jsonl.template +5 -0
  27. package/.claude/hooks/CLAUDE.md +342 -0
  28. package/.claude/hooks/inject-agent-context.ts +480 -0
  29. package/.claude/hooks/inject-skill-context.ts +359 -0
  30. package/.claude/hooks/ralph-loop.ts +931 -0
  31. package/.claude/hooks/task-completed-hook.ts +593 -0
  32. package/.claude/hooks/teammate-idle-hook.ts +690 -0
  33. package/.claude/hooks/types/team-types.d.ts +238 -0
  34. package/.claude/rules/devflow-conventions.md +82 -9
  35. package/.claude/scripts/archive-requirement.sh +44 -1
  36. package/.claude/scripts/common.sh +670 -3
  37. package/.claude/scripts/delta-parser.ts +527 -0
  38. package/.claude/scripts/detect-file-conflicts.sh +151 -0
  39. package/.claude/scripts/flow-context-add.sh +134 -0
  40. package/.claude/scripts/flow-context-init.sh +133 -0
  41. package/.claude/scripts/flow-context-validate.sh +144 -0
  42. package/.claude/scripts/flow-delta-apply.sh +297 -0
  43. package/.claude/scripts/flow-delta-archive.sh +71 -0
  44. package/.claude/scripts/flow-delta-create.sh +202 -0
  45. package/.claude/scripts/flow-delta-list.sh +142 -0
  46. package/.claude/scripts/flow-delta-status.sh +235 -0
  47. package/.claude/scripts/flow-quality-full.sh +184 -0
  48. package/.claude/scripts/flow-quality-quick.sh +64 -0
  49. package/.claude/scripts/flow-workspace-init.sh +117 -0
  50. package/.claude/scripts/flow-workspace-record.sh +164 -0
  51. package/.claude/scripts/flow-workspace-start.sh +88 -0
  52. package/.claude/scripts/get-workflow-status.sh +415 -0
  53. package/.claude/scripts/parse-task-dependencies.js +334 -0
  54. package/.claude/scripts/record-quality-error.sh +165 -0
  55. package/.claude/scripts/run-quality-gates.sh +242 -0
  56. package/.claude/scripts/team-dev-init.sh +319 -0
  57. package/.claude/scripts/team-state-recovery.sh +229 -0
  58. package/.claude/scripts/workflow-status.ts +433 -0
  59. package/.claude/settings.json +19 -0
  60. package/.claude/skills/cc-devflow-orchestrator/SKILL.md +85 -200
  61. package/.claude/skills/domain/using-git-worktrees/SKILL.md +252 -0
  62. package/.claude/skills/domain/using-git-worktrees/assets/SHELL_ALIASES.md +133 -0
  63. package/.claude/skills/domain/using-git-worktrees/context.jsonl +4 -0
  64. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh +218 -0
  65. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh +232 -0
  66. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-list.sh +130 -0
  67. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-status.sh +140 -0
  68. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-switch.sh +70 -0
  69. package/.claude/skills/skill-rules.json +72 -1
  70. package/.claude/skills/utility/journey-checker/SKILL.md +199 -0
  71. package/.claude/skills/utility/journey-checker/pressure-scenarios.md +164 -0
  72. package/.claude/skills/utility/skill-creator/LICENSE.txt +202 -0
  73. package/.claude/skills/utility/skill-creator/SKILL.md +356 -0
  74. package/.claude/skills/utility/skill-creator/references/output-patterns.md +82 -0
  75. package/.claude/skills/utility/skill-creator/references/workflows.md +28 -0
  76. package/.claude/skills/utility/skill-creator/scripts/init_skill.py +303 -0
  77. package/.claude/skills/utility/skill-creator/scripts/package_skill.py +110 -0
  78. package/.claude/skills/utility/skill-creator/scripts/quick_validate.py +95 -0
  79. package/.claude/skills/workflow/flow-dev/CLAUDE.md +78 -0
  80. package/.claude/skills/workflow/flow-dev/SKILL.md +96 -0
  81. package/.claude/skills/workflow/flow-dev/assets/IMPLEMENTATION_PLAN_TEMPLATE.md +71 -0
  82. package/.claude/skills/workflow/flow-dev/context.jsonl +8 -0
  83. package/.claude/skills/workflow/flow-dev/dev-implementer.jsonl +8 -0
  84. package/.claude/skills/workflow/flow-dev/scripts/entry-gate.sh +116 -0
  85. package/.claude/skills/workflow/flow-dev/scripts/exit-gate.sh +101 -0
  86. package/.claude/skills/workflow/flow-dev/scripts/task-orchestrator.sh +106 -0
  87. package/.claude/skills/workflow/flow-fix/SKILL.md +105 -0
  88. package/.claude/skills/workflow/flow-fix/context.jsonl +6 -0
  89. package/.claude/skills/workflow/flow-fix/references/bug-analyzer.md +381 -0
  90. package/.claude/skills/workflow/flow-init/SKILL.md +211 -0
  91. package/.claude/skills/workflow/flow-init/assets/BRAINSTORM_TEMPLATE.md +148 -0
  92. package/.claude/skills/workflow/flow-init/assets/INIT_FLOW_TEMPLATE.md +198 -0
  93. package/.claude/skills/workflow/flow-init/assets/RESEARCH_TEMPLATE.md +276 -0
  94. package/.claude/skills/workflow/flow-init/context.jsonl +5 -0
  95. package/.claude/skills/workflow/flow-init/references/flow-researcher.md +132 -0
  96. package/.claude/skills/workflow/flow-init/scripts/check-prerequisites.sh +232 -0
  97. package/.claude/skills/workflow/flow-init/scripts/consolidate-research.sh +182 -0
  98. package/.claude/skills/workflow/flow-init/scripts/create-requirement.sh +515 -0
  99. package/.claude/skills/workflow/flow-init/scripts/generate-research-tasks.sh +157 -0
  100. package/.claude/skills/workflow/flow-init/scripts/populate-research-tasks.sh +284 -0
  101. package/.claude/skills/workflow/flow-init/scripts/validate-research.sh +332 -0
  102. package/.claude/skills/workflow/flow-quality/SKILL.md +94 -0
  103. package/.claude/skills/workflow/flow-quality/context.jsonl +6 -0
  104. package/.claude/skills/workflow/flow-quality/references/code-quality-reviewer.md +205 -0
  105. package/.claude/skills/workflow/flow-quality/references/qa-tester.md +313 -0
  106. package/.claude/skills/workflow/flow-quality/references/security-reviewer.md +314 -0
  107. package/.claude/skills/workflow/flow-quality/references/spec-reviewer.md +221 -0
  108. package/.claude/skills/workflow/flow-release/SKILL.md +126 -0
  109. package/.claude/skills/workflow/flow-release/context.jsonl +7 -0
  110. package/.claude/skills/workflow/flow-release/references/release-manager.md +295 -0
  111. package/.claude/skills/workflow/flow-spec/CLAUDE.md +103 -0
  112. package/.claude/skills/workflow/flow-spec/SKILL.md +545 -0
  113. package/.claude/skills/workflow/flow-spec/context.jsonl +7 -0
  114. package/.claude/skills/workflow/flow-spec/scripts/entry-gate.sh +194 -0
  115. package/.claude/skills/workflow/flow-spec/scripts/exit-gate.sh +244 -0
  116. package/.claude/skills/workflow/flow-spec/scripts/parallel-orchestrator.sh +205 -0
  117. package/.claude/skills/workflow/flow-spec/scripts/team-communication.sh +353 -0
  118. package/.claude/skills/workflow/flow-spec/scripts/team-init.sh +195 -0
  119. package/.claude/skills/workflow/flow-spec/scripts/test-team-mode.sh +496 -0
  120. package/.claude/skills/workflow/flow-spec/team-config.json +165 -0
  121. package/.claude/skills/workflow.yaml +417 -0
  122. package/CHANGELOG.md +254 -0
  123. package/README.md +193 -33
  124. package/README.zh-CN.md +206 -46
  125. package/lib/compiler/CLAUDE.md +77 -46
  126. package/lib/compiler/__tests__/multi-module-emitters.test.js +508 -0
  127. package/lib/compiler/context-expander.js +179 -0
  128. package/lib/compiler/emitters/antigravity-emitter.js +195 -5
  129. package/lib/compiler/emitters/base-emitter.js +217 -2
  130. package/lib/compiler/emitters/codex-emitter.js +200 -4
  131. package/lib/compiler/emitters/cursor-emitter.js +307 -3
  132. package/lib/compiler/emitters/qwen-emitter.js +196 -4
  133. package/lib/compiler/index.js +197 -2
  134. package/lib/compiler/platforms.js +270 -21
  135. package/package.json +1 -1
  136. package/.claude/commands/flow-epic.md +0 -183
  137. package/.claude/commands/flow-init.md +0 -370
  138. package/.claude/commands/flow-prd.md +0 -144
  139. package/.claude/commands/flow-qa.md +0 -93
  140. package/.claude/commands/flow-review.md +0 -257
  141. package/.claude/commands/flow-tech.md +0 -142
  142. package/.claude/commands/flow-ui.md +0 -189
  143. package/.claude/skills/file-header-guardian/SKILL.md +0 -56
  144. package/.claude/skills/skill-developer/ADVANCED.md +0 -197
  145. package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +0 -306
  146. package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +0 -152
  147. package/.claude/skills/skill-developer/SKILL.md +0 -426
  148. package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +0 -315
  149. package/.claude/skills/skill-developer/TRIGGER_TYPES.md +0 -305
  150. package/.claude/skills/skill-developer/TROUBLESHOOTING.md +0 -514
  151. package/.claude/skills/writing-skills/SKILL.md +0 -655
  152. package/.claude/skills/writing-skills/anthropic-best-practices.md +0 -1150
  153. package/.claude/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
  154. package/.claude/skills/writing-skills/graphviz-conventions.dot +0 -172
  155. package/.claude/skills/writing-skills/persuasion-principles.md +0 -187
  156. package/.claude/skills/writing-skills/render-graphs.js +0 -168
  157. package/.claude/skills/writing-skills/testing-skills-with-subagents.md +0 -384
  158. package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/affected-repos.txt +0 -1
  159. package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/affected-repos.txt +0 -1
  160. /package/.claude/commands/{core-architecture.md → core/architecture.md} +0 -0
  161. /package/.claude/commands/{core-guidelines.md → core/guidelines.md} +0 -0
  162. /package/.claude/commands/{core-roadmap.md → core/roadmap.md} +0 -0
  163. /package/.claude/commands/{core-style.md → core/style.md} +0 -0
  164. /package/.claude/commands/{flow-checklist.md → flow/checklist.md} +0 -0
  165. /package/.claude/commands/{flow-clarify.md → flow/clarify.md} +0 -0
  166. /package/.claude/commands/{flow-constitution.md → flow/constitution.md} +0 -0
  167. /package/.claude/commands/{flow-fix.md → flow/fix.md} +0 -0
  168. /package/.claude/commands/{flow-ideate.md → flow/ideate.md} +0 -0
  169. /package/.claude/commands/{flow-new.md → flow/new.md} +0 -0
  170. /package/.claude/commands/{flow-release.md → flow/release.md} +0 -0
  171. /package/.claude/commands/{flow-restart.md → flow/restart.md} +0 -0
  172. /package/.claude/commands/{flow-status.md → flow/status.md} +0 -0
  173. /package/.claude/commands/{flow-update.md → flow/update.md} +0 -0
  174. /package/.claude/commands/{flow-upgrade.md → flow/upgrade.md} +0 -0
  175. /package/.claude/commands/{flow-verify.md → flow/verify.md} +0 -0
  176. /package/.claude/commands/{code-review-high.md → util/code-review.md} +0 -0
  177. /package/.claude/commands/{git-commit.md → util/git-commit.md} +0 -0
  178. /package/.claude/commands/{problem-analyzer.md → util/problem-analyzer.md} +0 -0
  179. /package/.claude/skills/{flow-attention-refresh → domain/attention-refresh}/SKILL.md +0 -0
  180. /package/.claude/skills/{flow-brainstorming → domain/brainstorming}/SKILL.md +0 -0
  181. /package/.claude/skills/{flow-debugging → domain/debugging}/SKILL.md +0 -0
  182. /package/.claude/skills/{flow-finishing-branch → domain/finishing-branch}/SKILL.md +0 -0
  183. /package/.claude/skills/{flow-receiving-review → domain/receiving-review}/SKILL.md +0 -0
  184. /package/.claude/skills/{flow-tdd → domain/tdd}/SKILL.md +0 -0
  185. /package/.claude/skills/{verification-before-completion → domain/verification}/SKILL.md +0 -0
  186. /package/.claude/skills/{constitution-guardian → guardrail/constitution-guardian}/SKILL.md +0 -0
  187. /package/.claude/skills/{devflow-tdd-enforcer → guardrail/tdd-enforcer}/SKILL.md +0 -0
  188. /package/.claude/skills/{devflow-constitution-quick-ref → utility/constitution-quick-ref}/SKILL.md +0 -0
  189. /package/.claude/skills/{devflow-file-standards → utility/file-standards}/SKILL.md +0 -0
  190. /package/.claude/skills/{fractal-docs-generator → utility/fractal-docs}/SKILL.md +0 -0
  191. /package/.claude/skills/{npm-release → utility/npm-release}/SKILL.md +0 -0
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: flow-researcher
3
+ description: Executes mandatory /flow-init deep research using MCP services (Context7/WebSearch/WebFetch) with file-based memory. Produces research artifacts under devflow/requirements/$REQ_ID/research/ and returns only a short summary + file paths (no long pastes).
4
+ tools: Read, Write, Grep, Glob, WebFetch, WebSearch, mcp__context7__resolve-library-id, mcp__context7__get-library-docs
5
+ model: inherit
6
+ ---
7
+
8
+ You are a requirement research runner invoked by `/flow-init`.
9
+
10
+ Your job is to do **research work** without exhausting the main session context:
11
+ - Put large content into files under `devflow/requirements/$REQ_ID/research/`
12
+ - Return only a **short** summary + **paths**, never paste long docs into chat
13
+
14
+ ## MCP Research Requirement
15
+
16
+ This agent MUST use **MCP services** to fetch external materials for deep research:
17
+ - **Context7 MCP**: official documentation for detected frameworks/libraries (`mcp__context7__resolve-library-id` + `mcp__context7__get-library-docs`)
18
+ - **WebSearch + WebFetch**: tutorials, guides, examples, case studies, and plan URLs
19
+
20
+ All fetched content MUST be written to `research/mcp/YYYYMMDD/**` (not pasted into chat).
21
+
22
+ ## Hard Rules
23
+
24
+ 1. **NO USER INTERACTION**
25
+ - Never ask the user questions.
26
+ - If information is missing, record it under `## Unresolved Questions` in `research/research-summary.md`.
27
+
28
+ 2. **FILE-BASED MEMORY (MANDATORY)**
29
+ - Any fetched/long content must be written to files in `research/`.
30
+ - Chat output must stay small (decision bullets + file paths).
31
+
32
+ 3. **NO PLACEHOLDERS**
33
+ - Do not leave `TODO`, `FIXME`, `{{PLACEHOLDER}}`.
34
+ - Ensure `validate-research.sh --strict` passes.
35
+
36
+ 4. **TRACEABILITY**
37
+ - Every decision must include a concrete `Source` (file path + section/line if possible).
38
+
39
+ ## Input Contract (provided via prompt)
40
+
41
+ You will receive a JSON payload in the prompt:
42
+
43
+ ```json
44
+ {
45
+ "reqId": "REQ-123",
46
+ "reqDir": "devflow/requirements/REQ-123",
47
+ "title": "User Authentication",
48
+ "planUrls": ["https://..."],
49
+ "contextFiles": {
50
+ "brainstorm": "devflow/requirements/REQ-123/BRAINSTORM.md",
51
+ "roadmap": "devflow/ROADMAP.md",
52
+ "architecture": "devflow/ARCHITECTURE.md"
53
+ }
54
+ }
55
+ ```
56
+
57
+ ## Required Outputs (MUST create/update)
58
+
59
+ Under `${reqDir}/research/`:
60
+ - `internal/codebase-overview.md`
61
+ - `mcp/YYYYMMDD/official/*.md` (if applicable)
62
+ - `mcp/YYYYMMDD/guides/*.md` (if applicable)
63
+ - `mcp/YYYYMMDD/tutorials/*.md` (if applicable)
64
+ - `mcp/YYYYMMDD/examples/*.md` (if applicable)
65
+ - `research-summary.md` (human-readable decisions)
66
+ - `tasks.json` (decision/rationale/alternatives filled)
67
+ - `research.md` (consolidated, Decision/Rationale/Alternatives format)
68
+
69
+ ## Execution Procedure (follow in order)
70
+
71
+ ### Step 1: Validate Paths & Prepare Directories
72
+ - Ensure `${reqDir}` exists.
73
+ - Ensure `${reqDir}/research/` exists, create missing subfolders:
74
+ - `research/internal/`
75
+ - `research/mcp/YYYYMMDD/{official,guides,tutorials,examples}/`
76
+ - Read `${reqDir}/BRAINSTORM.md` and `${reqDir}/README.md` if present.
77
+
78
+ ### Step 2: Internal Codebase Research (S0)
79
+ Goal: produce a **useful** `research/internal/codebase-overview.md` with:
80
+ - Repo tech stack snapshot (from `package.json`, lockfiles, etc.)
81
+ - Relevant modules/entry points you will likely touch
82
+ - Existing patterns for auth/data validation/error handling/tests
83
+ - Constraints you must not violate (existing conventions, CI, tooling)
84
+
85
+ ### Step 3: External Research (Task 1-5)
86
+ Do not paste docs into chat; store them as files.
87
+
88
+ 1) **Official docs (Context7 MCP)** for the detected key libraries/frameworks
89
+ 2) **Tutorials/guides (WebSearch + WebFetch)** for practical patterns
90
+ 3) **Examples/case studies (WebSearch + WebFetch)** similar to this requirement
91
+ 4) Write short per-source notes at top of each saved file:
92
+ - What it answers
93
+ - What it recommends
94
+ - Any caveats
95
+
96
+ If planUrls exist:
97
+ - Fetch each URL and store content under `research/mcp/YYYYMMDD/guides/plan-*.md` (or `tutorials/` if more appropriate).
98
+
99
+ ### Step 4: Write `research/research-summary.md`
100
+ Use `.claude/docs/templates/RESEARCH_TEMPLATE.md` as the format baseline.
101
+ - Create **at least 3** Decision blocks `### R001`, `### R002`, `### R003`.
102
+ - Each decision must cite sources under `research/` (internal or external).
103
+ - Add unresolved questions only when genuinely blocked.
104
+
105
+ ### Step 5: Generate & Fill `tasks.json`
106
+ - Run:
107
+ - `bash .claude/scripts/generate-research-tasks.sh "${reqDir}"`
108
+ - Ensure `tasks.json` contains at least **1** task.
109
+ - If the generator produced 0 tasks, append baseline tasks matching your decision blocks (`R001..R003`).
110
+ - Fill each task's `decision`, `rationale`, `alternatives` based on `research-summary.md`.
111
+ - Prefer using `bash .claude/scripts/populate-research-tasks.sh "${reqDir}"` if it matches the ID format.
112
+
113
+ ### Step 6: Consolidate & Validate
114
+ - Run:
115
+ - `bash .claude/scripts/consolidate-research.sh "${reqDir}"`
116
+ - `bash .claude/scripts/validate-research.sh "${reqDir}" --strict`
117
+ - If validation fails:
118
+ - Fix the files (do not weaken validation).
119
+ - Re-run validation until it passes.
120
+
121
+ ## Return Format (chat output)
122
+
123
+ Return ONLY:
124
+ - 3–6 bullet decisions (R001..), one line each
125
+ - Paths created/updated
126
+ - Any unresolved questions (≤5)
127
+
128
+ Never paste long fetched content.
129
+
130
+ ---
131
+
132
+ **[PROTOCOL]**: 变更时更新此头部,然后检查 CLAUDE.md
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Consolidated prerequisite checking script for cc-devflow
4
+ #
5
+ # This script provides unified prerequisite checking for development workflow.
6
+ # Based on spec-kit design principles with cc-devflow enhancements.
7
+ #
8
+ # Usage: ./check-prerequisites.sh [OPTIONS]
9
+ #
10
+ # OPTIONS:
11
+ # --json Output in JSON format
12
+ # --require-epic Require EPIC.md to exist (for task generation phase)
13
+ # --require-tasks Require tasks/ to exist (for implementation phase)
14
+ # --include-tasks Include tasks/ in AVAILABLE_DOCS list
15
+ # --paths-only Only output path variables (no validation)
16
+ # --help, -h Show help message
17
+ #
18
+ # OUTPUTS:
19
+ # JSON mode: {"REQ_ID":"...", "REQ_DIR":"...", "AVAILABLE_DOCS":["..."]}
20
+ # Text mode: REQ_ID:... \n REQ_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md
21
+ # Paths only: REPO_ROOT: ... \n REQ_ID: ... \n REQ_DIR: ... etc.
22
+
23
+ set -e
24
+
25
+ # Parse command line arguments
26
+ JSON_MODE=false
27
+ REQUIRE_EPIC=false
28
+ REQUIRE_TASKS=false
29
+ INCLUDE_TASKS=false
30
+ PATHS_ONLY=false
31
+
32
+ for arg in "$@"; do
33
+ case "$arg" in
34
+ --json)
35
+ JSON_MODE=true
36
+ ;;
37
+ --require-epic)
38
+ REQUIRE_EPIC=true
39
+ ;;
40
+ --require-tasks)
41
+ REQUIRE_TASKS=true
42
+ ;;
43
+ --include-tasks)
44
+ INCLUDE_TASKS=true
45
+ ;;
46
+ --paths-only)
47
+ PATHS_ONLY=true
48
+ ;;
49
+ --help|-h)
50
+ cat << 'EOF'
51
+ Usage: check-prerequisites.sh [OPTIONS]
52
+
53
+ Consolidated prerequisite checking for cc-devflow workflow.
54
+
55
+ OPTIONS:
56
+ --json Output in JSON format
57
+ --require-epic Require EPIC.md to exist (for task generation phase)
58
+ --require-tasks Require tasks/ to exist (for implementation phase)
59
+ --include-tasks Include tasks/ in AVAILABLE_DOCS list
60
+ --paths-only Only output path variables (no prerequisite validation)
61
+ --help, -h Show this help message
62
+
63
+ EXAMPLES:
64
+ # Check planning prerequisites (PRD.md required)
65
+ ./check-prerequisites.sh --json
66
+
67
+ # Check task generation prerequisites (PRD.md + EPIC.md required)
68
+ ./check-prerequisites.sh --json --require-epic
69
+
70
+ # Check implementation prerequisites (PRD.md + EPIC.md + tasks/ required)
71
+ ./check-prerequisites.sh --json --require-epic --require-tasks --include-tasks
72
+
73
+ # Get requirement paths only (no validation)
74
+ ./check-prerequisites.sh --paths-only
75
+
76
+ EOF
77
+ exit 0
78
+ ;;
79
+ *)
80
+ echo "ERROR: Unknown option '$arg'. Use --help for usage information." >&2
81
+ exit 1
82
+ ;;
83
+ esac
84
+ done
85
+
86
+ # Source common functions
87
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
88
+ source "$SCRIPT_DIR/common.sh"
89
+
90
+ # Get requirement paths
91
+ eval $(get_requirement_paths)
92
+
93
+ # Validate requirement ID exists
94
+ if [[ -z "$REQ_ID" ]]; then
95
+ echo "ERROR: No requirement ID found" >&2
96
+ echo "Please ensure you are on a feature branch (feature/REQ-XXX-title)" >&2
97
+ echo "Or set DEVFLOW_REQ_ID environment variable" >&2
98
+ exit 1
99
+ fi
100
+
101
+ # Validate requirement ID format
102
+ validate_req_id "$REQ_ID" || exit 1
103
+
104
+ # If paths-only mode, output paths and exit (support JSON + paths-only combined)
105
+ if $PATHS_ONLY; then
106
+ if $JSON_MODE; then
107
+ # Minimal JSON paths payload (no validation performed)
108
+ printf '{"%s":"%s","%s":"%s","%s":"%s","%s":"%s","%s":"%s","%s":"%s"}\n' \
109
+ "REPO_ROOT" "$REPO_ROOT" \
110
+ "REQ_ID" "$REQ_ID" \
111
+ "REQ_TYPE" "$REQ_TYPE" \
112
+ "REQ_DIR" "$REQ_DIR" \
113
+ "PRD_FILE" "$PRD_FILE" \
114
+ "EPIC_FILE" "$EPIC_FILE"
115
+ else
116
+ echo "REPO_ROOT: $REPO_ROOT"
117
+ echo "REQ_ID: $REQ_ID"
118
+ echo "REQ_TYPE: $REQ_TYPE"
119
+ echo "REQ_DIR: $REQ_DIR"
120
+ echo "PRD_FILE: $PRD_FILE"
121
+ echo "EPIC_FILE: $EPIC_FILE"
122
+ fi
123
+ exit 0
124
+ fi
125
+
126
+ # Validate required directories and files
127
+ if [[ ! -d "$REQ_DIR" ]]; then
128
+ echo "ERROR: Requirement directory not found: $REQ_DIR" >&2
129
+ echo "Run /flow-new first to create the requirement structure." >&2
130
+ exit 1
131
+ fi
132
+
133
+ if [[ ! -f "$PRD_FILE" ]]; then
134
+ echo "ERROR: PRD.md not found in $REQ_DIR" >&2
135
+ echo "Run prd-writer agent first to create the PRD." >&2
136
+ exit 1
137
+ fi
138
+
139
+ # Check for EPIC.md if required
140
+ if $REQUIRE_EPIC && [[ ! -f "$EPIC_FILE" ]]; then
141
+ echo "ERROR: EPIC.md not found in $REQ_DIR" >&2
142
+ echo "Run planner agent first to create the Epic." >&2
143
+ exit 1
144
+ fi
145
+
146
+ # Check for tasks/ or TASKS.md if required
147
+ # Support both tasks/ directory (old format) and TASKS.md file (new format)
148
+ if $REQUIRE_TASKS; then
149
+ TASKS_FILE="$REQ_DIR/TASKS.md"
150
+ if [[ ! -d "$TASKS_DIR" || -z "$(ls -A "$TASKS_DIR" 2>/dev/null)" ]] && [[ ! -f "$TASKS_FILE" ]]; then
151
+ echo "ERROR: Neither tasks/ directory nor TASKS.md file found in $REQ_DIR" >&2
152
+ echo "Run planner agent first to create the task breakdown." >&2
153
+ exit 1
154
+ fi
155
+ fi
156
+
157
+ # Build list of available documents
158
+ docs=()
159
+
160
+ # Check optional docs
161
+ [[ -d "$RESEARCH_DIR" && -n "$(ls -A "$RESEARCH_DIR" 2>/dev/null)" ]] && docs+=("research/")
162
+ [[ -f "$TEST_PLAN_FILE" ]] && docs+=("TEST_PLAN.md")
163
+ [[ -f "$SECURITY_PLAN_FILE" ]] && docs+=("SECURITY_PLAN.md")
164
+ [[ -f "$TEST_REPORT_FILE" ]] && docs+=("TEST_REPORT.md")
165
+ [[ -f "$SECURITY_REPORT_FILE" ]] && docs+=("SECURITY_REPORT.md")
166
+ [[ -f "$RELEASE_PLAN_FILE" ]] && docs+=("RELEASE_PLAN.md")
167
+ [[ -f "$LOG_FILE" ]] && docs+=("EXECUTION_LOG.md")
168
+
169
+ # Include tasks/ or TASKS.md if requested and it exists
170
+ # Support both tasks/ directory (old format) and TASKS.md file (new format)
171
+ if $INCLUDE_TASKS; then
172
+ TASKS_FILE="$REQ_DIR/TASKS.md"
173
+ if [[ -d "$TASKS_DIR" && -n "$(ls -A "$TASKS_DIR" 2>/dev/null)" ]]; then
174
+ docs+=("tasks/")
175
+ elif [[ -f "$TASKS_FILE" ]]; then
176
+ docs+=("TASKS.md")
177
+ fi
178
+ fi
179
+
180
+ # For BUG type, check BUG-specific files
181
+ if [[ "$REQ_TYPE" == "bug" ]]; then
182
+ [[ -f "$ANALYSIS_FILE" ]] && docs+=("ANALYSIS.md")
183
+ [[ -f "$PLAN_FILE" ]] && docs+=("PLAN.md")
184
+ fi
185
+
186
+ # Output results
187
+ if $JSON_MODE; then
188
+ # Build JSON array of documents
189
+ if [[ ${#docs[@]} -eq 0 ]]; then
190
+ json_docs="[]"
191
+ else
192
+ json_docs=$(printf '"%s",' "${docs[@]}")
193
+ json_docs="[${json_docs%,}]"
194
+ fi
195
+
196
+ printf '{"%s":"%s","%s":"%s","%s":"%s","%s":%s}\n' \
197
+ "REQ_ID" "$REQ_ID" \
198
+ "REQ_TYPE" "$REQ_TYPE" \
199
+ "REQ_DIR" "$REQ_DIR" \
200
+ "AVAILABLE_DOCS" "$json_docs"
201
+ else
202
+ # Text output
203
+ echo "REQ_ID: $REQ_ID"
204
+ echo "REQ_TYPE: $REQ_TYPE"
205
+ echo "REQ_DIR: $REQ_DIR"
206
+ echo "AVAILABLE_DOCS:"
207
+
208
+ # Show status of each potential document
209
+ check_dir "$RESEARCH_DIR" "research/"
210
+ check_file "$TEST_PLAN_FILE" "TEST_PLAN.md"
211
+ check_file "$SECURITY_PLAN_FILE" "SECURITY_PLAN.md"
212
+ check_file "$TEST_REPORT_FILE" "TEST_REPORT.md"
213
+ check_file "$SECURITY_REPORT_FILE" "SECURITY_REPORT.md"
214
+ check_file "$RELEASE_PLAN_FILE" "RELEASE_PLAN.md"
215
+ check_file "$LOG_FILE" "EXECUTION_LOG.md"
216
+
217
+ if $INCLUDE_TASKS; then
218
+ TASKS_FILE="$REQ_DIR/TASKS.md"
219
+ # Check for tasks/ directory first, fallback to TASKS.md
220
+ if [[ -d "$TASKS_DIR" && -n "$(ls -A "$TASKS_DIR" 2>/dev/null)" ]]; then
221
+ check_dir "$TASKS_DIR" "tasks/"
222
+ else
223
+ check_file "$TASKS_FILE" "TASKS.md"
224
+ fi
225
+ fi
226
+
227
+ # BUG-specific files
228
+ if [[ "$REQ_TYPE" == "bug" ]]; then
229
+ check_file "$ANALYSIS_FILE" "ANALYSIS.md"
230
+ check_file "$PLAN_FILE" "PLAN.md"
231
+ fi
232
+ fi
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env bash
2
+ # shellcheck disable=SC2312
3
+
4
+ set -euo pipefail
5
+
6
+ usage() {
7
+ cat <<'USAGE'
8
+ Usage: scripts/bash/consolidate-research.sh <requirement-dir>
9
+
10
+ Aggregates research findings into research/research.md using the standard
11
+ Decision/Rationale/Alternatives format. Existing files are overwritten.
12
+ USAGE
13
+ }
14
+
15
+ if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
16
+ usage
17
+ exit 0
18
+ fi
19
+
20
+ if [[ $# -lt 1 ]]; then
21
+ echo "Error: requirement directory is required." >&2
22
+ usage
23
+ exit 1
24
+ fi
25
+
26
+ REQ_DIR="$1"
27
+ if [[ ! -d "$REQ_DIR" ]]; then
28
+ echo "Error: requirement directory '$REQ_DIR' does not exist." >&2
29
+ exit 1
30
+ fi
31
+
32
+ python3 - "$REQ_DIR" <<'PY'
33
+ from __future__ import annotations
34
+
35
+ import json
36
+ import os
37
+ import sys
38
+ from datetime import datetime, timezone
39
+ from pathlib import Path
40
+
41
+ req_dir = Path(sys.argv[1]).resolve()
42
+ research_dir = req_dir / "research"
43
+ research_dir.mkdir(exist_ok=True, parents=True)
44
+ summary_path = research_dir / "research.md"
45
+ tasks_path = research_dir / "tasks.json"
46
+
47
+ def detect_feature_title() -> str:
48
+ readme = req_dir / "README.md"
49
+ if readme.exists():
50
+ for line in readme.read_text(encoding="utf-8").splitlines():
51
+ line = line.strip("# ").strip()
52
+ if line:
53
+ return line
54
+ return req_dir.name
55
+
56
+ def validate_task_completeness(tasks: list) -> tuple[int, int, list]:
57
+ """Validate tasks have decision/rationale/alternatives fields.
58
+
59
+ Returns:
60
+ (total_tasks, completed_tasks, incomplete_task_ids)
61
+ """
62
+ total = len(tasks)
63
+ completed = 0
64
+ incomplete = []
65
+
66
+ for task in tasks:
67
+ task_id = task.get("id", "???")
68
+ decision = task.get("decision", "")
69
+ rationale = task.get("rationale", "")
70
+ alternatives = task.get("alternatives", "")
71
+
72
+ # 字段完整的条件:非空 + 不是 TODO 占位符
73
+ has_decision = bool(decision and decision.strip() and decision != "TODO - fill decision outcome")
74
+ has_rationale = bool(rationale and rationale.strip() and rationale != "TODO - explain why this decision was chosen")
75
+ has_alternatives = bool(alternatives and alternatives.strip() and alternatives != "TODO - list evaluated alternatives")
76
+
77
+ if has_decision and has_rationale and has_alternatives:
78
+ completed += 1
79
+ else:
80
+ incomplete.append(task_id)
81
+
82
+ return total, completed, incomplete
83
+
84
+ feature_title = detect_feature_title()
85
+ generated_at = datetime.now(timezone.utc).isoformat()
86
+
87
+ tasks_data = {}
88
+ if tasks_path.exists():
89
+ try:
90
+ tasks_data = json.loads(tasks_path.read_text(encoding="utf-8"))
91
+ except json.JSONDecodeError:
92
+ print(f"ERROR: {tasks_path} is not valid JSON", file=sys.stderr)
93
+ sys.exit(1)
94
+
95
+ tasks = tasks_data.get("tasks", [])
96
+
97
+ # Validate task completion
98
+ if tasks:
99
+ total, completed, incomplete = validate_task_completeness(tasks)
100
+ completion_rate = completed / total if total > 0 else 0
101
+
102
+ print(f"Research Tasks: {completed}/{total} completed ({completion_rate:.0%})", file=sys.stderr)
103
+
104
+ if completion_rate < 0.5:
105
+ print(f"WARNING: Research incomplete. Only {completed}/{total} tasks have decisions.", file=sys.stderr)
106
+ print(f"Incomplete tasks: {', '.join(incomplete)}", file=sys.stderr)
107
+ print(f"Generated research.md will contain TODO placeholders.", file=sys.stderr)
108
+ print(f"Fix: Add decision/rationale/alternatives fields to tasks.json", file=sys.stderr)
109
+
110
+ sources = []
111
+ for path in research_dir.rglob("*.md"):
112
+ if path.name in {"research.md"}:
113
+ continue
114
+ sources.append(str(path.relative_to(req_dir)))
115
+
116
+ lines = []
117
+ lines.append(f"# Research Summary — {feature_title}")
118
+ lines.append("")
119
+ lines.append(f"Generated: {generated_at}")
120
+ lines.append("")
121
+ lines.append("## Decisions")
122
+ lines.append("")
123
+
124
+ if not tasks:
125
+ lines.append("_No research tasks detected. Populate research/tasks.json to track clarifications._")
126
+ else:
127
+ for task in tasks:
128
+ task_id = task.get("id", "R???")
129
+ prompt = task.get("prompt", "(unknown prompt)")
130
+ lines.append(f"### {task_id} — {prompt}")
131
+
132
+ # 处理空字符串,替换为 TODO 占位符
133
+ decision = task.get("decision", "")
134
+ rationale = task.get("rationale", "")
135
+ alternatives = task.get("alternatives", "")
136
+
137
+ decision = decision.strip() if decision.strip() else "TODO - fill decision outcome"
138
+ rationale = rationale.strip() if rationale.strip() else "TODO - explain why this decision was chosen"
139
+ alternatives = alternatives.strip() if alternatives.strip() else "TODO - list evaluated alternatives"
140
+
141
+ lines.append(f"- Decision: {decision}")
142
+ lines.append(f"- Rationale: {rationale}")
143
+ lines.append(f"- Alternatives considered: {alternatives}")
144
+ source = task.get("source")
145
+ if source:
146
+ lines.append(f"- Source: {source}")
147
+ lines.append("")
148
+
149
+ lines.append("## Source Library")
150
+ lines.append("")
151
+ if sources:
152
+ for src in sorted(sources):
153
+ lines.append(f"- {src}")
154
+ else:
155
+ lines.append("_No research source files detected yet._")
156
+
157
+ summary_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
158
+
159
+ # Post-write validation: detect TODO placeholders
160
+ content = summary_path.read_text(encoding="utf-8")
161
+ todo_count = content.count("TODO")
162
+ placeholder_count = content.count("{{") + content.count("}}")
163
+
164
+ if todo_count > 0 or placeholder_count > 0:
165
+ print(f"⚠️ WARNING: Generated research.md contains quality issues:", file=sys.stderr)
166
+ if todo_count > 0:
167
+ print(f" - {todo_count} TODO marker(s) found", file=sys.stderr)
168
+ if placeholder_count > 0:
169
+ print(f" - Placeholder markers {{{{ }}}} found", file=sys.stderr)
170
+ print(f"", file=sys.stderr)
171
+ print(f"This will cause validate-research.sh to FAIL.", file=sys.stderr)
172
+ print(f"", file=sys.stderr)
173
+ print(f"Fix Options:", file=sys.stderr)
174
+ print(f" 1. Update tasks.json with actual decision/rationale/alternatives", file=sys.stderr)
175
+ print(f" 2. Manually edit {summary_path.relative_to(req_dir)}", file=sys.stderr)
176
+ print(f" 3. Use .claude/docs/templates/RESEARCH_TEMPLATE.md as reference", file=sys.stderr)
177
+ print(f"", file=sys.stderr)
178
+ print(f"Wrote research summary → {summary_path} (WITH WARNINGS)", file=sys.stderr)
179
+ else:
180
+ print(f"✅ Wrote research summary → {summary_path}", file=sys.stderr)
181
+ print(f" Quality check: No TODO/PLACEHOLDER markers detected", file=sys.stderr)
182
+ PY