cc-devflow 1.0.1

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 (277) hide show
  1. package/.claude/CLAUDE.md +83 -0
  2. package/.claude/agents/architecture-designer.md +443 -0
  3. package/.claude/agents/bug-analyzer.md +382 -0
  4. package/.claude/agents/checklist-agent.md +175 -0
  5. package/.claude/agents/clarify-analyst.md +50 -0
  6. package/.claude/agents/code-reviewer.md +71 -0
  7. package/.claude/agents/codex-analyzer.md +39 -0
  8. package/.claude/agents/compatibility-checker.md +580 -0
  9. package/.claude/agents/consistency-checker.md +532 -0
  10. package/.claude/agents/impact-analyzer.md +441 -0
  11. package/.claude/agents/planner.md +230 -0
  12. package/.claude/agents/prd-writer.md +320 -0
  13. package/.claude/agents/project-guidelines-generator.md +1329 -0
  14. package/.claude/agents/qa-tester.md +313 -0
  15. package/.claude/agents/release-manager.md +295 -0
  16. package/.claude/agents/security-reviewer.md +314 -0
  17. package/.claude/agents/style-guide-generator.md +458 -0
  18. package/.claude/agents/tech-architect.md +516 -0
  19. package/.claude/agents/ui-designer.md +485 -0
  20. package/.claude/commands/code-review-high.md +58 -0
  21. package/.claude/commands/core-architecture.md +429 -0
  22. package/.claude/commands/core-guidelines.md +486 -0
  23. package/.claude/commands/core-roadmap.md +439 -0
  24. package/.claude/commands/core-style.md +293 -0
  25. package/.claude/commands/flow-archive.md +245 -0
  26. package/.claude/commands/flow-checklist.md +260 -0
  27. package/.claude/commands/flow-clarify.md +136 -0
  28. package/.claude/commands/flow-constitution.md +82 -0
  29. package/.claude/commands/flow-dev.md +134 -0
  30. package/.claude/commands/flow-epic.md +150 -0
  31. package/.claude/commands/flow-fix.md +104 -0
  32. package/.claude/commands/flow-ideate.md +214 -0
  33. package/.claude/commands/flow-init.md +313 -0
  34. package/.claude/commands/flow-new.md +394 -0
  35. package/.claude/commands/flow-prd.md +131 -0
  36. package/.claude/commands/flow-qa.md +93 -0
  37. package/.claude/commands/flow-release.md +92 -0
  38. package/.claude/commands/flow-restart.md +98 -0
  39. package/.claude/commands/flow-status.md +64 -0
  40. package/.claude/commands/flow-tech.md +142 -0
  41. package/.claude/commands/flow-ui.md +189 -0
  42. package/.claude/commands/flow-update.md +111 -0
  43. package/.claude/commands/flow-upgrade.md +115 -0
  44. package/.claude/commands/flow-verify.md +96 -0
  45. package/.claude/commands/problem-analyzer.md +60 -0
  46. package/.claude/config/quality-rules.yml +161 -0
  47. package/.claude/docs/SPEC_KIT_CONSTITUTION_ANALYSIS.md +426 -0
  48. package/.claude/docs/design/consistency-conflict-detection-algorithms.md +658 -0
  49. package/.claude/docs/design/intent-driven-input-design.md +380 -0
  50. package/.claude/docs/design/prd-version-management-design.md +437 -0
  51. package/.claude/docs/guides/INIT_TROUBLESHOOTING.md +117 -0
  52. package/.claude/docs/guides/NEW_TROUBLESHOOTING.md +151 -0
  53. package/.claude/docs/guides/ROADMAP_TROUBLESHOOTING.md +188 -0
  54. package/.claude/docs/guides/TASK_COMPLETION_MARKING.md +338 -0
  55. package/.claude/docs/templates/ARCHITECTURE_TEMPLATE.md +633 -0
  56. package/.claude/docs/templates/BACKLOG_TEMPLATE.md +261 -0
  57. package/.claude/docs/templates/CHECKLIST_TEMPLATE.md +52 -0
  58. package/.claude/docs/templates/CLARIFICATION_REPORT_TEMPLATE.md +206 -0
  59. package/.claude/docs/templates/CODE_REVIEW_TEMPLATE.md +71 -0
  60. package/.claude/docs/templates/EPIC_TEMPLATE.md +805 -0
  61. package/.claude/docs/templates/INIT_FLOW_TEMPLATE.md +213 -0
  62. package/.claude/docs/templates/INTENT_CLARIFICATION_TEMPLATE.md +57 -0
  63. package/.claude/docs/templates/NEW_ORCHESTRATION_TEMPLATE.md +148 -0
  64. package/.claude/docs/templates/PRD_TEMPLATE.md +562 -0
  65. package/.claude/docs/templates/RESEARCH_TEMPLATE.md +276 -0
  66. package/.claude/docs/templates/REVIEW-HIGH.md +57 -0
  67. package/.claude/docs/templates/ROADMAP_DIALOGUE_TEMPLATE.md +198 -0
  68. package/.claude/docs/templates/ROADMAP_TEMPLATE.md +310 -0
  69. package/.claude/docs/templates/STYLE_TEMPLATE.md +1266 -0
  70. package/.claude/docs/templates/TASKS_TEMPLATE.md +523 -0
  71. package/.claude/docs/templates/TECH_DESIGN_TEMPLATE.md +1019 -0
  72. package/.claude/docs/templates/UI_PROTOTYPE_TEMPLATE.md +1436 -0
  73. package/.claude/guides/agent-guides/agent-coordination-guide.md +459 -0
  74. package/.claude/guides/project-guidelines-system.md +463 -0
  75. package/.claude/guides/technical-guides/datetime-handling-guide.md +563 -0
  76. package/.claude/guides/technical-guides/git-github-guide.md +642 -0
  77. package/.claude/guides/technical-guides/test-execution-guide.md +618 -0
  78. package/.claude/guides/workflow-guides/bug-fix-orchestrator.md +217 -0
  79. package/.claude/guides/workflow-guides/flow-orchestrator.md +282 -0
  80. package/.claude/hooks/checklist-gate.js +397 -0
  81. package/.claude/hooks/error-handling-reminder.sh +12 -0
  82. package/.claude/hooks/error-handling-reminder.ts +459 -0
  83. package/.claude/hooks/post-tool-use-tracker.sh +280 -0
  84. package/.claude/hooks/pre-tool-use-guardrail.sh +36 -0
  85. package/.claude/hooks/pre-tool-use-guardrail.ts +342 -0
  86. package/.claude/hooks/skill-activation-prompt.sh +36 -0
  87. package/.claude/hooks/skill-activation-prompt.ts +214 -0
  88. package/.claude/hooks/state/skills-used-test-guard.json +3 -0
  89. package/.claude/rules/devflow-conventions.md +305 -0
  90. package/.claude/rules/project-constitution.md +748 -0
  91. package/.claude/schemas/constitution.schema.json +43 -0
  92. package/.claude/scripts/analyze-upgrade-impact.sh +200 -0
  93. package/.claude/scripts/archive-requirement.sh +351 -0
  94. package/.claude/scripts/calculate-checklist-completion.sh +243 -0
  95. package/.claude/scripts/calculate-quarter.sh +206 -0
  96. package/.claude/scripts/check-dependencies.sh +409 -0
  97. package/.claude/scripts/check-prerequisites.sh +232 -0
  98. package/.claude/scripts/check-task-status.sh +264 -0
  99. package/.claude/scripts/checklist-errors.sh +131 -0
  100. package/.claude/scripts/common.sh +570 -0
  101. package/.claude/scripts/consolidate-research.sh +182 -0
  102. package/.claude/scripts/create-requirement.sh +426 -0
  103. package/.claude/scripts/export-contracts.sh +117 -0
  104. package/.claude/scripts/extract-data-model.sh +78 -0
  105. package/.claude/scripts/generate-clarification-questions.sh +377 -0
  106. package/.claude/scripts/generate-clarification-report.sh +463 -0
  107. package/.claude/scripts/generate-quickstart.sh +146 -0
  108. package/.claude/scripts/generate-research-tasks.sh +157 -0
  109. package/.claude/scripts/generate-status-report.sh +523 -0
  110. package/.claude/scripts/generate-tech-analysis.sh +46 -0
  111. package/.claude/scripts/locate-requirement-in-roadmap.sh +233 -0
  112. package/.claude/scripts/manage-constitution.sh +602 -0
  113. package/.claude/scripts/mark-task-complete.sh +198 -0
  114. package/.claude/scripts/populate-research-tasks.sh +259 -0
  115. package/.claude/scripts/recover-workflow.sh +460 -0
  116. package/.claude/scripts/run-clarify-scan.sh +601 -0
  117. package/.claude/scripts/run-high-review.sh +62 -0
  118. package/.claude/scripts/run-problem-analysis.sh +68 -0
  119. package/.claude/scripts/setup-epic.sh +173 -0
  120. package/.claude/scripts/sync-roadmap-progress.sh +300 -0
  121. package/.claude/scripts/sync-task-marks.sh +199 -0
  122. package/.claude/scripts/test-clarify-scan.sh +515 -0
  123. package/.claude/scripts/update-agent-context.sh +806 -0
  124. package/.claude/scripts/validate-constitution.sh +567 -0
  125. package/.claude/scripts/validate-hooks.sh +487 -0
  126. package/.claude/scripts/validate-research.sh +332 -0
  127. package/.claude/scripts/validate-scope-boundary.sh +493 -0
  128. package/.claude/scripts/verify-setup.sh +37 -0
  129. package/.claude/settings.json +76 -0
  130. package/.claude/skills/_reference-implementations/README.md +96 -0
  131. package/.claude/skills/_reference-implementations/backend-express-prisma/SKILL.md +302 -0
  132. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/architecture-overview.md +451 -0
  133. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/async-and-errors.md +307 -0
  134. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/complete-examples.md +638 -0
  135. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/configuration.md +275 -0
  136. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/database-patterns.md +224 -0
  137. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/middleware-guide.md +213 -0
  138. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/routing-and-controllers.md +756 -0
  139. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/sentry-and-monitoring.md +336 -0
  140. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/services-and-repositories.md +789 -0
  141. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/testing-guide.md +235 -0
  142. package/.claude/skills/_reference-implementations/backend-express-prisma/resources/validation-patterns.md +754 -0
  143. package/.claude/skills/_reference-implementations/frontend-react-mui/SKILL.md +399 -0
  144. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/common-patterns.md +331 -0
  145. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/complete-examples.md +872 -0
  146. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/component-patterns.md +502 -0
  147. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/data-fetching.md +767 -0
  148. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/file-organization.md +502 -0
  149. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/loading-and-error-states.md +501 -0
  150. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/performance.md +406 -0
  151. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/routing-guide.md +364 -0
  152. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/styling-guide.md +428 -0
  153. package/.claude/skills/_reference-implementations/frontend-react-mui/resources/typescript-standards.md +418 -0
  154. package/.claude/skills/cc-devflow-orchestrator/SKILL.md +229 -0
  155. package/.claude/skills/constitution-guardian/SKILL.md +306 -0
  156. package/.claude/skills/devflow-constitution-quick-ref/SKILL.md +374 -0
  157. package/.claude/skills/devflow-file-standards/SKILL.md +353 -0
  158. package/.claude/skills/devflow-tdd-enforcer/SKILL.md +192 -0
  159. package/.claude/skills/skill-developer/ADVANCED.md +197 -0
  160. package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +306 -0
  161. package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +152 -0
  162. package/.claude/skills/skill-developer/SKILL.md +426 -0
  163. package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +315 -0
  164. package/.claude/skills/skill-developer/TRIGGER_TYPES.md +305 -0
  165. package/.claude/skills/skill-developer/TROUBLESHOOTING.md +514 -0
  166. package/.claude/skills/skill-rules.json +213 -0
  167. package/.claude/tests/README.md +300 -0
  168. package/.claude/tests/TODO.md +69 -0
  169. package/.claude/tests/__pycache__/test_analyze_upgrade_impact.cpython-311-pytest-7.2.2.pyc +0 -0
  170. package/.claude/tests/__pycache__/test_consolidate_research.cpython-311-pytest-7.2.2.pyc +0 -0
  171. package/.claude/tests/__pycache__/test_export_contracts.cpython-311-pytest-7.2.2.pyc +0 -0
  172. package/.claude/tests/__pycache__/test_extract_data_model.cpython-311-pytest-7.2.2.pyc +0 -0
  173. package/.claude/tests/__pycache__/test_generate_quickstart.cpython-311-pytest-7.2.2.pyc +0 -0
  174. package/.claude/tests/__pycache__/test_generate_research_tasks.cpython-311-pytest-7.2.2.pyc +0 -0
  175. package/.claude/tests/constitution/run_all_constitution_tests.sh +111 -0
  176. package/.claude/tests/constitution/test_agent_assignment.sh +207 -0
  177. package/.claude/tests/constitution/test_article_coverage.sh +201 -0
  178. package/.claude/tests/constitution/test_template_completeness.sh +150 -0
  179. package/.claude/tests/constitution/test_version_consistency.sh +120 -0
  180. package/.claude/tests/fixtures/spec_delta_full.md +16 -0
  181. package/.claude/tests/fixtures/tasks_progress_sample.md +5 -0
  182. package/.claude/tests/run-all-tests.sh +229 -0
  183. package/.claude/tests/scripts/run.sh +30 -0
  184. package/.claude/tests/scripts/test-framework.sh +128 -0
  185. package/.claude/tests/scripts/test_check_prerequisites.sh +511 -0
  186. package/.claude/tests/scripts/test_check_prerequisites.sh.bak +504 -0
  187. package/.claude/tests/scripts/test_check_prerequisites.sh.bak2 +505 -0
  188. package/.claude/tests/scripts/test_check_prerequisites.sh.bak3 +506 -0
  189. package/.claude/tests/scripts/test_check_prerequisites.sh.bak4 +507 -0
  190. package/.claude/tests/scripts/test_check_prerequisites.sh.bak5 +508 -0
  191. package/.claude/tests/scripts/test_check_task_status.sh +499 -0
  192. package/.claude/tests/scripts/test_common.sh +244 -0
  193. package/.claude/tests/scripts/test_generate_status_report.sh +71 -0
  194. package/.claude/tests/scripts/test_mark_task_complete.sh +441 -0
  195. package/.claude/tests/scripts/test_mark_task_complete.sh.backup +410 -0
  196. package/.claude/tests/scripts/test_recover_workflow.sh +304 -0
  197. package/.claude/tests/scripts/test_setup_epic.sh +437 -0
  198. package/.claude/tests/scripts/test_sync_task_marks.sh +196 -0
  199. package/.claude/tests/scripts/test_validate_constitution.sh +74 -0
  200. package/.claude/tests/scripts/test_validate_research.sh +462 -0
  201. package/.claude/tests/slugify.bats +82 -0
  202. package/.claude/tests/test-framework.sh +732 -0
  203. package/.claude/tests/test_analyze_upgrade_impact.py +34 -0
  204. package/.claude/tests/test_consolidate_research.py +48 -0
  205. package/.claude/tests/test_export_contracts.py +43 -0
  206. package/.claude/tests/test_extract_data_model.py +33 -0
  207. package/.claude/tests/test_generate_quickstart.py +50 -0
  208. package/.claude/tests/test_generate_research_tasks.py +52 -0
  209. package/.claude/tsc-cache/6e64f818-6398-49ca-8623-581a9af85c44/edited-files.log +1 -0
  210. package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/affected-repos.txt +1 -0
  211. package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/edited-files.log +1 -0
  212. package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/affected-repos.txt +1 -0
  213. package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/edited-files.log +1 -0
  214. package/CHANGELOG.md +507 -0
  215. package/LICENSE +21 -0
  216. package/README.md +534 -0
  217. package/README.zh-CN.md +530 -0
  218. package/bin/adapt.js +240 -0
  219. package/bin/cc-devflow-cli.js +185 -0
  220. package/bin/cc-devflow.js +78 -0
  221. package/config/adapters.yml +5 -0
  222. package/config/schema/adapters.schema.json +44 -0
  223. package/docs/CLAUDE.md +26 -0
  224. package/docs/commands/README.md +61 -0
  225. package/docs/commands/README.zh-CN.md +55 -0
  226. package/docs/commands/core-roadmap.md +106 -0
  227. package/docs/commands/core-roadmap.zh-CN.md +102 -0
  228. package/docs/commands/core-style.md +405 -0
  229. package/docs/commands/core-style.zh-CN.md +405 -0
  230. package/docs/commands/flow-init.md +134 -0
  231. package/docs/commands/flow-init.zh-CN.md +163 -0
  232. package/docs/commands/flow-new.md +274 -0
  233. package/docs/commands/flow-new.zh-CN.md +270 -0
  234. package/docs/guides/getting-started.md +204 -0
  235. package/docs/guides/getting-started.zh-CN.md +152 -0
  236. package/lib/adapters/adapter-interface.js +57 -0
  237. package/lib/adapters/claude-adapter.js +74 -0
  238. package/lib/adapters/codex-adapter.js +40 -0
  239. package/lib/adapters/config-validator.js +68 -0
  240. package/lib/adapters/logger.js +42 -0
  241. package/lib/adapters/registry.js +153 -0
  242. package/lib/compiler/CLAUDE.md +92 -0
  243. package/lib/compiler/__tests__/drift.test.js +215 -0
  244. package/lib/compiler/__tests__/errors.test.js +184 -0
  245. package/lib/compiler/__tests__/incremental.test.js +174 -0
  246. package/lib/compiler/__tests__/integration.test.js +174 -0
  247. package/lib/compiler/__tests__/manifest.test.js +233 -0
  248. package/lib/compiler/__tests__/parser.test.js +456 -0
  249. package/lib/compiler/__tests__/schemas.test.js +301 -0
  250. package/lib/compiler/__tests__/skills-registry.test.js +125 -0
  251. package/lib/compiler/__tests__/transformer.test.js +286 -0
  252. package/lib/compiler/emitters/antigravity-emitter.js +171 -0
  253. package/lib/compiler/emitters/base-emitter.js +73 -0
  254. package/lib/compiler/emitters/codex-emitter.js +52 -0
  255. package/lib/compiler/emitters/cursor-emitter.js +31 -0
  256. package/lib/compiler/emitters/index.js +50 -0
  257. package/lib/compiler/emitters/qwen-emitter.js +39 -0
  258. package/lib/compiler/errors.js +119 -0
  259. package/lib/compiler/index.js +256 -0
  260. package/lib/compiler/manifest.js +242 -0
  261. package/lib/compiler/parser.js +258 -0
  262. package/lib/compiler/platforms.js +113 -0
  263. package/lib/compiler/resource-copier.js +320 -0
  264. package/lib/compiler/rules-emitters/__tests__/antigravity-rules-emitter.test.js +191 -0
  265. package/lib/compiler/rules-emitters/__tests__/codex-rules-emitter.test.js +109 -0
  266. package/lib/compiler/rules-emitters/__tests__/cursor-rules-emitter.test.js +123 -0
  267. package/lib/compiler/rules-emitters/__tests__/qwen-rules-emitter.test.js +123 -0
  268. package/lib/compiler/rules-emitters/antigravity-rules-emitter.js +253 -0
  269. package/lib/compiler/rules-emitters/base-rules-emitter.js +83 -0
  270. package/lib/compiler/rules-emitters/codex-rules-emitter.js +116 -0
  271. package/lib/compiler/rules-emitters/cursor-rules-emitter.js +98 -0
  272. package/lib/compiler/rules-emitters/index.js +71 -0
  273. package/lib/compiler/rules-emitters/qwen-rules-emitter.js +70 -0
  274. package/lib/compiler/schemas.js +144 -0
  275. package/lib/compiler/skills-registry.js +225 -0
  276. package/lib/compiler/transformer.js +236 -0
  277. package/package.json +50 -0
