@curdx/flow 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/CHANGELOG.md +21 -87
  2. package/LICENSE +1 -1
  3. package/README.md +28 -129
  4. package/dist/index.mjs +995 -0
  5. package/package.json +33 -44
  6. package/.claude-plugin/marketplace.json +0 -48
  7. package/.claude-plugin/plugin.json +0 -52
  8. package/agent-preamble/preamble.md +0 -314
  9. package/agents/flow-adversary.md +0 -203
  10. package/agents/flow-architect.md +0 -198
  11. package/agents/flow-brownfield-analyst.md +0 -143
  12. package/agents/flow-debugger.md +0 -321
  13. package/agents/flow-edge-hunter.md +0 -289
  14. package/agents/flow-executor.md +0 -269
  15. package/agents/flow-orchestrator.md +0 -145
  16. package/agents/flow-planner.md +0 -247
  17. package/agents/flow-product-designer.md +0 -159
  18. package/agents/flow-qa-engineer.md +0 -282
  19. package/agents/flow-researcher.md +0 -166
  20. package/agents/flow-reviewer.md +0 -304
  21. package/agents/flow-security-auditor.md +0 -401
  22. package/agents/flow-triage-analyst.md +0 -272
  23. package/agents/flow-ui-researcher.md +0 -230
  24. package/agents/flow-ux-designer.md +0 -221
  25. package/agents/flow-verifier.md +0 -350
  26. package/bin/curdx-flow +0 -5
  27. package/bin/curdx-flow-state +0 -104
  28. package/bin/curdx-flow.js +0 -54
  29. package/cli/README.md +0 -104
  30. package/cli/doctor-workflow.js +0 -483
  31. package/cli/doctor.js +0 -73
  32. package/cli/help.js +0 -59
  33. package/cli/install-bundled-mcps.js +0 -37
  34. package/cli/install-companions.js +0 -19
  35. package/cli/install-context7-config.js +0 -80
  36. package/cli/install-curdx-plugin.js +0 -96
  37. package/cli/install-language.js +0 -35
  38. package/cli/install-next-steps.js +0 -29
  39. package/cli/install-options.js +0 -9
  40. package/cli/install-paths.js +0 -52
  41. package/cli/install-recommended-plugins.js +0 -104
  42. package/cli/install-required-plugins.js +0 -57
  43. package/cli/install-self-update.js +0 -62
  44. package/cli/install-workflow.js +0 -209
  45. package/cli/install.js +0 -101
  46. package/cli/lib/claude-commands.js +0 -41
  47. package/cli/lib/claude-ops.js +0 -47
  48. package/cli/lib/claude.js +0 -183
  49. package/cli/lib/config.js +0 -24
  50. package/cli/lib/doctor-claude-settings.js +0 -1186
  51. package/cli/lib/doctor-report.js +0 -978
  52. package/cli/lib/doctor-runtime-environment.js +0 -196
  53. package/cli/lib/frontmatter.js +0 -44
  54. package/cli/lib/json-schema.js +0 -57
  55. package/cli/lib/logging.js +0 -25
  56. package/cli/lib/process.js +0 -60
  57. package/cli/lib/prompts.js +0 -135
  58. package/cli/lib/runtime.js +0 -107
  59. package/cli/lib/semver.js +0 -109
  60. package/cli/lib/version.js +0 -12
  61. package/cli/protocols-body.md +0 -22
  62. package/cli/protocols.js +0 -162
  63. package/cli/registry.js +0 -123
  64. package/cli/router.js +0 -49
  65. package/cli/uninstall-actions.js +0 -360
  66. package/cli/uninstall-workflow.js +0 -146
  67. package/cli/uninstall.js +0 -42
  68. package/cli/upgrade-workflow.js +0 -80
  69. package/cli/upgrade.js +0 -91
  70. package/cli/utils.js +0 -40
  71. package/gates/adversarial-review-gate.md +0 -219
  72. package/gates/coverage-audit-gate.md +0 -182
  73. package/gates/devex-gate.md +0 -254
  74. package/gates/edge-case-gate.md +0 -194
  75. package/gates/karpathy-gate.md +0 -130
  76. package/gates/security-gate.md +0 -218
  77. package/gates/tdd-gate.md +0 -182
  78. package/gates/test-quality-gate.md +0 -59
  79. package/gates/verification-gate.md +0 -179
  80. package/hooks/hooks.json +0 -130
  81. package/hooks/scripts/common.sh +0 -237
  82. package/hooks/scripts/config-change-guard.sh +0 -94
  83. package/hooks/scripts/flow-context-watch.sh +0 -94
  84. package/hooks/scripts/inject-karpathy.sh +0 -53
  85. package/hooks/scripts/quick-mode-guard.sh +0 -69
  86. package/hooks/scripts/session-start.sh +0 -94
  87. package/hooks/scripts/session-title.sh +0 -87
  88. package/hooks/scripts/stop-watcher.sh +0 -231
  89. package/hooks/scripts/subagent-artifact-guard.sh +0 -92
  90. package/hooks/scripts/subagent-statusline.sh +0 -111
  91. package/hooks/scripts/task-lifecycle-guard.sh +0 -106
  92. package/hooks/scripts/teammate-idle-guard.sh +0 -83
  93. package/knowledge/artifact-output-discipline.md +0 -24
  94. package/knowledge/artifact-summary-contracts.md +0 -50
  95. package/knowledge/atomic-commits.md +0 -262
  96. package/knowledge/claude-code-runtime-contracts.md +0 -240
  97. package/knowledge/epic-decomposition.md +0 -307
  98. package/knowledge/execution-strategies.md +0 -303
  99. package/knowledge/karpathy-guidelines.md +0 -219
  100. package/knowledge/planning-reviews.md +0 -211
  101. package/knowledge/poc-first-workflow.md +0 -223
  102. package/knowledge/review-feedback-intake.md +0 -57
  103. package/knowledge/spec-driven-development.md +0 -180
  104. package/knowledge/systematic-debugging.md +0 -378
  105. package/knowledge/two-stage-review.md +0 -249
  106. package/knowledge/wave-execution.md +0 -403
  107. package/monitors/monitors.json +0 -8
  108. package/monitors/scripts/flow-state-monitor.sh +0 -102
  109. package/output-styles/curdx-evidence-first.md +0 -34
  110. package/output-styles/curdx-fast-mode.md +0 -42
  111. package/output-styles/curdx-spec-mode.md +0 -46
  112. package/schemas/agent-frontmatter.schema.json +0 -66
  113. package/schemas/config.schema.json +0 -134
  114. package/schemas/gate-frontmatter.schema.json +0 -30
  115. package/schemas/hooks.schema.json +0 -115
  116. package/schemas/output-style-frontmatter.schema.json +0 -22
  117. package/schemas/plugin-manifest.schema.json +0 -436
  118. package/schemas/plugin-settings.schema.json +0 -29
  119. package/schemas/skill-frontmatter.schema.json +0 -177
  120. package/schemas/spec-frontmatter.schema.json +0 -42
  121. package/schemas/spec-state.schema.json +0 -165
  122. package/settings.json +0 -8
  123. package/skills/brownfield-index/SKILL.md +0 -53
  124. package/skills/brownfield-index/references/applicability.md +0 -12
  125. package/skills/brownfield-index/references/handoff.md +0 -8
  126. package/skills/brownfield-index/references/index-contract.md +0 -10
  127. package/skills/browser-qa/SKILL.md +0 -39
  128. package/skills/browser-qa/references/handoff.md +0 -6
  129. package/skills/browser-qa/references/prerequisites.md +0 -10
  130. package/skills/browser-qa/references/qa-contract.md +0 -20
  131. package/skills/cancel/SKILL.md +0 -41
  132. package/skills/cancel/references/destructive-mode.md +0 -17
  133. package/skills/cancel/references/reporting.md +0 -18
  134. package/skills/cancel/references/state-recovery.md +0 -30
  135. package/skills/cancel/references/target-resolution.md +0 -7
  136. package/skills/debug/SKILL.md +0 -45
  137. package/skills/debug/references/context-gathering.md +0 -11
  138. package/skills/debug/references/failure-guard.md +0 -25
  139. package/skills/debug/references/intake.md +0 -12
  140. package/skills/debug/references/phase-workflow.md +0 -34
  141. package/skills/debug/references/reporting.md +0 -20
  142. package/skills/epic/SKILL.md +0 -39
  143. package/skills/epic/references/epic-artifacts.md +0 -20
  144. package/skills/epic/references/epic-intake.md +0 -9
  145. package/skills/epic/references/slice-handoff.md +0 -16
  146. package/skills/fast/SKILL.md +0 -62
  147. package/skills/fast/references/applicability.md +0 -25
  148. package/skills/fast/references/clarification.md +0 -20
  149. package/skills/fast/references/execution-contract.md +0 -56
  150. package/skills/help/SKILL.md +0 -55
  151. package/skills/help/references/dispatch.md +0 -20
  152. package/skills/help/references/overview.md +0 -39
  153. package/skills/help/references/troubleshoot.md +0 -47
  154. package/skills/help/references/workflow.md +0 -37
  155. package/skills/implement/SKILL.md +0 -104
  156. package/skills/implement/references/error-recovery.md +0 -36
  157. package/skills/implement/references/linear-execution.md +0 -43
  158. package/skills/implement/references/native-task-sync.md +0 -107
  159. package/skills/implement/references/preflight.md +0 -43
  160. package/skills/implement/references/progress-contract.md +0 -36
  161. package/skills/implement/references/state-init.md +0 -36
  162. package/skills/implement/references/stop-hook-execution.md +0 -50
  163. package/skills/implement/references/strategy-router.md +0 -38
  164. package/skills/implement/references/subagent-execution.md +0 -57
  165. package/skills/implement/references/wave-execution.md +0 -180
  166. package/skills/init/SKILL.md +0 -49
  167. package/skills/init/references/gitignore-and-health.md +0 -26
  168. package/skills/init/references/next-steps.md +0 -22
  169. package/skills/init/references/preflight.md +0 -15
  170. package/skills/init/references/scaffold-contract.md +0 -27
  171. package/skills/review/SKILL.md +0 -82
  172. package/skills/review/references/optional-passes.md +0 -48
  173. package/skills/review/references/preflight.md +0 -38
  174. package/skills/review/references/report-contract.md +0 -49
  175. package/skills/review/references/reporting.md +0 -20
  176. package/skills/review/references/stage-execution.md +0 -32
  177. package/skills/security-audit/SKILL.md +0 -47
  178. package/skills/security-audit/references/audit-contract.md +0 -21
  179. package/skills/security-audit/references/gate-handoff.md +0 -8
  180. package/skills/security-audit/references/scope-and-depth.md +0 -9
  181. package/skills/spec/SKILL.md +0 -100
  182. package/skills/spec/references/artifact-landing.md +0 -31
  183. package/skills/spec/references/phase-execution.md +0 -50
  184. package/skills/spec/references/planning-review.md +0 -31
  185. package/skills/spec/references/preflight-and-routing.md +0 -46
  186. package/skills/spec/references/reporting.md +0 -21
  187. package/skills/start/SKILL.md +0 -84
  188. package/skills/start/references/branch-routing.md +0 -51
  189. package/skills/start/references/mode-semantics.md +0 -12
  190. package/skills/start/references/preflight.md +0 -13
  191. package/skills/start/references/reporting.md +0 -20
  192. package/skills/start/references/state-seeding.md +0 -44
  193. package/skills/start/references/workflow-handoff.md +0 -26
  194. package/skills/status/SKILL.md +0 -41
  195. package/skills/status/references/gather-contract.md +0 -30
  196. package/skills/status/references/health-rules.md +0 -27
  197. package/skills/status/references/output-contract.md +0 -25
  198. package/skills/status/references/preflight.md +0 -10
  199. package/skills/status/references/recovery-hints.md +0 -18
  200. package/skills/ui-sketch/SKILL.md +0 -39
  201. package/skills/ui-sketch/references/brief-intake.md +0 -10
  202. package/skills/ui-sketch/references/iteration-handoff.md +0 -5
  203. package/skills/ui-sketch/references/variant-contract.md +0 -15
  204. package/skills/verify/SKILL.md +0 -56
  205. package/skills/verify/references/evidence-workflow.md +0 -39
  206. package/skills/verify/references/output-contract.md +0 -23
  207. package/skills/verify/references/preflight.md +0 -11
  208. package/skills/verify/references/report-handoff.md +0 -35
  209. package/skills/verify/references/strict-mode.md +0 -12
  210. package/templates/CONTEXT.md.tmpl +0 -53
  211. package/templates/PROJECT.md.tmpl +0 -59
  212. package/templates/ROADMAP.md.tmpl +0 -50
  213. package/templates/STATE.md.tmpl +0 -49
  214. package/templates/config.json.tmpl +0 -51
  215. package/templates/design.md.tmpl +0 -83
  216. package/templates/progress.md.tmpl +0 -77
  217. package/templates/requirements.md.tmpl +0 -76
  218. package/templates/research.md.tmpl +0 -83
  219. package/templates/tasks.md.tmpl +0 -107
