@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.
- package/CHANGELOG.md +21 -87
- package/LICENSE +1 -1
- package/README.md +28 -129
- package/dist/index.mjs +995 -0
- package/package.json +33 -44
- package/.claude-plugin/marketplace.json +0 -48
- package/.claude-plugin/plugin.json +0 -52
- package/agent-preamble/preamble.md +0 -314
- package/agents/flow-adversary.md +0 -203
- package/agents/flow-architect.md +0 -198
- package/agents/flow-brownfield-analyst.md +0 -143
- package/agents/flow-debugger.md +0 -321
- package/agents/flow-edge-hunter.md +0 -289
- package/agents/flow-executor.md +0 -269
- package/agents/flow-orchestrator.md +0 -145
- package/agents/flow-planner.md +0 -247
- package/agents/flow-product-designer.md +0 -159
- package/agents/flow-qa-engineer.md +0 -282
- package/agents/flow-researcher.md +0 -166
- package/agents/flow-reviewer.md +0 -304
- package/agents/flow-security-auditor.md +0 -401
- package/agents/flow-triage-analyst.md +0 -272
- package/agents/flow-ui-researcher.md +0 -230
- package/agents/flow-ux-designer.md +0 -221
- package/agents/flow-verifier.md +0 -350
- package/bin/curdx-flow +0 -5
- package/bin/curdx-flow-state +0 -104
- package/bin/curdx-flow.js +0 -54
- package/cli/README.md +0 -104
- package/cli/doctor-workflow.js +0 -483
- package/cli/doctor.js +0 -73
- package/cli/help.js +0 -59
- package/cli/install-bundled-mcps.js +0 -37
- package/cli/install-companions.js +0 -19
- package/cli/install-context7-config.js +0 -80
- package/cli/install-curdx-plugin.js +0 -96
- package/cli/install-language.js +0 -35
- package/cli/install-next-steps.js +0 -29
- package/cli/install-options.js +0 -9
- package/cli/install-paths.js +0 -52
- package/cli/install-recommended-plugins.js +0 -104
- package/cli/install-required-plugins.js +0 -57
- package/cli/install-self-update.js +0 -62
- package/cli/install-workflow.js +0 -209
- package/cli/install.js +0 -101
- package/cli/lib/claude-commands.js +0 -41
- package/cli/lib/claude-ops.js +0 -47
- package/cli/lib/claude.js +0 -183
- package/cli/lib/config.js +0 -24
- package/cli/lib/doctor-claude-settings.js +0 -1186
- package/cli/lib/doctor-report.js +0 -978
- package/cli/lib/doctor-runtime-environment.js +0 -196
- package/cli/lib/frontmatter.js +0 -44
- package/cli/lib/json-schema.js +0 -57
- package/cli/lib/logging.js +0 -25
- package/cli/lib/process.js +0 -60
- package/cli/lib/prompts.js +0 -135
- package/cli/lib/runtime.js +0 -107
- package/cli/lib/semver.js +0 -109
- package/cli/lib/version.js +0 -12
- package/cli/protocols-body.md +0 -22
- package/cli/protocols.js +0 -162
- package/cli/registry.js +0 -123
- package/cli/router.js +0 -49
- package/cli/uninstall-actions.js +0 -360
- package/cli/uninstall-workflow.js +0 -146
- package/cli/uninstall.js +0 -42
- package/cli/upgrade-workflow.js +0 -80
- package/cli/upgrade.js +0 -91
- package/cli/utils.js +0 -40
- package/gates/adversarial-review-gate.md +0 -219
- package/gates/coverage-audit-gate.md +0 -182
- package/gates/devex-gate.md +0 -254
- package/gates/edge-case-gate.md +0 -194
- package/gates/karpathy-gate.md +0 -130
- package/gates/security-gate.md +0 -218
- package/gates/tdd-gate.md +0 -182
- package/gates/test-quality-gate.md +0 -59
- package/gates/verification-gate.md +0 -179
- package/hooks/hooks.json +0 -130
- package/hooks/scripts/common.sh +0 -237
- package/hooks/scripts/config-change-guard.sh +0 -94
- package/hooks/scripts/flow-context-watch.sh +0 -94
- package/hooks/scripts/inject-karpathy.sh +0 -53
- package/hooks/scripts/quick-mode-guard.sh +0 -69
- package/hooks/scripts/session-start.sh +0 -94
- package/hooks/scripts/session-title.sh +0 -87
- package/hooks/scripts/stop-watcher.sh +0 -231
- package/hooks/scripts/subagent-artifact-guard.sh +0 -92
- package/hooks/scripts/subagent-statusline.sh +0 -111
- package/hooks/scripts/task-lifecycle-guard.sh +0 -106
- package/hooks/scripts/teammate-idle-guard.sh +0 -83
- package/knowledge/artifact-output-discipline.md +0 -24
- package/knowledge/artifact-summary-contracts.md +0 -50
- package/knowledge/atomic-commits.md +0 -262
- package/knowledge/claude-code-runtime-contracts.md +0 -240
- package/knowledge/epic-decomposition.md +0 -307
- package/knowledge/execution-strategies.md +0 -303
- package/knowledge/karpathy-guidelines.md +0 -219
- package/knowledge/planning-reviews.md +0 -211
- package/knowledge/poc-first-workflow.md +0 -223
- package/knowledge/review-feedback-intake.md +0 -57
- package/knowledge/spec-driven-development.md +0 -180
- package/knowledge/systematic-debugging.md +0 -378
- package/knowledge/two-stage-review.md +0 -249
- package/knowledge/wave-execution.md +0 -403
- package/monitors/monitors.json +0 -8
- package/monitors/scripts/flow-state-monitor.sh +0 -102
- package/output-styles/curdx-evidence-first.md +0 -34
- package/output-styles/curdx-fast-mode.md +0 -42
- package/output-styles/curdx-spec-mode.md +0 -46
- package/schemas/agent-frontmatter.schema.json +0 -66
- package/schemas/config.schema.json +0 -134
- package/schemas/gate-frontmatter.schema.json +0 -30
- package/schemas/hooks.schema.json +0 -115
- package/schemas/output-style-frontmatter.schema.json +0 -22
- package/schemas/plugin-manifest.schema.json +0 -436
- package/schemas/plugin-settings.schema.json +0 -29
- package/schemas/skill-frontmatter.schema.json +0 -177
- package/schemas/spec-frontmatter.schema.json +0 -42
- package/schemas/spec-state.schema.json +0 -165
- package/settings.json +0 -8
- package/skills/brownfield-index/SKILL.md +0 -53
- package/skills/brownfield-index/references/applicability.md +0 -12
- package/skills/brownfield-index/references/handoff.md +0 -8
- package/skills/brownfield-index/references/index-contract.md +0 -10
- package/skills/browser-qa/SKILL.md +0 -39
- package/skills/browser-qa/references/handoff.md +0 -6
- package/skills/browser-qa/references/prerequisites.md +0 -10
- package/skills/browser-qa/references/qa-contract.md +0 -20
- package/skills/cancel/SKILL.md +0 -41
- package/skills/cancel/references/destructive-mode.md +0 -17
- package/skills/cancel/references/reporting.md +0 -18
- package/skills/cancel/references/state-recovery.md +0 -30
- package/skills/cancel/references/target-resolution.md +0 -7
- package/skills/debug/SKILL.md +0 -45
- package/skills/debug/references/context-gathering.md +0 -11
- package/skills/debug/references/failure-guard.md +0 -25
- package/skills/debug/references/intake.md +0 -12
- package/skills/debug/references/phase-workflow.md +0 -34
- package/skills/debug/references/reporting.md +0 -20
- package/skills/epic/SKILL.md +0 -39
- package/skills/epic/references/epic-artifacts.md +0 -20
- package/skills/epic/references/epic-intake.md +0 -9
- package/skills/epic/references/slice-handoff.md +0 -16
- package/skills/fast/SKILL.md +0 -62
- package/skills/fast/references/applicability.md +0 -25
- package/skills/fast/references/clarification.md +0 -20
- package/skills/fast/references/execution-contract.md +0 -56
- package/skills/help/SKILL.md +0 -55
- package/skills/help/references/dispatch.md +0 -20
- package/skills/help/references/overview.md +0 -39
- package/skills/help/references/troubleshoot.md +0 -47
- package/skills/help/references/workflow.md +0 -37
- package/skills/implement/SKILL.md +0 -104
- package/skills/implement/references/error-recovery.md +0 -36
- package/skills/implement/references/linear-execution.md +0 -43
- package/skills/implement/references/native-task-sync.md +0 -107
- package/skills/implement/references/preflight.md +0 -43
- package/skills/implement/references/progress-contract.md +0 -36
- package/skills/implement/references/state-init.md +0 -36
- package/skills/implement/references/stop-hook-execution.md +0 -50
- package/skills/implement/references/strategy-router.md +0 -38
- package/skills/implement/references/subagent-execution.md +0 -57
- package/skills/implement/references/wave-execution.md +0 -180
- package/skills/init/SKILL.md +0 -49
- package/skills/init/references/gitignore-and-health.md +0 -26
- package/skills/init/references/next-steps.md +0 -22
- package/skills/init/references/preflight.md +0 -15
- package/skills/init/references/scaffold-contract.md +0 -27
- package/skills/review/SKILL.md +0 -82
- package/skills/review/references/optional-passes.md +0 -48
- package/skills/review/references/preflight.md +0 -38
- package/skills/review/references/report-contract.md +0 -49
- package/skills/review/references/reporting.md +0 -20
- package/skills/review/references/stage-execution.md +0 -32
- package/skills/security-audit/SKILL.md +0 -47
- package/skills/security-audit/references/audit-contract.md +0 -21
- package/skills/security-audit/references/gate-handoff.md +0 -8
- package/skills/security-audit/references/scope-and-depth.md +0 -9
- package/skills/spec/SKILL.md +0 -100
- package/skills/spec/references/artifact-landing.md +0 -31
- package/skills/spec/references/phase-execution.md +0 -50
- package/skills/spec/references/planning-review.md +0 -31
- package/skills/spec/references/preflight-and-routing.md +0 -46
- package/skills/spec/references/reporting.md +0 -21
- package/skills/start/SKILL.md +0 -84
- package/skills/start/references/branch-routing.md +0 -51
- package/skills/start/references/mode-semantics.md +0 -12
- package/skills/start/references/preflight.md +0 -13
- package/skills/start/references/reporting.md +0 -20
- package/skills/start/references/state-seeding.md +0 -44
- package/skills/start/references/workflow-handoff.md +0 -26
- package/skills/status/SKILL.md +0 -41
- package/skills/status/references/gather-contract.md +0 -30
- package/skills/status/references/health-rules.md +0 -27
- package/skills/status/references/output-contract.md +0 -25
- package/skills/status/references/preflight.md +0 -10
- package/skills/status/references/recovery-hints.md +0 -18
- package/skills/ui-sketch/SKILL.md +0 -39
- package/skills/ui-sketch/references/brief-intake.md +0 -10
- package/skills/ui-sketch/references/iteration-handoff.md +0 -5
- package/skills/ui-sketch/references/variant-contract.md +0 -15
- package/skills/verify/SKILL.md +0 -56
- package/skills/verify/references/evidence-workflow.md +0 -39
- package/skills/verify/references/output-contract.md +0 -23
- package/skills/verify/references/preflight.md +0 -11
- package/skills/verify/references/report-handoff.md +0 -35
- package/skills/verify/references/strict-mode.md +0 -12
- package/templates/CONTEXT.md.tmpl +0 -53
- package/templates/PROJECT.md.tmpl +0 -59
- package/templates/ROADMAP.md.tmpl +0 -50
- package/templates/STATE.md.tmpl +0 -49
- package/templates/config.json.tmpl +0 -51
- package/templates/design.md.tmpl +0 -83
- package/templates/progress.md.tmpl +0 -77
- package/templates/requirements.md.tmpl +0 -76
- package/templates/research.md.tmpl +0 -83
- 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
|
-
}
|
package/hooks/scripts/common.sh
DELETED
|
@@ -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
|