@@ -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
@@ -0,0 +1,426 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Create new requirement structure for cc-devflow
4
+ #
5
+ # This script initializes a new requirement or BUG directory structure.
6
+ # Based on spec-kit's create-new-feature.sh design.
7
+ #
8
+ # Usage: ./create-requirement.sh [REQ_ID] [OPTIONS]
9
+ #
10
+ # ARGUMENTS:
11
+ # REQ_ID Requirement ID (REQ-XXX or BUG-XXX format)
12
+ # Optional if --interactive mode is used
13
+ #
14
+ # OPTIONS:
15
+ # --title TITLE Requirement title (for git branch)
16
+ # --description DESC Brief description (optional)
17
+ # --skip-git Skip git branch creation
18
+ # --interactive, -i Interactive mode (prompts for inputs)
19
+ # --json Output in JSON format
20
+ # --help, -h Show help message
21
+ #
22
+ # EXAMPLES:
23
+ # # Create requirement with title
24
+ # ./create-requirement.sh REQ-123 --title "User authentication"
25
+ #
26
+ # # Interactive mode
27
+ # ./create-requirement.sh --interactive
28
+ #
29
+ # # Create BUG structure
30
+ # ./create-requirement.sh BUG-456 --title "Fix login issue" --skip-git
31
+ #
32
+ # # JSON output for automation
33
+ # ./create-requirement.sh REQ-123 --title "API Gateway" --json
34
+
35
+ set -e
36
+
37
+ # Parse command line arguments
38
+ REQ_ID=""
39
+ TITLE=""
40
+ DESCRIPTION=""
41
+ SKIP_GIT=false
42
+ INTERACTIVE=false
43
+ JSON_MODE=false
44
+ AUTO_ID=false
45
+
46
+ while [[ $# -gt 0 ]]; do
47
+ case "$1" in
48
+ --title)
49
+ TITLE="$2"
50
+ shift 2
51
+ ;;
52
+ --description)
53
+ DESCRIPTION="$2"
54
+ shift 2
55
+ ;;
56
+ --skip-git)
57
+ SKIP_GIT=true
58
+ shift
59
+ ;;
60
+ --interactive|-i)
61
+ INTERACTIVE=true
62
+ shift
63
+ ;;
64
+ --json)
65
+ JSON_MODE=true
66
+ shift
67
+ ;;
68
+ --auto-id)
69
+ AUTO_ID=true
70
+ shift
71
+ ;;
72
+ --help|-h)
73
+ cat << 'EOF'
74
+ Usage: create-requirement.sh [REQ_ID] [OPTIONS]
75
+
76
+ Create new requirement or BUG structure for cc-devflow.
77
+
78
+ ARGUMENTS:
79
+ REQ_ID Requirement ID (REQ-XXX or BUG-XXX format)
80
+ Optional if --interactive mode is used
81
+
82
+ OPTIONS:
83
+ --title TITLE Requirement title (for git branch naming)
84
+ --description DESC Brief description (optional)
85
+ --skip-git Skip git branch creation
86
+ --interactive, -i Interactive mode (prompts for inputs)
87
+ --json Output results in JSON format
88
+ --auto-id Auto-select next available REQ-ID when missing or duplicated
89
+ --help, -h Show this help message
90
+
91
+ EXAMPLES:
92
+ # Create requirement with title
93
+ ./create-requirement.sh REQ-123 --title "User authentication"
94
+
95
+ # Interactive mode
96
+ ./create-requirement.sh --interactive
97
+
98
+ # Create BUG structure
99
+ ./create-requirement.sh BUG-456 --title "Fix login issue"
100
+
101
+ # JSON output
102
+ ./create-requirement.sh REQ-123 --title "API Gateway" --json
103
+
104
+ STRUCTURE CREATED:
105
+ Requirements (REQ-XXX):
106
+ devflow/requirements/REQ-XXX/
107
+ ├── research/ # External research materials
108
+ ├── EXECUTION_LOG.md # Event log
109
+ └── orchestration_status.json # Status tracking
110
+
111
+ BUG Fixes (BUG-XXX):
112
+ devflow/bugs/BUG-XXX/
113
+ ├── EXECUTION_LOG.md
114
+ └── status.json
115
+
116
+ GIT BRANCH:
117
+ - Requirements: feature/REQ-XXX-title
118
+ - BUG Fixes: bugfix/BUG-XXX-title
119
+
120
+ EOF
121
+ exit 0
122
+ ;;
123
+ -*)
124
+ echo "ERROR: Unknown option '$1'. Use --help for usage information." >&2
125
+ exit 1
126
+ ;;
127
+ *)
128
+ if [[ -z "$REQ_ID" ]]; then
129
+ REQ_ID="$1"
130
+ else
131
+ echo "ERROR: Too many arguments. Use --help for usage information." >&2
132
+ exit 1
133
+ fi
134
+ shift
135
+ ;;
136
+ esac
137
+ done
138
+
139
+ # Source common functions
140
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
141
+ source "$SCRIPT_DIR/common.sh"
142
+ REPO_ROOT=$(get_repo_root)
143
+
144
+ # Interactive mode
145
+ if $INTERACTIVE; then
146
+ if ! $JSON_MODE; then
147
+ echo "=== Create New Requirement ==="
148
+ echo ""
149
+ fi
150
+
151
+ # Prompt for requirement ID if not provided
152
+ if [[ -z "$REQ_ID" ]]; then
153
+ suggested_req_id=$(next_available_req_id "$REPO_ROOT")
154
+ read -p "Requirement ID (REQ-XXX or BUG-XXX) [${suggested_req_id}]: " input_req_id
155
+ input_req_id=$(echo "${input_req_id}" | tr '[:lower:]' '[:upper:]')
156
+ if [[ -z "$input_req_id" ]]; then
157
+ AUTO_ID=true
158
+ REQ_ID="$suggested_req_id"
159
+ else
160
+ REQ_ID="$input_req_id"
161
+ fi
162
+ fi
163
+
164
+ # Prompt for title if not provided
165
+ if [[ -z "$TITLE" ]]; then
166
+ read -p "Requirement Title: " TITLE
167
+ fi
168
+
169
+ # Prompt for description
170
+ if [[ -z "$DESCRIPTION" ]]; then
171
+ read -p "Brief Description (optional): " DESCRIPTION
172
+ fi
173
+
174
+ # Prompt for git branch creation
175
+ if ! $SKIP_GIT && has_git; then
176
+ read -p "Create git branch? (y/n): " create_branch
177
+ if [[ "$create_branch" != "y" && "$create_branch" != "Y" ]]; then
178
+ SKIP_GIT=true
179
+ fi
180
+ fi
181
+ fi
182
+
183
+ # Ensure requirement ID is set, auto-select when allowed
184
+ if [[ -z "$REQ_ID" ]]; then
185
+ AUTO_ID=true
186
+ REQ_ID=$(next_available_req_id "$REPO_ROOT")
187
+ if [[ -z "$REQ_ID" ]]; then
188
+ echo "ERROR: Unable to determine next requirement ID" >&2
189
+ exit 1
190
+ fi
191
+ if ! $JSON_MODE; then
192
+ echo "Auto-selected requirement ID: $REQ_ID" >&2
193
+ fi
194
+ fi
195
+
196
+ # Normalize requirement ID to uppercase
197
+ REQ_ID=$(echo "$REQ_ID" | tr '[:lower:]' '[:upper:]')
198
+
199
+ # Validate requirement ID format
200
+ validate_req_id "$REQ_ID" || exit 1
201
+
202
+ # Resolve conflicts when requirement ID already exists
203
+ if req_id_in_use "$REPO_ROOT" "$REQ_ID"; then
204
+ if $AUTO_ID; then
205
+ original_req_id="$REQ_ID"
206
+ while req_id_in_use "$REPO_ROOT" "$REQ_ID"; do
207
+ next_candidate=$(next_available_req_id "$REPO_ROOT")
208
+ if [[ "$next_candidate" == "$REQ_ID" ]]; then
209
+ next_candidate="REQ-$(date +%Y%m%d%H%M%S)"
210
+ fi
211
+ REQ_ID="$next_candidate"
212
+ done
213
+ if [[ "$REQ_ID" != "$original_req_id" ]] && ! $JSON_MODE; then
214
+ echo "Requirement ID in use; switched to $REQ_ID" >&2
215
+ fi
216
+ else
217
+ suggested_req_id=$(next_available_req_id "$REPO_ROOT")
218
+ conflict_dir=$(get_req_dir "$REPO_ROOT" "$REQ_ID")
219
+ echo "ERROR: Requirement directory already exists: $conflict_dir" >&2
220
+ if [[ "$suggested_req_id" != "$REQ_ID" ]]; then
221
+ echo "Suggested next available ID: $suggested_req_id" >&2
222
+ fi
223
+ exit 1
224
+ fi
225
+ fi
226
+
227
+ # Get requirement type and directory
228
+ REQ_TYPE=$(get_req_type "$REQ_ID")
229
+ REQ_DIR=$(get_req_dir "$REPO_ROOT" "$REQ_ID")
230
+
231
+ # Create directory structure
232
+ if ! $JSON_MODE; then
233
+ echo "Creating requirement structure at $REQ_DIR..." >&2
234
+ fi
235
+
236
+ # Create directories
237
+ mkdir -p "$REQ_DIR/research"
238
+
239
+ # Initialize EXECUTION_LOG.md
240
+ cat > "$REQ_DIR/EXECUTION_LOG.md" <<EOF
241
+ # Execution Log: $REQ_ID
242
+
243
+ **Title**: ${TITLE:-"To be defined"}
244
+ **Type**: $REQ_TYPE
245
+ **Created**: $(get_beijing_time_full)
246
+
247
+ EOF
248
+
249
+ if [[ -n "$DESCRIPTION" ]]; then
250
+ cat >> "$REQ_DIR/EXECUTION_LOG.md" <<EOF
251
+ ## Description
252
+ $DESCRIPTION
253
+
254
+ EOF
255
+ fi
256
+
257
+ cat >> "$REQ_DIR/EXECUTION_LOG.md" <<'EOF'
258
+ ## Events
259
+
260
+ EOF
261
+
262
+ # Initialize status file
263
+ if [[ "$REQ_TYPE" == "bug" ]]; then
264
+ # BUG-specific status file
265
+ cat > "$REQ_DIR/status.json" <<EOF
266
+ {
267
+ "bugId": "$REQ_ID",
268
+ "title": "${TITLE:-"To be defined"}",
269
+ "status": "initialized",
270
+ "phase": "analysis",
271
+ "severity": "unknown",
272
+ "createdAt": "$(get_beijing_time_iso)",
273
+ "updatedAt": "$(get_beijing_time_iso)"
274
+ }
275
+ EOF
276
+ else
277
+ # Requirement status file
278
+ cat > "$REQ_DIR/orchestration_status.json" <<EOF
279
+ {
280
+ "reqId": "$REQ_ID",
281
+ "title": "${TITLE:-"To be defined"}",
282
+ "status": "initialized",
283
+ "phase": "planning",
284
+ "createdAt": "$(get_beijing_time_iso)",
285
+ "updatedAt": "$(get_beijing_time_iso)"
286
+ }
287
+ EOF
288
+ fi
289
+
290
+ # Create README.md for the requirement
291
+ cat > "$REQ_DIR/README.md" <<EOF
292
+ # $REQ_ID: ${TITLE:-"To be defined"}
293
+
294
+ **Status**: Initialized
295
+ **Type**: $REQ_TYPE
296
+ **Created**: $(get_beijing_time_full)
297
+
298
+ EOF
299
+
300
+ if [[ -n "$DESCRIPTION" ]]; then
301
+ cat >> "$REQ_DIR/README.md" <<EOF
302
+ ## Description
303
+ $DESCRIPTION
304
+
305
+ EOF
306
+ fi
307
+
308
+ cat >> "$REQ_DIR/README.md" <<'EOF'
309
+ ## Documents
310
+
311
+ ### Planning Phase
312
+ - [ ] PRD.md - Product Requirements Document
313
+ - [ ] EPIC.md - Epic Planning
314
+ - [ ] TASKS.md - Task Breakdown
315
+
316
+ ### Execution Phase
317
+ - [ ] TEST_PLAN.md - Test Plan
318
+ - [ ] SECURITY_PLAN.md - Security Plan
319
+ - [ ] EXECUTION_LOG.md - Event Log
320
+
321
+ ### Review Phase
322
+ - [ ] TEST_REPORT.md - Test Report
323
+ - [ ] SECURITY_REPORT.md - Security Report
324
+ - [ ] RELEASE_PLAN.md - Release Plan
325
+
326
+ ## Research Materials
327
+ Place external research materials in `research/` directory:
328
+ - API documentation
329
+ - Design specifications
330
+ - Reference implementations
331
+ - Planning documents
332
+
333
+ ## Workflow
334
+ 1. **Planning**: Create PRD → Generate EPIC → Break down TASKS
335
+ 2. **Development**: Implement tasks following TDD approach
336
+ 3. **Quality**: Execute test plan and security review
337
+ 4. **Release**: Create release plan and merge to main
338
+
339
+ EOF
340
+
341
+ # Log the creation event
342
+ log_event "$REQ_ID" "Requirement structure initialized"
343
+
344
+ if [[ -n "$TITLE" ]]; then
345
+ log_event "$REQ_ID" "Title: $TITLE"
346
+ fi
347
+
348
+ if [[ -n "$DESCRIPTION" ]]; then
349
+ log_event "$REQ_ID" "Description: $DESCRIPTION"
350
+ fi
351
+
352
+ # Create git branch if requested and available
353
+ GIT_BRANCH=""
354
+ if ! $SKIP_GIT && has_git; then
355
+ # Generate branch name from title
356
+ if [[ -n "$TITLE" ]]; then
357
+ BRANCH_SUFFIX=$(slugify "$TITLE")
358
+ if [[ -z "$BRANCH_SUFFIX" ]]; then
359
+ BRANCH_SUFFIX="new-requirement"
360
+ fi
361
+ else
362
+ BRANCH_SUFFIX="new-requirement"
363
+ fi
364
+
365
+ # Determine branch prefix based on type
366
+ if [[ "$REQ_TYPE" == "bug" ]]; then
367
+ GIT_BRANCH="bugfix/$REQ_ID-$BRANCH_SUFFIX"
368
+ else
369
+ GIT_BRANCH="feature/$REQ_ID-$BRANCH_SUFFIX"
370
+ fi
371
+
372
+ # Check if branch already exists
373
+ if git rev-parse --verify "$GIT_BRANCH" >/dev/null 2>&1; then
374
+ if ! $JSON_MODE; then
375
+ echo "WARNING: Git branch already exists: $GIT_BRANCH" >&2
376
+ echo "Skipping branch creation." >&2
377
+ fi
378
+ else
379
+ # Create and checkout new branch
380
+ git checkout -b "$GIT_BRANCH" >/dev/null 2>&1
381
+ log_event "$REQ_ID" "Created git branch: $GIT_BRANCH"
382
+
383
+ if ! $JSON_MODE; then
384
+ echo "Created and checked out branch: $GIT_BRANCH" >&2
385
+ fi
386
+ fi
387
+
388
+ # Set environment variable for non-branch-based workflows
389
+ export DEVFLOW_REQ_ID="$REQ_ID"
390
+ fi
391
+
392
+ # Output results
393
+ if $JSON_MODE; then
394
+ printf '{"req_id":"%s","req_type":"%s","req_dir":"%s","title":"%s","git_branch":"%s","created_at":"%s"}\n' \
395
+ "$REQ_ID" \
396
+ "$REQ_TYPE" \
397
+ "$REQ_DIR" \
398
+ "${TITLE:-""}" \
399
+ "${GIT_BRANCH:-""}" \
400
+ "$(get_beijing_time_iso)"
401
+ else
402
+ echo ""
403
+ echo "✅ Requirement structure created successfully!"
404
+ echo ""
405
+ echo "Requirement ID: $REQ_ID"
406
+ echo "Type: $REQ_TYPE"
407
+ echo "Directory: $REQ_DIR"
408
+ if [[ -n "$TITLE" ]]; then
409
+ echo "Title: $TITLE"
410
+ fi
411
+ if [[ -n "$GIT_BRANCH" ]]; then
412
+ echo "Git Branch: $GIT_BRANCH"
413
+ fi
414
+ echo ""
415
+ echo "Next Steps:"
416
+ if [[ "$REQ_TYPE" == "bug" ]]; then
417
+ echo " 1. Run bug-analyzer agent to analyze the BUG"
418
+ echo " 2. Run /flow-fix to start BUG fix workflow"
419
+ echo " 3. Keep EXECUTION_LOG.md updated during fixes"
420
+ else
421
+ echo " 1. Add research materials to research/ (optional)"
422
+ echo " 2. Run prd-writer agent to create PRD.md"
423
+ echo " 3. Continue with planner and subsequent flow commands"
424
+ fi
425
+ echo ""
426
+ fi