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,397 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ============================================================================
4
+ * checklist-gate.js
5
+ * ============================================================================
6
+ * Epic Entry Gate Hook - Validates Checklist completion before Epic generation
7
+ *
8
+ * Usage: node checklist-gate.js [OPTIONS]
9
+ *
10
+ * OPTIONS:
11
+ * --req-id ID Requirement ID (e.g., REQ-002)
12
+ * --json Output in JSON format
13
+ * --skip Skip gate check
14
+ * --reason TEXT Reason for skipping (required with --skip)
15
+ *
16
+ * EXIT CODES:
17
+ * 0 - PASS or SKIPPED
18
+ * 1 - FAIL (completion below threshold)
19
+ * 2 - ERROR (configuration or file error)
20
+ *
21
+ * Reference: contracts/hook-interface.md, TECH_DESIGN.md Section 4.3
22
+ * ============================================================================
23
+ */
24
+
25
+ const fs = require('fs');
26
+ const path = require('path');
27
+ const { execSync } = require('child_process');
28
+
29
+ // ============================================================================
30
+ // Constants
31
+ // ============================================================================
32
+ const DEFAULT_THRESHOLD = 80;
33
+ const REPO_ROOT = findRepoRoot();
34
+
35
+ // ============================================================================
36
+ // Argument Parsing
37
+ // ============================================================================
38
+ function parseArgs() {
39
+ const args = process.argv.slice(2);
40
+ const options = {
41
+ reqId: null,
42
+ json: false,
43
+ skip: false,
44
+ reason: null
45
+ };
46
+
47
+ for (let i = 0; i < args.length; i++) {
48
+ switch (args[i]) {
49
+ case '--req-id':
50
+ options.reqId = args[++i];
51
+ break;
52
+ case '--json':
53
+ options.json = true;
54
+ break;
55
+ case '--skip':
56
+ options.skip = true;
57
+ break;
58
+ case '--reason':
59
+ options.reason = args[++i];
60
+ break;
61
+ case '--help':
62
+ case '-h':
63
+ printHelp();
64
+ process.exit(0);
65
+ }
66
+ }
67
+
68
+ return options;
69
+ }
70
+
71
+ function printHelp() {
72
+ console.log(`
73
+ Usage: node checklist-gate.js [OPTIONS]
74
+
75
+ OPTIONS:
76
+ --req-id ID Requirement ID (e.g., REQ-002)
77
+ --json Output in JSON format
78
+ --skip Skip gate check
79
+ --reason TEXT Reason for skipping (required with --skip)
80
+ --help, -h Show this help message
81
+
82
+ EXAMPLES:
83
+ node checklist-gate.js --req-id REQ-002 --json
84
+ node checklist-gate.js --req-id REQ-002 --skip --reason "Emergency release"
85
+ `);
86
+ }
87
+
88
+ // ============================================================================
89
+ // Helper Functions
90
+ // ============================================================================
91
+ function findRepoRoot() {
92
+ try {
93
+ return execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim();
94
+ } catch {
95
+ return process.cwd();
96
+ }
97
+ }
98
+
99
+ function getReqIdFromEnv() {
100
+ // Try environment variable
101
+ if (process.env.DEVFLOW_REQ_ID) {
102
+ return process.env.DEVFLOW_REQ_ID;
103
+ }
104
+ // Try git branch
105
+ try {
106
+ const branch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim();
107
+ const match = branch.match(/(REQ-[0-9]+)/);
108
+ if (match) return match[1];
109
+ } catch {}
110
+ return null;
111
+ }
112
+
113
+ function loadConfig() {
114
+ const configPath = path.join(REPO_ROOT, 'config', 'quality-rules.yml');
115
+ try {
116
+ if (!fs.existsSync(configPath)) {
117
+ return { threshold: DEFAULT_THRESHOLD, requireReason: true };
118
+ }
119
+ // Simple YAML parsing for threshold
120
+ const content = fs.readFileSync(configPath, 'utf-8');
121
+ const thresholdMatch = content.match(/threshold:\s*(\d+)/);
122
+ const requireReasonMatch = content.match(/require_reason:\s*(true|false)/);
123
+ return {
124
+ threshold: thresholdMatch ? parseInt(thresholdMatch[1]) : DEFAULT_THRESHOLD,
125
+ requireReason: requireReasonMatch ? requireReasonMatch[1] === 'true' : true
126
+ };
127
+ } catch (err) {
128
+ return { threshold: DEFAULT_THRESHOLD, requireReason: true };
129
+ }
130
+ }
131
+
132
+ function getBeijingTime() {
133
+ const now = new Date();
134
+ const beijingOffset = 8 * 60;
135
+ const utcOffset = now.getTimezoneOffset();
136
+ const beijingTime = new Date(now.getTime() + (beijingOffset + utcOffset) * 60 * 1000);
137
+ return beijingTime.toISOString().replace('T', ' ').substring(0, 19);
138
+ }
139
+
140
+ // ============================================================================
141
+ // Checklist Calculation
142
+ // ============================================================================
143
+ function calculateCompletion(checklistsDir) {
144
+ if (!fs.existsSync(checklistsDir)) {
145
+ return { error: 'NO_CHECKLISTS', message: 'Checklists directory not found' };
146
+ }
147
+
148
+ const files = fs.readdirSync(checklistsDir).filter(f => f.endsWith('.md'));
149
+ if (files.length === 0) {
150
+ return { error: 'NO_CHECKLISTS', message: 'No checklist files found' };
151
+ }
152
+
153
+ let totalItems = 0;
154
+ let checkedItems = 0;
155
+ const checklists = [];
156
+
157
+ for (const file of files) {
158
+ const filePath = path.join(checklistsDir, file);
159
+ const content = fs.readFileSync(filePath, 'utf-8');
160
+
161
+ // Count all checkbox items (- [ ] or - [x] or - [X])
162
+ const totalMatches = content.match(/^\s*- \[[ xX]\]/gm) || [];
163
+ const checkedMatches = content.match(/^\s*- \[[xX]\]/gm) || [];
164
+
165
+ const fileTotal = totalMatches.length;
166
+ const fileChecked = checkedMatches.length;
167
+ const filePercentage = fileTotal > 0 ? Math.round((fileChecked / fileTotal) * 100) : 0;
168
+
169
+ totalItems += fileTotal;
170
+ checkedItems += fileChecked;
171
+
172
+ checklists.push({
173
+ file: file,
174
+ total: fileTotal,
175
+ checked: fileChecked,
176
+ percentage: filePercentage
177
+ });
178
+ }
179
+
180
+ const overallPercentage = totalItems > 0 ? Math.round((checkedItems / totalItems) * 100) : 0;
181
+
182
+ return {
183
+ total: totalItems,
184
+ checked: checkedItems,
185
+ percentage: overallPercentage,
186
+ checklists: checklists
187
+ };
188
+ }
189
+
190
+ // ============================================================================
191
+ // Status Update
192
+ // ============================================================================
193
+ function updateOrchestrationStatus(reqDir, completion, skip, reason) {
194
+ const statusPath = path.join(reqDir, 'orchestration_status.json');
195
+ try {
196
+ const status = JSON.parse(fs.readFileSync(statusPath, 'utf-8'));
197
+
198
+ if (!status.checklist) {
199
+ status.checklist = {};
200
+ }
201
+
202
+ status.checklist.total_items = completion.total;
203
+ status.checklist.checked_items = completion.checked;
204
+ status.checklist.completion_percentage = completion.percentage;
205
+ status.checklist.gate_passed = !skip && completion.percentage >= loadConfig().threshold;
206
+ status.checklist.gate_skipped = skip;
207
+ status.checklist.skip_reason = reason || null;
208
+ status.checklist.last_check_at = new Date().toISOString().replace('Z', '+08:00');
209
+
210
+ fs.writeFileSync(statusPath, JSON.stringify(status, null, 2) + '\n');
211
+ } catch (err) {
212
+ // Silently fail - status update is not critical
213
+ }
214
+ }
215
+
216
+ // ============================================================================
217
+ // Audit Logging
218
+ // ============================================================================
219
+ function logGateSkip(reqDir, completion, threshold, reason) {
220
+ const logPath = path.join(reqDir, 'EXECUTION_LOG.md');
221
+ const timestamp = getBeijingTime();
222
+ const weekday = ['日', '一', '二', '三', '四', '五', '六'][new Date().getDay()];
223
+
224
+ const logEntry = `
225
+ ### ${timestamp} (周${weekday})
226
+ **Event**: Gate Skipped
227
+ **Actor**: user
228
+ **Completion**: ${completion.percentage}%
229
+ **Threshold**: ${threshold}%
230
+ **Reason**: ${reason}
231
+ **Command**: /flow-epic --skip-gate --reason "${reason}"
232
+ `;
233
+
234
+ try {
235
+ fs.appendFileSync(logPath, logEntry);
236
+ } catch (err) {
237
+ // Silently fail - audit log is not critical for gate decision
238
+ }
239
+ }
240
+
241
+ // ============================================================================
242
+ // Output Functions
243
+ // ============================================================================
244
+ function outputJson(result) {
245
+ console.log(JSON.stringify(result, null, 2));
246
+ }
247
+
248
+ function outputText(result) {
249
+ const { status, completion, threshold } = result;
250
+
251
+ if (status === 'NO_CHECKLISTS') {
252
+ console.log('❌ Checklist Gate: NO_CHECKLISTS');
253
+ console.log(' No checklist files found.');
254
+ console.log('');
255
+ console.log(' Run /flow-checklist --type <type> first.');
256
+ return;
257
+ }
258
+
259
+ const icon = status === 'PASS' ? '✅' : status === 'SKIPPED' ? '⚠️' : '❌';
260
+ console.log(`${icon} Checklist Gate: ${status}`);
261
+ console.log(` Completion: ${completion.percentage}% (${completion.checked}/${completion.total})`);
262
+ console.log(` Threshold: ${threshold}%`);
263
+ console.log('');
264
+
265
+ if (result.details && result.details.checklists) {
266
+ console.log(' Details:');
267
+ for (const cl of result.details.checklists) {
268
+ console.log(` - ${cl.file}: ${cl.percentage}% (${cl.checked}/${cl.total})`);
269
+ }
270
+ }
271
+
272
+ if (status === 'FAIL') {
273
+ console.log('');
274
+ console.log(' To continue:');
275
+ console.log(' 1. Review and complete checklist items');
276
+ console.log(' 2. Run /flow-checklist --status to check progress');
277
+ console.log(' 3. Or use --skip-gate --reason "your reason" to bypass');
278
+ }
279
+
280
+ if (status === 'SKIPPED') {
281
+ console.log('');
282
+ console.log(` Reason: ${result.skip_reason}`);
283
+ console.log(' ⚠️ Audit logged to EXECUTION_LOG.md');
284
+ }
285
+ }
286
+
287
+ // ============================================================================
288
+ // Main
289
+ // ============================================================================
290
+ function main() {
291
+ const options = parseArgs();
292
+
293
+ // Get requirement ID
294
+ const reqId = options.reqId || getReqIdFromEnv();
295
+ if (!reqId) {
296
+ const result = { status: 'ERROR', error: 'NO_REQ_ID', message: 'Could not determine requirement ID' };
297
+ if (options.json) {
298
+ outputJson(result);
299
+ } else {
300
+ console.error('ERROR: NO_REQ_ID - Could not determine requirement ID');
301
+ console.error('Use --req-id REQ-XXX or set DEVFLOW_REQ_ID environment variable');
302
+ }
303
+ process.exit(2);
304
+ }
305
+
306
+ // Validate skip with reason
307
+ if (options.skip && !options.reason) {
308
+ const result = { status: 'ERROR', error: 'SKIP_REASON_REQUIRED', message: '--reason is required when using --skip' };
309
+ if (options.json) {
310
+ outputJson(result);
311
+ } else {
312
+ console.error('ERROR: SKIP_REASON_REQUIRED');
313
+ console.error('--reason is required when using --skip');
314
+ }
315
+ process.exit(2);
316
+ }
317
+
318
+ // Load configuration
319
+ const config = loadConfig();
320
+ const threshold = config.threshold;
321
+
322
+ // Get checklists directory
323
+ const reqDir = path.join(REPO_ROOT, 'devflow', 'requirements', reqId);
324
+ const checklistsDir = path.join(reqDir, 'checklists');
325
+
326
+ // Calculate completion
327
+ const completion = calculateCompletion(checklistsDir);
328
+
329
+ // Handle NO_CHECKLISTS error
330
+ if (completion.error) {
331
+ const result = {
332
+ status: 'NO_CHECKLISTS',
333
+ message: completion.message
334
+ };
335
+ if (options.json) {
336
+ outputJson(result);
337
+ } else {
338
+ outputText(result);
339
+ }
340
+ process.exit(1);
341
+ }
342
+
343
+ // Handle skip
344
+ if (options.skip) {
345
+ logGateSkip(reqDir, completion, threshold, options.reason);
346
+ updateOrchestrationStatus(reqDir, completion, true, options.reason);
347
+
348
+ const result = {
349
+ status: 'SKIPPED',
350
+ completion: completion.percentage,
351
+ threshold: threshold,
352
+ skip_reason: options.reason,
353
+ audit_logged: true,
354
+ message: `Gate skipped with reason: ${options.reason}`,
355
+ details: {
356
+ total_items: completion.total,
357
+ checked_items: completion.checked,
358
+ checklists: completion.checklists
359
+ }
360
+ };
361
+
362
+ if (options.json) {
363
+ outputJson(result);
364
+ } else {
365
+ outputText(result);
366
+ }
367
+ process.exit(0);
368
+ }
369
+
370
+ // Check gate
371
+ const passed = completion.percentage >= threshold;
372
+ updateOrchestrationStatus(reqDir, completion, false, null);
373
+
374
+ const result = {
375
+ status: passed ? 'PASS' : 'FAIL',
376
+ completion: completion.percentage,
377
+ threshold: threshold,
378
+ details: {
379
+ total_items: completion.total,
380
+ checked_items: completion.checked,
381
+ checklists: completion.checklists
382
+ },
383
+ message: passed
384
+ ? `Checklist completion ${completion.percentage}% >= ${threshold}% threshold`
385
+ : `Checklist completion ${completion.percentage}% < ${threshold}% threshold. Run /flow-checklist --status to review.`
386
+ };
387
+
388
+ if (options.json) {
389
+ outputJson(result);
390
+ } else {
391
+ outputText(result);
392
+ }
393
+
394
+ process.exit(passed ? 0 : 1);
395
+ }
396
+
397
+ main();
@@ -0,0 +1,12 @@
1
+ #!/bin/bash
2
+
3
+ # Skip if environment variable is set
4
+ if [ -n "$SKIP_ERROR_REMINDER" ]; then
5
+ exit 0
6
+ fi
7
+
8
+ # Get the directory of this script
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ cd "$SCRIPT_DIR"
11
+
12
+ cat | npx tsx error-handling-reminder.ts