@@ -1,59 +0,0 @@
1
- ---
2
- gate: test-quality-gate
3
- category: standard-mode
4
- severity: blocking
5
- depends_on: []
6
- ---
7
-
8
- # Test Quality Gate
9
-
10
- A green test suite is not enough. Tests must exercise real behavior and fail for the right reason.
11
-
12
- ## Blocking Findings
13
-
14
- Flag as blocking when a test is the only evidence for an FR/AC and any of these hold:
15
-
16
- 1. **Mock-only behavior**
17
- - Assertions only check mock calls (`toHaveBeenCalled`, `calledWith`, spy counts).
18
- - The real module/function under test is never invoked.
19
- - The test would still pass if the production implementation were empty.
20
-
21
- 2. **Mock setup dominates evidence**
22
- - Mock/stub/spy setup lines are more than 3x real behavioral assertions.
23
- - The test mostly restates fixture wiring instead of asserting output, state, persistence, or user-visible behavior.
24
-
25
- 3. **Skipped or inert tests**
26
- - `it.skip`, `describe.skip`, `test.skip`, `xit`, `pending`, or equivalent on covered behavior.
27
- - Test has no assertions and no meaningful side-effect check.
28
-
29
- 4. **Implementation-biased regression**
30
- - Test was added after implementation without evidence of RED failure when the task claims TDD.
31
- - Test asserts internal private structure instead of externally observable behavior.
32
-
33
- 5. **Missing cleanup for stateful mocks**
34
- - Stateful mocks/spies are used across tests without `afterEach` cleanup (`restoreAllMocks`, `clearAllMocks`, sandbox restore, etc.).
35
- - Shared mock state can leak between tests.
36
-
37
- ## Acceptable Mock Usage
38
-
39
- Mocks are acceptable when they isolate a boundary and the assertion still verifies real behavior:
40
-
41
- - Network/payment/email provider mocked, but service logic and error handling are real.
42
- - Clock/randomness mocked to make deterministic assertions.
43
- - Database mocked only when a separate integration test covers persistence behavior.
44
-
45
- ## Evidence Checklist
46
-
47
- For each FR/AC test evidence, record:
48
-
49
- - Test file and test name.
50
- - What real code path is invoked.
51
- - What behavioral assertion proves the requirement.
52
- - Whether the test was observed RED before GREEN when TDD is claimed.
53
- - Whether mocks are boundary-only or behavior-replacing.
54
-
55
- ## Verdicts
56
-
57
- - `PASS`: Tests exercise real behavior with meaningful assertions.
58
- - `WARN`: Mock-heavy but supported by separate integration/e2e coverage.
59
- - `FAIL`: Mock-only/skipped/no-assertion test is used as primary evidence.
@@ -1,179 +0,0 @@
1
- ---
2
- gate: verification-gate
3
- category: always-on
4
- severity: blocking
5
- depends_on: []
6
- ---
7
-
8
- # Verification Gate — Verification Required Before Completion
9
-
10
- > **Always enabled**. No evidence = no completion. Verification must be based on observed proof, not claimed completion.
11
-
12
- ---
13
-
14
- ## Core Rule
15
-
16
- **Do not declare `done`, `fixed`, `passed`, `working`, `okay` unless there is fresh execution evidence.**
17
-
18
- ---
19
-
20
- ## Trigger Timing
21
-
22
- - Before any agent outputs a "done/fixed/passed" conclusion
23
- - Before commit messages contain forbidden words
24
- - Before Phase transitions (research → requirements, requirements → design, etc.)
25
-
26
- ---
27
-
28
- ## Forbidden Word List (English + Chinese)
29
-
30
- Fresh evidence required to use:
31
-
32
- **English**:
33
- - `done`, `fixed`, `working`, `passed`, `resolved`, `completed`
34
- - `should work`, `probably`, `likely`, `might work`
35
- - `seems to`, `appears to`, `looks good`, `looks right`
36
- - `great!`, `perfect!`, `all set`
37
-
38
- **Chinese**:
39
- - `完成`, `搞定`, `好了`, `可以了`, `修好了`
40
- - `应该`, `可能`, `大概`, `似乎`, `好像`
41
- - `看起来没问题`, `应该能工作`
42
-
43
- ---
44
-
45
- ## Allowed Conclusions Must Carry Evidence
46
-
47
- ✗ **Violation**:
48
- > I fixed the login bug
49
-
50
- ✓ **Compliant**:
51
- > I fixed the login bug. Re-running `npm test -- auth/login` produced:
52
- > ```
53
- > ✓ login endpoint rejects empty email
54
- > ✓ login endpoint accepts valid credentials
55
- > Test Suites: 1 passed, Tests: 2 passed
56
- > ```
57
-
58
- ✗ **Violation**:
59
- > The code looks fine
60
-
61
- ✓ **Compliant**:
62
- > Ran `npx tsc --noEmit` → 0 errors
63
- > Ran `npx eslint src/auth/` → 0 errors, 0 warnings
64
-
65
- ---
66
-
67
- ## Evidence Types
68
-
69
- | Claim | Required Evidence |
70
- |------|---------|
71
- | "Fixed X" | command reproducing X + execution output |
72
- | "Tests pass" | full `npm test` output including pass count |
73
- | "Code is valid" | `tsc --noEmit` exit code + output |
74
- | "API works" | `curl` response + status code |
75
- | "Deployment succeeded" | deployment log + health check response |
76
- | "User can log in" | browser / chrome-devtools test screenshot or log |
77
- | "Performance meets target" | benchmark command + numbers |
78
-
79
- ---
80
-
81
- ## Checking Methods
82
-
83
- ### Agent Built-in (self-check)
84
-
85
- Each agent runs an internal check before outputting:
86
-
87
- ```
88
- For each conclusion sentence, ask yourself:
89
- 1. Does this sentence contain a forbidden word?
90
- 2. If so, do I have fresh evidence supporting it?
91
- 3. Is the evidence from a just-executed command, or older / assumed?
92
- 4. If the evidence is not fresh or does not exist, re-run or delete this sentence.
93
- ```
94
-
95
- ### flow-reviewer Agent (external check)
96
-
97
- Scan:
98
- - `commit messages` for forbidden words
99
- - declarative sentences in `.progress.md`
100
- - the conclusion section of agent output
101
-
102
- ---
103
-
104
- ## Violation Handling
105
-
106
- ### Severe (block)
107
-
108
- - commit message contains forbidden word without evidence
109
- - `.progress.md` says "done" but has no verify output
110
-
111
- **Actions**:
112
- - Block the commit (pre-commit hook, Phase 4+)
113
- - Or dispatch flow-executor to re-run Verify and update the record
114
- - Rewrite the commit message
115
-
116
- ### Medium (warning)
117
-
118
- - Verbally saying "looks good" (not in commit or file)
119
- - Using "should" as a hypothetical statement (acceptable)
120
-
121
- **Action**: mark, non-blocking
122
-
123
- ---
124
-
125
- ## Special Cases
126
-
127
- ### "I already checked"
128
-
129
- Not enough. "Checked" is a subjective claim. You need **execution output**.
130
-
131
- ```
132
- ✗ "I checked that all tests pass"
133
- ✓ "Ran npm test: Test Suites: 5 passed, Tests: 47 passed, Snapshots: 0 total"
134
- ```
135
-
136
- ### Partial Completion
137
-
138
- Do not describe partial completion as complete. Clearly categorize:
139
-
140
- ```
141
- ✓ Completed:
142
- - FR-01 login endpoint: passed (test output)
143
- - FR-02 password encryption: passed (test output)
144
-
145
- ⚠ Partially completed:
146
- - FR-03 Token refresh: code written but tests not yet run
147
-
148
- ✗ Not started:
149
- - FR-04 Logout
150
- ```
151
-
152
- ---
153
-
154
- ## Output Format
155
-
156
- ```markdown
157
- ## Verification Gate Check Result
158
-
159
- Scan range: commit abc123..def456
160
- Statements containing forbidden words: 3
161
-
162
- [V1] "Login bug fixed" (commit abc123)
163
- Evidence: ✗ none (no corresponding test output or verify record found)
164
- Verdict: block
165
-
166
- [V2] "All tests pass" (.progress.md line 12)
167
- Evidence: ✓ "npm test: 47/47 passed" (same file, line 11)
168
- Verdict: compliant
169
-
170
- [V3] "Should handle concurrency" (design.md AD-05)
171
- Evidence: ⚠ "should" is hypothetical tone, acceptable
172
- Verdict: warning (recommend adding a spike to verify)
173
-
174
- Blockers: 1
175
- Warnings: 1
176
-
177
- Fix recommendations:
178
- V1: dispatch flow-executor to run tests, add evidence to the commit message body
179
- ```
package/hooks/hooks.json DELETED
@@ -1,130 +0,0 @@
1
- {
2
- "hooks": {
3
- "SessionStart": [
4
- {
5
- "hooks": [
6
- {
7
- "type": "command",
8
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start.sh",
9
- "statusMessage": "Loading CurDX-Flow project context"
10
- }
11
- ]
12
- },
13
- {
14
- "matcher": "startup|clear|compact",
15
- "hooks": [
16
- {
17
- "type": "command",
18
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/inject-karpathy.sh",
19
- "statusMessage": "Injecting CurDX-Flow engineering baseline"
20
- }
21
- ]
22
- }
23
- ],
24
- "UserPromptSubmit": [
25
- {
26
- "hooks": [
27
- {
28
- "type": "command",
29
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-title.sh",
30
- "statusMessage": "Refreshing CurDX-Flow session title"
31
- }
32
- ]
33
- }
34
- ],
35
- "CwdChanged": [
36
- {
37
- "hooks": [
38
- {
39
- "type": "command",
40
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/flow-context-watch.sh"
41
- }
42
- ]
43
- }
44
- ],
45
- "FileChanged": [
46
- {
47
- "hooks": [
48
- {
49
- "type": "command",
50
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/flow-context-watch.sh"
51
- }
52
- ]
53
- }
54
- ],
55
- "Stop": [
56
- {
57
- "hooks": [
58
- {
59
- "type": "command",
60
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-watcher.sh"
61
- }
62
- ]
63
- }
64
- ],
65
- "SubagentStop": [
66
- {
67
- "matcher": "flow-(architect|brownfield-analyst|debugger|edge-hunter|executor|product-designer|planner|qa-engineer|researcher|reviewer|security-auditor|triage-analyst|ui-researcher|ux-designer|verifier|adversary)",
68
- "hooks": [
69
- {
70
- "type": "command",
71
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/subagent-artifact-guard.sh",
72
- "statusMessage": "Checking curdx-flow artifact landing"
73
- }
74
- ]
75
- }
76
- ],
77
- "TaskCreated": [
78
- {
79
- "hooks": [
80
- {
81
- "type": "command",
82
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/task-lifecycle-guard.sh"
83
- }
84
- ]
85
- }
86
- ],
87
- "TaskCompleted": [
88
- {
89
- "hooks": [
90
- {
91
- "type": "command",
92
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/task-lifecycle-guard.sh"
93
- }
94
- ]
95
- }
96
- ],
97
- "TeammateIdle": [
98
- {
99
- "hooks": [
100
- {
101
- "type": "command",
102
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/teammate-idle-guard.sh"
103
- }
104
- ]
105
- }
106
- ],
107
- "ConfigChange": [
108
- {
109
- "matcher": "project_settings|local_settings",
110
- "hooks": [
111
- {
112
- "type": "command",
113
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/config-change-guard.sh"
114
- }
115
- ]
116
- }
117
- ],
118
- "PreToolUse": [
119
- {
120
- "matcher": "AskUserQuestion",
121
- "hooks": [
122
- {
123
- "type": "command",
124
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/quick-mode-guard.sh"
125
- }
126
- ]
127
- }
128
- ]
129
- }
130
- }
@@ -1,237 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- has_python3() {
4
- command -v python3 >/dev/null 2>&1
5
- }
6
-
7
- resolve_flow_root() {
8
- local candidate="${1:-${PWD:-}}"
9
-
10
- if [ -n "${CLAUDE_PROJECT_DIR:-}" ] && [ -d "${CLAUDE_PROJECT_DIR}/.flow" ]; then
11
- printf '%s\n' "${CLAUDE_PROJECT_DIR%/}"
12
- return 0
13
- fi
14
-
15
- [ -n "$candidate" ] || candidate="$(pwd 2>/dev/null || printf '.')"
16
-
17
- while [ -n "$candidate" ]; do
18
- if [ -d "$candidate/.flow" ]; then
19
- printf '%s\n' "$candidate"
20
- return 0
21
- fi
22
-
23
- [ "$candidate" = "/" ] && break
24
- candidate="$(dirname "$candidate")"
25
- done
26
-
27
- return 1
28
- }
29
-
30
- curdx_active_spec_name() {
31
- local flow_root="${1:-${FLOW_ROOT:-}}"
32
- [ -n "$flow_root" ] || return 1
33
- [ -f "$flow_root/.flow/.active-spec" ] || return 1
34
- cat "$flow_root/.flow/.active-spec" 2>/dev/null
35
- }
36
-
37
- curdx_active_spec_path() {
38
- local flow_root="${1:-${FLOW_ROOT:-}}"
39
- local file_name="${2:-}"
40
- local active
41
-
42
- [ -n "$flow_root" ] || return 1
43
- [ -n "$file_name" ] || return 1
44
-
45
- active="$(curdx_active_spec_name "$flow_root" 2>/dev/null || true)"
46
- [ -n "$active" ] || return 1
47
-
48
- printf '%s/.flow/specs/%s/%s\n' "$flow_root" "$active" "$file_name"
49
- }
50
-
51
- curdx_latest_epic_artifact_path() {
52
- local flow_root="${1:-${FLOW_ROOT:-}}"
53
-
54
- [ -n "$flow_root" ] || return 1
55
- [ -d "$flow_root/.flow/_epics" ] || return 1
56
- has_python3 || return 1
57
-
58
- export CURDX_EPIC_DIR="$flow_root/.flow/_epics"
59
- python3 <<'PY' 2>/dev/null
60
- import os
61
- from pathlib import Path
62
-
63
- base = Path(os.environ["CURDX_EPIC_DIR"])
64
- candidates = [path for path in base.glob("*/epic.md") if path.is_file()]
65
- if not candidates:
66
- raise SystemExit(1)
67
-
68
- latest = max(candidates, key=lambda path: path.stat().st_mtime)
69
- print(str(latest))
70
- PY
71
- }
72
-
73
- curdx_epic_artifact_path_from_message() {
74
- local flow_root="${1:-${FLOW_ROOT:-}}"
75
- local msg="${2:-}"
76
-
77
- [ -n "$flow_root" ] || return 1
78
- has_python3 || return 1
79
-
80
- export CURDX_EPIC_MSG="$msg"
81
- export CURDX_FLOW_ROOT="$flow_root"
82
- python3 <<'PY' 2>/dev/null
83
- import os
84
- import re
85
-
86
- msg = os.environ.get("CURDX_EPIC_MSG", "")
87
- match = re.search(r'(\.flow/_epics/[^/\s]+/epic\.md)\b', msg)
88
- if not match:
89
- raise SystemExit(1)
90
-
91
- rel = match.group(1)
92
- if rel.startswith(".flow/"):
93
- rel = rel[len(".flow/"):]
94
-
95
- print(os.path.join(os.environ["CURDX_FLOW_ROOT"], ".flow", rel))
96
- PY
97
- }
98
-
99
- curdx_resolve_artifact_contract() {
100
- local agent_type="${1:-}"
101
- local last_message="${2:-}"
102
- local flow_root="${3:-${FLOW_ROOT:-}}"
103
-
104
- CURDX_ARTIFACT_TARGET=""
105
- CURDX_ARTIFACT_MIN_SIZE=0
106
-
107
- [ -n "$agent_type" ] || return 1
108
-
109
- case "$agent_type" in
110
- flow-researcher)
111
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" research.md)" || return 1
112
- CURDX_ARTIFACT_MIN_SIZE=400
113
- ;;
114
- flow-product-designer)
115
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" requirements.md)" || return 1
116
- CURDX_ARTIFACT_MIN_SIZE=400
117
- ;;
118
- flow-architect)
119
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" design.md)" || return 1
120
- CURDX_ARTIFACT_MIN_SIZE=400
121
- ;;
122
- flow-planner)
123
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" tasks.md)" || return 1
124
- CURDX_ARTIFACT_MIN_SIZE=400
125
- ;;
126
- flow-executor)
127
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" tasks.md)" || return 1
128
- CURDX_ARTIFACT_MIN_SIZE=400
129
- ;;
130
- flow-debugger)
131
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" debug-report.md)" || return 1
132
- CURDX_ARTIFACT_MIN_SIZE=250
133
- ;;
134
- flow-reviewer)
135
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" review-report.md)" || return 1
136
- CURDX_ARTIFACT_MIN_SIZE=300
137
- ;;
138
- flow-verifier)
139
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" verification-report.md)" || return 1
140
- CURDX_ARTIFACT_MIN_SIZE=300
141
- ;;
142
- flow-security-auditor)
143
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" security-audit.md)" || return 1
144
- CURDX_ARTIFACT_MIN_SIZE=250
145
- ;;
146
- flow-qa-engineer)
147
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" qa-report.md)" || return 1
148
- CURDX_ARTIFACT_MIN_SIZE=250
149
- ;;
150
- flow-edge-hunter)
151
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" edge-cases.md)" || return 1
152
- CURDX_ARTIFACT_MIN_SIZE=250
153
- ;;
154
- flow-adversary)
155
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" adversarial-review.md)" || return 1
156
- CURDX_ARTIFACT_MIN_SIZE=250
157
- ;;
158
- flow-ui-researcher)
159
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" ui-research.md)" || return 1
160
- CURDX_ARTIFACT_MIN_SIZE=250
161
- ;;
162
- flow-ux-designer)
163
- CURDX_ARTIFACT_TARGET="$(curdx_active_spec_path "$flow_root" ui-sketch/index.html)" || return 1
164
- CURDX_ARTIFACT_MIN_SIZE=400
165
- ;;
166
- flow-triage-analyst)
167
- CURDX_ARTIFACT_TARGET="$(curdx_epic_artifact_path_from_message "$flow_root" "$last_message" 2>/dev/null || true)"
168
- if [ -z "$CURDX_ARTIFACT_TARGET" ]; then
169
- CURDX_ARTIFACT_TARGET="$(curdx_latest_epic_artifact_path "$flow_root" 2>/dev/null || true)"
170
- fi
171
- [ -n "$CURDX_ARTIFACT_TARGET" ] || return 1
172
- CURDX_ARTIFACT_MIN_SIZE=400
173
- ;;
174
- flow-brownfield-analyst)
175
- [ -n "$flow_root" ] || return 1
176
- CURDX_ARTIFACT_TARGET="$flow_root/.flow/codebase-index.md"
177
- CURDX_ARTIFACT_MIN_SIZE=250
178
- ;;
179
- *)
180
- return 1
181
- ;;
182
- esac
183
-
184
- return 0
185
- }
186
-
187
- env_flag_enabled() {
188
- case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in
189
- 1|true|yes|on) return 0 ;;
190
- *) return 1 ;;
191
- esac
192
- }
193
-
194
- json_escape() {
195
- local value="${1:-}"
196
-
197
- if has_python3; then
198
- printf '%s' "$value" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
199
- return
200
- fi
201
-
202
- printf '%s' "$value" \
203
- | sed 's/\\/\\\\/g; s/"/\\"/g' \
204
- | awk 'BEGIN{printf "\""} {printf "%s\\n", $0} END{printf "\""}'
205
- }
206
-
207
- emit_session_start_context() {
208
- local context="${1:-}"
209
- printf '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":%s}}\n' \
210
- "$(json_escape "$context")"
211
- }
212
-
213
- emit_userprompt_submit_title() {
214
- local title="${1:-}"
215
- printf '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","sessionTitle":%s}}\n' \
216
- "$(json_escape "$title")"
217
- }
218
-
219
- emit_pretooluse_deny() {
220
- local reason="${1:-}"
221
- printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":%s}}\n' \
222
- "$(json_escape "$reason")"
223
- }
224
-
225
- emit_stop_block() {
226
- local reason="${1:-}"
227
- printf '{"decision":"block","reason":%s}\n' "$(json_escape "$reason")"
228
- }
229
-
230
- emit_subagentstop_block() {
231
- emit_stop_block "${1:-}"
232
- }
233
-
234
- emit_configchange_block() {
235
- local reason="${1:-}"
236
- printf '{"decision":"block","reason":%s}\n' "$(json_escape "$reason")"
237
- }
@@ -1,94 +0,0 @@
1
- #!/usr/bin/env bash
2
- # CurDX-Flow ConfigChange Hook
3
- # Blocks mid-execute settings changes that would disable CurDX's runtime spine.
4
-
5
- set -u
6
-
7
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
- . "$SCRIPT_DIR/common.sh"
9
-
10
- INPUT="$(cat 2>/dev/null || echo "{}")"
11
- FLOW_ROOT="$(resolve_flow_root 2>/dev/null || true)"
12
-
13
- [ -n "$FLOW_ROOT" ] || exit 0
14
- has_python3 || exit 0
15
-
16
- export CURDX_CONFIG_CHANGE_INPUT="$INPUT"
17
-
18
- SOURCE="$(python3 -c 'import json, os
19
- try:
20
- data = json.loads(os.environ["CURDX_CONFIG_CHANGE_INPUT"])
21
- print(data.get("source", ""))
22
- except Exception:
23
- print("")
24
- ' 2>/dev/null)"
25
-
26
- case "$SOURCE" in
27
- project_settings|local_settings) ;;
28
- *) exit 0 ;;
29
- esac
30
-
31
- FILE_PATH="$(python3 -c 'import json, os
32
- try:
33
- data = json.loads(os.environ["CURDX_CONFIG_CHANGE_INPUT"])
34
- print(data.get("file_path", ""))
35
- except Exception:
36
- print("")
37
- ' 2>/dev/null)"
38
-
39
- [ -n "$FILE_PATH" ] || exit 0
40
- [ -f "$FILE_PATH" ] || exit 0
41
- [ -f "$FLOW_ROOT/.flow/.active-spec" ] || exit 0
42
-
43
- ACTIVE="$(cat "$FLOW_ROOT/.flow/.active-spec" 2>/dev/null)"
44
- [ -n "$ACTIVE" ] || exit 0
45
-
46
- STATE_FILE="$FLOW_ROOT/.flow/specs/$ACTIVE/.state.json"
47
- [ -f "$STATE_FILE" ] || exit 0
48
-
49
- export STATE_FILE
50
- PHASE="$(python3 -c 'import json, os
51
- try:
52
- state = json.load(open(os.environ["STATE_FILE"]))
53
- print(state.get("phase", ""))
54
- except Exception:
55
- print("")
56
- ' 2>/dev/null)"
57
-
58
- [ "$PHASE" = "execute" ] || exit 0
59
-
60
- export CURDX_CONFIG_CHANGE_FILE="$FILE_PATH"
61
- BLOCK_REASONS="$(python3 <<'PY' 2>/dev/null
62
- import json
63
- import os
64
-
65
- file_path = os.environ["CURDX_CONFIG_CHANGE_FILE"]
66
- try:
67
- parsed = json.load(open(file_path))
68
- except Exception:
69
- raise SystemExit(0)
70
-
71
- reasons = []
72
-
73
- if parsed.get("disableAllHooks") is True:
74
- reasons.append("disableAllHooks would disable CurDX-Flow stop/recovery hooks and status lines")
75
-
76
- agent = parsed.get("agent")
77
- if isinstance(agent, str):
78
- agent = agent.strip()
79
- if agent and agent != "flow-orchestrator":
80
- reasons.append(f'agent would reroute the main thread through subagent "{agent}"')
81
-
82
- enabled_plugins = parsed.get("enabledPlugins")
83
- if isinstance(enabled_plugins, dict) and enabled_plugins.get("curdx-flow@curdx-flow-marketplace") is False:
84
- reasons.append("enabledPlugins would disable curdx-flow@curdx-flow-marketplace for this project")
85
-
86
- if reasons:
87
- print(" | ".join(reasons))
88
- PY
89
- )"
90
-
91
- [ -n "$BLOCK_REASONS" ] || exit 0
92
-
93
- emit_configchange_block "[CurDX-Flow config-change-guard] Blocking ${SOURCE} update while spec '${ACTIVE}' is in execute: ${BLOCK_REASONS}. Finish or cancel the active implementation first, then reapply the settings change after execute ends."
94
- exit 0