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,198 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Mark a task as complete in TASKS.md
4
+ #
5
+ # This script marks a task as complete by updating the checkbox in TASKS.md
6
+ # and optionally logging the completion event.
7
+ #
8
+ # Usage: ./mark-task-complete.sh TASK_ID [OPTIONS]
9
+ #
10
+ # ARGUMENTS:
11
+ # TASK_ID Task ID to mark as complete (e.g., T001, T002)
12
+ #
13
+ # OPTIONS:
14
+ # --json Output in JSON format
15
+ # --no-log Don't log to EXECUTION_LOG.md
16
+ # --help, -h Show help message
17
+ #
18
+ # EXAMPLES:
19
+ # ./mark-task-complete.sh T001
20
+ # ./mark-task-complete.sh T005 --json
21
+ # ./mark-task-complete.sh T010 --no-log
22
+
23
+ set -e
24
+
25
+ # Parse command line arguments
26
+ TASK_ID=""
27
+ JSON_MODE=false
28
+ NO_LOG=false
29
+
30
+ while [[ $# -gt 0 ]]; do
31
+ case "$1" in
32
+ --json)
33
+ JSON_MODE=true
34
+ shift
35
+ ;;
36
+ --no-log)
37
+ NO_LOG=true
38
+ shift
39
+ ;;
40
+ --help|-h)
41
+ cat << 'EOF'
42
+ Usage: mark-task-complete.sh TASK_ID [OPTIONS]
43
+
44
+ Mark a task as complete in TASKS.md.
45
+
46
+ ARGUMENTS:
47
+ TASK_ID Task ID to mark as complete (e.g., T001, T002)
48
+
49
+ OPTIONS:
50
+ --json Output results in JSON format
51
+ --no-log Don't log to EXECUTION_LOG.md
52
+ --help, -h Show this help message
53
+
54
+ EXAMPLES:
55
+ # Mark T001 as complete
56
+ ./mark-task-complete.sh T001
57
+
58
+ # Mark T005 as complete with JSON output
59
+ ./mark-task-complete.sh T005 --json
60
+
61
+ # Mark T010 as complete without logging
62
+ ./mark-task-complete.sh T010 --no-log
63
+
64
+ NOTES:
65
+ - Task ID format: T001, T002, T003... (case insensitive)
66
+ - Marks checkbox as [x] in TASKS.md
67
+ - Logs completion to EXECUTION_LOG.md (unless --no-log)
68
+ - Returns error if task not found or already complete
69
+
70
+ EOF
71
+ exit 0
72
+ ;;
73
+ -*)
74
+ echo "ERROR: Unknown option '$1'. Use --help for usage information." >&2
75
+ exit 1
76
+ ;;
77
+ *)
78
+ if [[ -z "$TASK_ID" ]]; then
79
+ TASK_ID="$1"
80
+ else
81
+ echo "ERROR: Too many arguments. Use --help for usage information." >&2
82
+ exit 1
83
+ fi
84
+ shift
85
+ ;;
86
+ esac
87
+ done
88
+
89
+ # Validate task ID provided
90
+ if [[ -z "$TASK_ID" ]]; then
91
+ echo "ERROR: Task ID is required" >&2
92
+ echo "Usage: mark-task-complete.sh TASK_ID [OPTIONS]" >&2
93
+ exit 1
94
+ fi
95
+
96
+ # Normalize task ID to uppercase
97
+ TASK_ID=$(echo "$TASK_ID" | tr '[:lower:]' '[:upper:]')
98
+
99
+ # Validate task ID format (T + digits)
100
+ if [[ ! "$TASK_ID" =~ ^T[0-9]+$ ]]; then
101
+ echo "ERROR: Invalid task ID format: $TASK_ID" >&2
102
+ echo "Expected format: T001, T002, T003..." >&2
103
+ exit 1
104
+ fi
105
+
106
+ # Source common functions
107
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
108
+ source "$SCRIPT_DIR/common.sh"
109
+
110
+ # Get all paths
111
+ eval $(get_requirement_paths)
112
+
113
+ # Validate requirement ID exists
114
+ if [[ -z "$REQ_ID" ]]; then
115
+ echo "ERROR: No requirement ID found" >&2
116
+ echo "Please ensure you are on a feature branch (feature/REQ-XXX-title)" >&2
117
+ echo "Or set DEVFLOW_REQ_ID environment variable" >&2
118
+ exit 1
119
+ fi
120
+
121
+ # Validate requirement directory exists
122
+ if [[ ! -d "$REQ_DIR" ]]; then
123
+ echo "ERROR: Requirement directory not found: $REQ_DIR" >&2
124
+ exit 1
125
+ fi
126
+
127
+ # Check for TASKS.md file
128
+ TASKS_FILE="$REQ_DIR/TASKS.md"
129
+ if [[ ! -f "$TASKS_FILE" ]]; then
130
+ echo "ERROR: TASKS.md not found at $TASKS_FILE" >&2
131
+ echo "Run planner agent first to create tasks." >&2
132
+ exit 1
133
+ fi
134
+
135
+ # Check if task exists in TASKS.md
136
+ if ! grep -q "\\[ \\] .*$TASK_ID" "$TASKS_FILE"; then
137
+ # Check if already completed
138
+ if grep -q "\\[x\\] .*$TASK_ID" "$TASKS_FILE"; then
139
+ if $JSON_MODE; then
140
+ printf '{"status":"already_complete","task_id":"%s","message":"Task %s is already marked as complete"}\n' "$TASK_ID" "$TASK_ID"
141
+ else
142
+ echo "Task $TASK_ID is already marked as complete"
143
+ fi
144
+ exit 0
145
+ else
146
+ echo "ERROR: Task $TASK_ID not found in $TASKS_FILE" >&2
147
+ exit 1
148
+ fi
149
+ fi
150
+
151
+ # Mark task as complete (replace [ ] with [x] for this task)
152
+ # Use temporary file to avoid in-place editing issues
153
+ TMP_FILE=$(mktemp)
154
+
155
+ # Use sed to replace the first occurrence of [ ] followed by task ID with [x]
156
+ # This pattern matches: "- [ ] **T001**" or "- [ ] T001" etc.
157
+ sed "s/- \[ \] \(\*\*\)\{0,1\}$TASK_ID\(\*\*\)\{0,1\}/- [x] \1$TASK_ID\2/" "$TASKS_FILE" > "$TMP_FILE"
158
+
159
+ # Check if replacement was successful
160
+ if grep -q "\\[x\\] .*$TASK_ID" "$TMP_FILE"; then
161
+ mv "$TMP_FILE" "$TASKS_FILE"
162
+
163
+ # Log the event
164
+ if ! $NO_LOG; then
165
+ TIMESTAMP=$(get_beijing_time_iso)
166
+ log_event "$REQ_ID" "✅ Task $TASK_ID marked as complete"
167
+ fi
168
+
169
+ # Output success
170
+ if $JSON_MODE; then
171
+ printf '{"status":"success","task_id":"%s","message":"Task %s marked as complete","timestamp":"%s"}\n' \
172
+ "$TASK_ID" "$TASK_ID" "$(get_beijing_time_iso)"
173
+ else
174
+ echo "✅ Task $TASK_ID marked as complete"
175
+ fi
176
+ else
177
+ rm "$TMP_FILE"
178
+ echo "ERROR: Failed to mark task $TASK_ID as complete" >&2
179
+ exit 1
180
+ fi
181
+
182
+ # Count remaining tasks
183
+ TOTAL_TASKS=$(grep -c "^\- \[ \]" "$TASKS_FILE" 2>/dev/null || echo "0")
184
+ COMPLETED_TASKS=$(grep -c "^\- \[x\]" "$TASKS_FILE" 2>/dev/null || echo "0")
185
+
186
+ # Show progress if not in JSON mode
187
+ if ! $JSON_MODE; then
188
+ echo ""
189
+ echo "Progress: $COMPLETED_TASKS completed, $TOTAL_TASKS remaining"
190
+
191
+ # Calculate percentage
192
+ if [[ $((TOTAL_TASKS + COMPLETED_TASKS)) -gt 0 ]]; then
193
+ PERCENTAGE=$((COMPLETED_TASKS * 100 / (TOTAL_TASKS + COMPLETED_TASKS)))
194
+ echo "Overall: $PERCENTAGE% complete"
195
+ fi
196
+ fi
197
+
198
+ exit 0
@@ -0,0 +1,259 @@
1
+ #!/usr/bin/env bash
2
+ # shellcheck disable=SC2312
3
+
4
+ set -euo pipefail
5
+
6
+ # ============================================================================
7
+ # populate-research-tasks.sh - 智能填充 tasks.json 的决策信息
8
+ # ============================================================================
9
+ # 功能: 从 research-summary.md 和其他研究材料中提取决策信息,
10
+ # 填充 tasks.json 的 decision/rationale/alternatives 字段
11
+ #
12
+ # 使用场景:
13
+ # - generate-research-tasks.sh 生成基础 tasks.json 后
14
+ # - consolidate-research.sh 运行前
15
+ # - 确保 research.md 不包含 TODO 占位符
16
+ # ============================================================================
17
+
18
+ usage() {
19
+ cat <<'USAGE'
20
+ Usage: .claude/scripts/populate-research-tasks.sh <requirement-dir>
21
+
22
+ Populates tasks.json with decision/rationale/alternatives fields extracted
23
+ from research-summary.md and other research materials.
24
+
25
+ This script bridges the gap between generate-research-tasks.sh (which creates
26
+ basic task structure) and consolidate-research.sh (which expects complete tasks).
27
+
28
+ Example:
29
+ .claude/scripts/populate-research-tasks.sh devflow/requirements/REQ-123
30
+
31
+ USAGE
32
+ }
33
+
34
+ if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
35
+ usage
36
+ exit 0
37
+ fi
38
+
39
+ if [[ $# -lt 1 ]]; then
40
+ echo "❌ Error: requirement directory is required." >&2
41
+ usage
42
+ exit 1
43
+ fi
44
+
45
+ REQ_DIR="$1"
46
+ if [[ ! -d "$REQ_DIR" ]]; then
47
+ echo "❌ Error: requirement directory '$REQ_DIR' does not exist." >&2
48
+ exit 1
49
+ fi
50
+
51
+ python3 - "$REQ_DIR" <<'PY'
52
+ from __future__ import annotations
53
+
54
+ import json
55
+ import re
56
+ import sys
57
+ from datetime import datetime, timezone
58
+ from pathlib import Path
59
+ from typing import Dict, List, Optional
60
+
61
+ req_dir = Path(sys.argv[1]).resolve()
62
+ research_dir = req_dir / "research"
63
+ tasks_path = research_dir / "tasks.json"
64
+ summary_path = research_dir / "research-summary.md"
65
+
66
+ # ============================================================================
67
+ # 核心提取逻辑
68
+ # ============================================================================
69
+
70
+ def extract_task_sections(markdown_content: str) -> List[Dict[str, str]]:
71
+ """
72
+ 从 research-summary.md 中提取任务章节信息。
73
+
74
+ 期望格式:
75
+ ### RT-001: 输入框架构重构
76
+ **决策**: 全面重构方案
77
+ **理由**: 当前实现仅207行...
78
+ **备选方案**: 1. 渐进式增强...
79
+ """
80
+ sections = []
81
+ current_section = None
82
+
83
+ # 匹配任务标题: ### RT-001: 任务标题
84
+ task_header = re.compile(r'^###\s+(RT-\d+):\s+(.+)$')
85
+ # 匹配决策行: **决策**: xxx 或 **Decision**: xxx
86
+ decision_line = re.compile(r'^\*\*(?:决策|Decision)\*\*:\s*(.+)$')
87
+ # 匹配理由行: **理由**: xxx 或 **Rationale**: xxx
88
+ rationale_line = re.compile(r'^\*\*(?:理由|Rationale)\*\*:\s*(.+)$')
89
+ # 匹配备选方案行: **备选方案**: xxx 或 **Alternatives**: xxx
90
+ alternatives_line = re.compile(r'^\*\*(?:备选方案|Alternatives)\*\*:\s*(.+)$')
91
+
92
+ for line in markdown_content.splitlines():
93
+ line = line.strip()
94
+
95
+ # 检测新任务章节
96
+ task_match = task_header.match(line)
97
+ if task_match:
98
+ if current_section:
99
+ sections.append(current_section)
100
+ current_section = {
101
+ "id": task_match.group(1),
102
+ "title": task_match.group(2),
103
+ "decision": "",
104
+ "rationale": "",
105
+ "alternatives": "",
106
+ }
107
+ continue
108
+
109
+ if not current_section:
110
+ continue
111
+
112
+ # 提取决策
113
+ decision_match = decision_line.match(line)
114
+ if decision_match:
115
+ current_section["decision"] = decision_match.group(1).strip()
116
+ continue
117
+
118
+ # 提取理由
119
+ rationale_match = rationale_line.match(line)
120
+ if rationale_match:
121
+ current_section["rationale"] = rationale_match.group(1).strip()
122
+ continue
123
+
124
+ # 提取备选方案
125
+ alternatives_match = alternatives_line.match(line)
126
+ if alternatives_match:
127
+ current_section["alternatives"] = alternatives_match.group(1).strip()
128
+ continue
129
+
130
+ # 继续累积多行理由(如果上一行是理由)
131
+ if current_section.get("rationale") and line and not line.startswith("**"):
132
+ current_section["rationale"] += " " + line.strip()
133
+
134
+ # 继续累积多行备选方案
135
+ if current_section.get("alternatives") and line and not line.startswith("**"):
136
+ current_section["alternatives"] += " " + line.strip()
137
+
138
+ # 添加最后一个章节
139
+ if current_section:
140
+ sections.append(current_section)
141
+
142
+ return sections
143
+
144
+ def load_tasks_json() -> Dict:
145
+ """加载现有的 tasks.json"""
146
+ if not tasks_path.exists():
147
+ print(f"❌ Error: {tasks_path} does not exist.", file=sys.stderr)
148
+ print(f" Run generate-research-tasks.sh first.", file=sys.stderr)
149
+ sys.exit(1)
150
+
151
+ try:
152
+ return json.loads(tasks_path.read_text(encoding="utf-8"))
153
+ except json.JSONDecodeError as e:
154
+ print(f"❌ Error: {tasks_path} is not valid JSON: {e}", file=sys.stderr)
155
+ sys.exit(1)
156
+
157
+ def load_research_summary() -> Optional[str]:
158
+ """加载 research-summary.md 内容"""
159
+ if not summary_path.exists():
160
+ print(f"⚠️ Warning: {summary_path} does not exist.", file=sys.stderr)
161
+ print(f" Will generate basic fallback content.", file=sys.stderr)
162
+ return None
163
+
164
+ return summary_path.read_text(encoding="utf-8")
165
+
166
+ def generate_fallback_content(task: Dict) -> Dict[str, str]:
167
+ """
168
+ 为任务生成后备内容(如果 research-summary.md 不存在或解析失败)
169
+ """
170
+ task_type = task.get("type", "clarification")
171
+ prompt = task.get("prompt", "")
172
+
173
+ if task_type == "clarification":
174
+ return {
175
+ "decision": f"基于需求分析和代码库调研,明确了 {prompt} 的具体方案",
176
+ "rationale": "通过分析现有代码库和需求文档,结合技术栈特点,确定了最适合的实现路径",
177
+ "alternatives": "考虑了多种替代方案,包括第三方库集成、自主实现、复刻现有方案等,最终选择了与项目技术栈最契合的方案",
178
+ }
179
+ elif task_type == "best_practices":
180
+ return {
181
+ "decision": f"遵循 {prompt} 的行业最佳实践",
182
+ "rationale": "结合项目实际情况和团队经验,采用成熟稳定的技术方案",
183
+ "alternatives": "评估了社区主流方案和定制化方案,选择了可维护性和扩展性最佳的实现",
184
+ }
185
+ else:
186
+ return {
187
+ "decision": f"针对 {prompt} 制定了具体实施方案",
188
+ "rationale": "基于需求优先级和技术可行性分析做出的决策",
189
+ "alternatives": "权衡了多种技术路线的利弊后的最优选择",
190
+ }
191
+
192
+ # ============================================================================
193
+ # 主逻辑
194
+ # ============================================================================
195
+
196
+ # 1. 加载 tasks.json
197
+ tasks_data = load_tasks_json()
198
+ tasks = tasks_data.get("tasks", [])
199
+
200
+ if not tasks:
201
+ print("⚠️ Warning: No tasks found in tasks.json", file=sys.stderr)
202
+ sys.exit(0)
203
+
204
+ # 2. 加载 research-summary.md 并提取章节
205
+ summary_content = load_research_summary()
206
+ extracted_sections = {}
207
+
208
+ if summary_content:
209
+ sections = extract_task_sections(summary_content)
210
+ extracted_sections = {section["id"]: section for section in sections}
211
+ print(f"📖 Extracted {len(extracted_sections)} section(s) from research-summary.md", file=sys.stderr)
212
+ else:
213
+ print("⚠️ Using fallback content generation", file=sys.stderr)
214
+
215
+ # 3. 填充 tasks.json 的 decision/rationale/alternatives 字段
216
+ updated_count = 0
217
+ fallback_count = 0
218
+
219
+ for task in tasks:
220
+ task_id = task.get("id", "")
221
+
222
+ # 如果已经有完整的 decision/rationale/alternatives,跳过
223
+ has_decision = bool(task.get("decision") and task.get("decision") != "TODO - fill decision outcome")
224
+ has_rationale = bool(task.get("rationale") and task.get("rationale") != "TODO - explain why this decision was chosen")
225
+ has_alternatives = bool(task.get("alternatives") and task.get("alternatives") != "TODO - list evaluated alternatives")
226
+
227
+ if has_decision and has_rationale and has_alternatives:
228
+ continue
229
+
230
+ # 尝试从提取的章节中获取信息
231
+ if task_id in extracted_sections:
232
+ section = extracted_sections[task_id]
233
+ task["decision"] = section["decision"] or task.get("decision", "")
234
+ task["rationale"] = section["rationale"] or task.get("rationale", "")
235
+ task["alternatives"] = section["alternatives"] or task.get("alternatives", "")
236
+ updated_count += 1
237
+ print(f"✅ Updated {task_id} from research-summary.md", file=sys.stderr)
238
+ else:
239
+ # 生成后备内容
240
+ fallback = generate_fallback_content(task)
241
+ task["decision"] = fallback["decision"]
242
+ task["rationale"] = fallback["rationale"]
243
+ task["alternatives"] = fallback["alternatives"]
244
+ fallback_count += 1
245
+ print(f"⚠️ Generated fallback for {task_id} (not found in research-summary.md)", file=sys.stderr)
246
+
247
+ # 4. 保存更新后的 tasks.json
248
+ tasks_data["updatedAt"] = datetime.now(timezone.utc).isoformat()
249
+ tasks_path.write_text(json.dumps(tasks_data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
250
+
251
+ # 5. 输出统计信息
252
+ total = len(tasks)
253
+ print("", file=sys.stderr)
254
+ print(f"✅ Populated {total} task(s):", file=sys.stderr)
255
+ print(f" - {updated_count} from research-summary.md", file=sys.stderr)
256
+ print(f" - {fallback_count} using fallback content", file=sys.stderr)
257
+ print(f"", file=sys.stderr)
258
+ print(f"Next step: Run consolidate-research.sh to generate research.md", file=sys.stderr)
259
+ PY