@ktpartners/dgs-platform 2.9.0 → 3.3.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 +197 -0
- package/README.md +34 -2
- package/agents/dgs-executor.md +124 -3
- package/agents/dgs-idea-researcher.md +447 -0
- package/agents/dgs-plan-checker.md +61 -3
- package/agents/dgs-planner.md +51 -8
- package/bin/install.js +44 -0
- package/commands/dgs/abandon-quick.md +28 -0
- package/commands/dgs/add-tests.md +2 -2
- package/commands/dgs/audit-milestone.md +4 -3
- package/commands/dgs/capture-principle.md +11 -11
- package/commands/dgs/cleanup.md +2 -2
- package/commands/dgs/complete-milestone.md +11 -11
- package/commands/dgs/complete-quick.md +28 -0
- package/commands/dgs/create-milestone-job.md +2 -2
- package/commands/dgs/debug.md +3 -3
- package/commands/dgs/develop-idea.md +1 -1
- package/commands/dgs/diff-report.md +124 -0
- package/commands/dgs/fast.md +3 -1
- package/commands/dgs/health.md +1 -1
- package/commands/dgs/map-codebase.md +6 -6
- package/commands/dgs/new-milestone.md +5 -5
- package/commands/dgs/new-project.md +8 -21
- package/commands/dgs/package-scan.md +43 -0
- package/commands/dgs/plan-milestone-gaps.md +1 -1
- package/commands/dgs/progress.md +3 -3
- package/commands/dgs/quick-abandon.md +8 -0
- package/commands/dgs/quick-complete.md +8 -0
- package/commands/dgs/quick.md +10 -3
- package/commands/dgs/research-idea.md +3 -2
- package/commands/dgs/research-phase.md +3 -3
- package/commands/dgs/switch-project.md +14 -1
- package/commands/dgs/write-spec.md +3 -3
- package/deliver-great-systems/bin/dgs-tools.cjs +401 -32
- package/deliver-great-systems/bin/lib/audit-tolerance.cjs +77 -0
- package/deliver-great-systems/bin/lib/audit-tolerance.test.cjs +101 -0
- package/deliver-great-systems/bin/lib/commands.cjs +626 -46
- package/deliver-great-systems/bin/lib/commands.test.cjs +451 -0
- package/deliver-great-systems/bin/lib/commit-verify.test.cjs +236 -0
- package/deliver-great-systems/bin/lib/config.cjs +80 -6
- package/deliver-great-systems/bin/lib/config.test.cjs +309 -0
- package/deliver-great-systems/bin/lib/context.cjs +120 -0
- package/deliver-great-systems/bin/lib/core.cjs +35 -14
- package/deliver-great-systems/bin/lib/core.test.cjs +79 -1
- package/deliver-great-systems/bin/lib/execution.cjs +49 -17
- package/deliver-great-systems/bin/lib/fast-routing.cjs +199 -0
- package/deliver-great-systems/bin/lib/fast-routing.test.cjs +108 -0
- package/deliver-great-systems/bin/lib/final-commit-precondition.test.cjs +87 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/bundler-audit-gemfile.json +21 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/gate-parity-expected.md +186 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/gate-parity-runresult.json +235 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/govulncheck-import.json +3 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/npm-audit-v10.json +37 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/osv-clean.json +3 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/osv-vulns.json +77 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/pip-audit-requirements.json +28 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/snyk-lodash.json +30 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/snyk-workspaces.json +55 -0
- package/deliver-great-systems/bin/lib/flat-migration.test.cjs +396 -0
- package/deliver-great-systems/bin/lib/frontmatter.cjs +1 -1
- package/deliver-great-systems/bin/lib/governance.cjs +211 -0
- package/deliver-great-systems/bin/lib/governance.test.cjs +339 -0
- package/deliver-great-systems/bin/lib/health-untracked-phase.test.cjs +269 -0
- package/deliver-great-systems/bin/lib/ideas.cjs +206 -91
- package/deliver-great-systems/bin/lib/ideas.test.cjs +244 -1
- package/deliver-great-systems/bin/lib/init.cjs +357 -61
- package/deliver-great-systems/bin/lib/init.test.cjs +625 -8
- package/deliver-great-systems/bin/lib/jobs.cjs +131 -25
- package/deliver-great-systems/bin/lib/jobs.test.cjs +193 -74
- package/deliver-great-systems/bin/lib/migration.cjs +409 -1
- package/deliver-great-systems/bin/lib/migration.test.cjs +158 -1
- package/deliver-great-systems/bin/lib/milestone.cjs +154 -31
- package/deliver-great-systems/bin/lib/milestone.test.cjs +203 -0
- package/deliver-great-systems/bin/lib/package-adapters.cjs +530 -0
- package/deliver-great-systems/bin/lib/package-adapters.test.cjs +618 -0
- package/deliver-great-systems/bin/lib/package-ecosystems.cjs +350 -0
- package/deliver-great-systems/bin/lib/package-ecosystems.test.cjs +348 -0
- package/deliver-great-systems/bin/lib/package-runner.cjs +199 -0
- package/deliver-great-systems/bin/lib/package-runner.test.cjs +198 -0
- package/deliver-great-systems/bin/lib/package-scan-provenance.cjs +56 -0
- package/deliver-great-systems/bin/lib/package-scan-provenance.test.cjs +103 -0
- package/deliver-great-systems/bin/lib/package-scan-report.cjs +1140 -0
- package/deliver-great-systems/bin/lib/package-scan-report.test.cjs +1963 -0
- package/deliver-great-systems/bin/lib/package-scan-skill.cjs +96 -0
- package/deliver-great-systems/bin/lib/package-scan-skill.test.cjs +136 -0
- package/deliver-great-systems/bin/lib/package-scan.cjs +919 -0
- package/deliver-great-systems/bin/lib/package-scan.test.cjs +2147 -0
- package/deliver-great-systems/bin/lib/phase.cjs +146 -3
- package/deliver-great-systems/bin/lib/phase.test.cjs +420 -0
- package/deliver-great-systems/bin/lib/plan-number-validity.test.cjs +48 -0
- package/deliver-great-systems/bin/lib/projects.cjs +65 -10
- package/deliver-great-systems/bin/lib/projects.test.cjs +198 -2
- package/deliver-great-systems/bin/lib/quick.cjs +739 -0
- package/deliver-great-systems/bin/lib/quick.test.cjs +730 -0
- package/deliver-great-systems/bin/lib/repos.cjs +37 -13
- package/deliver-great-systems/bin/lib/review.cjs +1821 -0
- package/deliver-great-systems/bin/lib/roadmap.cjs +34 -13
- package/deliver-great-systems/bin/lib/specs.cjs +3 -81
- package/deliver-great-systems/bin/lib/state-transition-gate.test.cjs +160 -0
- package/deliver-great-systems/bin/lib/state.cjs +147 -55
- package/deliver-great-systems/bin/lib/summary-frontmatter.cjs +54 -0
- package/deliver-great-systems/bin/lib/summary-frontmatter.test.cjs +78 -0
- package/deliver-great-systems/bin/lib/sweep-scope.test.cjs +263 -0
- package/deliver-great-systems/bin/lib/sync.cjs +75 -0
- package/deliver-great-systems/bin/lib/verify.cjs +198 -7
- package/deliver-great-systems/bin/lib/verify.test.cjs +82 -0
- package/deliver-great-systems/bin/lib/wave-0-template-rename.test.cjs +40 -0
- package/deliver-great-systems/bin/lib/worktrees.cjs +790 -0
- package/deliver-great-systems/bin/lib/worktrees.test.cjs +963 -0
- package/deliver-great-systems/references/agent-step-reliability.md +60 -0
- package/deliver-great-systems/references/conflict-resolution.md +4 -0
- package/deliver-great-systems/references/context-tiers.md +4 -0
- package/deliver-great-systems/references/package-scan-config.md +151 -0
- package/deliver-great-systems/references/questioning.md +0 -30
- package/deliver-great-systems/references/spec-review-loop.md +1 -2
- package/deliver-great-systems/references/workflow-conventions.md +29 -0
- package/deliver-great-systems/skills/dgs-tests/package-scan.md +44 -0
- package/deliver-great-systems/templates/REVIEW.md +35 -0
- package/deliver-great-systems/templates/VALIDATION.md +1 -1
- package/deliver-great-systems/templates/claude-md.md +27 -0
- package/deliver-great-systems/templates/package-scan-report.md +108 -0
- package/deliver-great-systems/templates/project.md +6 -170
- package/deliver-great-systems/templates/summary.md +3 -1
- package/deliver-great-systems/workflows/abandon-quick.md +89 -0
- package/deliver-great-systems/workflows/add-idea.md +3 -3
- package/deliver-great-systems/workflows/add-phase.md +5 -0
- package/deliver-great-systems/workflows/add-tests.md +14 -0
- package/deliver-great-systems/workflows/add-todo.md +1 -0
- package/deliver-great-systems/workflows/approve-spec.md +25 -4
- package/deliver-great-systems/workflows/audit-milestone.md +66 -10
- package/deliver-great-systems/workflows/audit-phase.md +15 -5
- package/deliver-great-systems/workflows/cancel-job.md +2 -2
- package/deliver-great-systems/workflows/check-todos.md +2 -3
- package/deliver-great-systems/workflows/codereview.md +103 -9
- package/deliver-great-systems/workflows/complete-milestone.md +218 -24
- package/deliver-great-systems/workflows/complete-quick.md +106 -0
- package/deliver-great-systems/workflows/consolidate-ideas.md +1 -1
- package/deliver-great-systems/workflows/create-milestone-job.md +4 -4
- package/deliver-great-systems/workflows/develop-idea.md +11 -11
- package/deliver-great-systems/workflows/diagnose-issues.md +14 -0
- package/deliver-great-systems/workflows/discuss-idea.md +1 -1
- package/deliver-great-systems/workflows/discuss-phase.md +3 -2
- package/deliver-great-systems/workflows/execute-phase.md +209 -33
- package/deliver-great-systems/workflows/execute-plan.md +22 -22
- package/deliver-great-systems/workflows/help.md +53 -20
- package/deliver-great-systems/workflows/import-spec.md +65 -7
- package/deliver-great-systems/workflows/init-product.md +45 -167
- package/deliver-great-systems/workflows/new-milestone.md +140 -33
- package/deliver-great-systems/workflows/new-project.md +60 -331
- package/deliver-great-systems/workflows/package-scan.md +59 -0
- package/deliver-great-systems/workflows/plan-phase.md +79 -1
- package/deliver-great-systems/workflows/progress-all.md +133 -0
- package/deliver-great-systems/workflows/quick-abandon.md +89 -0
- package/deliver-great-systems/workflows/quick-complete.md +106 -0
- package/deliver-great-systems/workflows/quick.md +328 -26
- package/deliver-great-systems/workflows/refine-spec.md +1 -1
- package/deliver-great-systems/workflows/research-idea.md +77 -139
- package/deliver-great-systems/workflows/resume-project.md +2 -2
- package/deliver-great-systems/workflows/run-job.md +29 -43
- package/deliver-great-systems/workflows/settings.md +13 -77
- package/deliver-great-systems/workflows/validate-phase.md +39 -1
- package/deliver-great-systems/workflows/verify-work.md +14 -0
- package/deliver-great-systems/workflows/write-spec.md +11 -13
- package/hooks/dist/dgs-enforce-discipline.js +196 -0
- package/package.json +1 -1
- package/scripts/build-hooks.js +1 -0
|
@@ -12,6 +12,14 @@ Audit Nyquist validation gaps for a completed phase. Generate missing tests. Upd
|
|
|
12
12
|
|
|
13
13
|
## 0. Initialize
|
|
14
14
|
|
|
15
|
+
**Parse `--scaffold` flag:**
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Parse `--scaffold` flag from PHASE_ARG (e.g., `/dgs:validate-phase 16 --scaffold`).
|
|
19
|
+
Set `SCAFFOLD_MODE = true` if `--scaffold` is present, `false` otherwise.
|
|
20
|
+
Strip `--scaffold` from PHASE_ARG before passing to `init phase-op`.
|
|
21
|
+
```
|
|
22
|
+
|
|
15
23
|
```bash
|
|
16
24
|
INIT=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" init phase-op "${PHASE_ARG}")
|
|
17
25
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
@@ -83,10 +91,14 @@ Classify each requirement:
|
|
|
83
91
|
|
|
84
92
|
Build: `{ task_id, requirement, gap_type, suggested_test_path, suggested_command }`
|
|
85
93
|
|
|
86
|
-
|
|
94
|
+
**Scaffold mode:** If `SCAFFOLD_MODE` is true, override all gap statuses to `PENDING_REVIEW` (not MISSING, not manual-only -- a distinct scaffold status meaning "gap identified but not yet triaged").
|
|
95
|
+
|
|
96
|
+
No gaps → skip to Step 6, set `nyquist_compliant: true`. In scaffold mode, this still produces a VALIDATION.md (with all requirements COVERED or PENDING_REVIEW).
|
|
87
97
|
|
|
88
98
|
## 4. Present Gap Plan
|
|
89
99
|
|
|
100
|
+
**Scaffold mode:** If `SCAFFOLD_MODE` is true, skip this step entirely (do not call AskUserQuestion). Proceed directly to Step 6.
|
|
101
|
+
|
|
90
102
|
Call AskUserQuestion with gap table and options:
|
|
91
103
|
1. "Fix all gaps" → Step 5
|
|
92
104
|
2. "Skip — mark manual-only" → add to Manual-Only, Step 6
|
|
@@ -94,6 +106,8 @@ Call AskUserQuestion with gap table and options:
|
|
|
94
106
|
|
|
95
107
|
## 5. Spawn dgs-nyquist-auditor
|
|
96
108
|
|
|
109
|
+
**Scaffold mode:** If `SCAFFOLD_MODE` is true, skip this step entirely (do not spawn auditor). Proceed directly to Step 6.
|
|
110
|
+
|
|
97
111
|
```
|
|
98
112
|
Task(
|
|
99
113
|
prompt="Read ~/.claude/agents/dgs-nyquist-auditor.md for instructions.\n\n" +
|
|
@@ -114,6 +128,8 @@ Handle return:
|
|
|
114
128
|
|
|
115
129
|
## 6. Generate/Update VALIDATION.md
|
|
116
130
|
|
|
131
|
+
**Scaffold mode:** If `SCAFFOLD_MODE` is true, always use the State B (create) flow regardless of existing VALIDATION.md state. Gaps are marked as `PENDING_REVIEW` in the Per-Task Map.
|
|
132
|
+
|
|
117
133
|
**State B (create):**
|
|
118
134
|
1. Read template from `~/.claude/deliver-great-systems/templates/VALIDATION.md`
|
|
119
135
|
2. Fill: frontmatter, Test Infrastructure, Per-Task Map, Manual-Only, Sign-Off
|
|
@@ -134,6 +150,15 @@ Handle return:
|
|
|
134
150
|
|
|
135
151
|
## 7. Commit
|
|
136
152
|
|
|
153
|
+
**Scaffold mode:** If `SCAFFOLD_MODE` is true:
|
|
154
|
+
- Only commit VALIDATION.md (no test files -- none were generated)
|
|
155
|
+
- Commit message: `docs(phase-${PHASE}): scaffold Nyquist validation`
|
|
156
|
+
- Use: `node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit-docs "docs(phase-${PHASE}): scaffold Nyquist validation"`
|
|
157
|
+
- Do NOT run the `git add {test_files}` / `git commit -m "test(..."` block
|
|
158
|
+
- Skip to Step 8
|
|
159
|
+
|
|
160
|
+
**Non-scaffold mode:**
|
|
161
|
+
|
|
137
162
|
```bash
|
|
138
163
|
git add {test_files}
|
|
139
164
|
git commit -m "test(phase-${PHASE}): add Nyquist validation tests"
|
|
@@ -143,6 +168,14 @@ node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit-docs "docs(p
|
|
|
143
168
|
|
|
144
169
|
## 8. Results + Routing
|
|
145
170
|
|
|
171
|
+
**Scaffold mode:** If `SCAFFOLD_MODE` is true, display scaffold-specific output and exit:
|
|
172
|
+
```
|
|
173
|
+
DGS > PHASE {N} VALIDATION SCAFFOLDED
|
|
174
|
+
{M} requirements mapped, {K} gaps pending review.
|
|
175
|
+
> Fill gaps: /dgs:validate-phase {N}
|
|
176
|
+
```
|
|
177
|
+
Display `/clear` reminder. Skip the Compliant/Partial output below.
|
|
178
|
+
|
|
146
179
|
**Compliant:**
|
|
147
180
|
```
|
|
148
181
|
DGS > PHASE {N} IS NYQUIST-COMPLIANT
|
|
@@ -174,4 +207,9 @@ Display `/clear` reminder.
|
|
|
174
207
|
- [ ] VALIDATION.md created or updated
|
|
175
208
|
- [ ] Test files committed separately
|
|
176
209
|
- [ ] Results with routing presented
|
|
210
|
+
- [ ] --scaffold flag parsed and controls Steps 4-8
|
|
211
|
+
- [ ] Scaffold mode skips interactive gap plan (Step 4) and auditor (Step 5)
|
|
212
|
+
- [ ] Scaffold mode marks gaps as PENDING_REVIEW
|
|
213
|
+
- [ ] Scaffold mode commits docs-only with scaffold commit message
|
|
214
|
+
- [ ] Scaffold mode displays scaffold-specific results banner
|
|
177
215
|
</success_criteria>
|
|
@@ -63,6 +63,20 @@ REPOS_MD=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" repos li
|
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
Parse JSON for the list of registered repos with paths.
|
|
66
|
+
|
|
67
|
+
**Worktree-aware code directory resolution (resolveCodeContext):**
|
|
68
|
+
|
|
69
|
+
For each registered code repo, resolve the correct working directory. When a milestone or quick worktree is active, code operations must target the worktree directory, not the main checkout.
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
// In the agent's execution context, use resolveCodeContext to determine the code directory:
|
|
73
|
+
const { resolveCodeContext } = require('./bin/lib/context.cjs');
|
|
74
|
+
const ctx = resolveCodeContext(planningRoot, repoName);
|
|
75
|
+
// ctx.type: 'main' | 'milestone' | 'quick'
|
|
76
|
+
// ctx.directory: absolute path to the correct working directory
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Use `ctx.directory` (or the repo's main checkout path when no worktree is active) for all file reading, test execution, and code verification operations. Do NOT hardcode repo paths from REPOS.md when a worktree may be active.
|
|
66
80
|
</step>
|
|
67
81
|
|
|
68
82
|
<step name="check_active_session">
|
|
@@ -103,8 +103,8 @@ Then proceed normally. Only show this tip when ALL selected ideas lack enrichmen
|
|
|
103
103
|
**Load supporting documents** from each selected idea's `docs/` directory:
|
|
104
104
|
|
|
105
105
|
For each selected idea:
|
|
106
|
-
a. Derive the idea's docs path: `${project_root}/ideas/
|
|
107
|
-
Alternative path: check
|
|
106
|
+
a. Derive the idea's docs path: `${project_root}/docs/ideas/{idea_slug}/` where `idea_slug` is derived from the idea filename (strip numeric prefix and .md suffix, e.g., `005-retry-logic.md` -> `retry-logic`).
|
|
107
|
+
Alternative path: check for research docs at `${project_root}/docs/ideas/{slug}-*.md`.
|
|
108
108
|
b. If the docs/ directory exists, list all files in it:
|
|
109
109
|
```bash
|
|
110
110
|
ls "${IDEA_DOCS_DIR}/" 2>/dev/null
|
|
@@ -222,7 +222,7 @@ node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs specs add-log-entry --id
|
|
|
222
222
|
|
|
223
223
|
Commit the draft:
|
|
224
224
|
```bash
|
|
225
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: draft $id from ideas $idea_ids" --push --files
|
|
225
|
+
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: draft $id from ideas $idea_ids" --push --files specs/$filename
|
|
226
226
|
```
|
|
227
227
|
|
|
228
228
|
Store `SPEC_ID` and `FILENAME` for subsequent steps.
|
|
@@ -289,7 +289,7 @@ Use AskUserQuestion: "Review the draft spec above. Type **approve** to send to r
|
|
|
289
289
|
|
|
290
290
|
After approval, commit any changes:
|
|
291
291
|
```bash
|
|
292
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: revise draft $SPEC_ID" --push --files
|
|
292
|
+
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: revise draft $SPEC_ID" --push --files specs/$FILENAME
|
|
293
293
|
```
|
|
294
294
|
</step>
|
|
295
295
|
|
|
@@ -350,7 +350,7 @@ Estimated cost: ~$X.XX
|
|
|
350
350
|
**6. Commit updated spec:**
|
|
351
351
|
|
|
352
352
|
```bash
|
|
353
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: review $SPEC_ID (N rounds)" --push --files
|
|
353
|
+
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: review $SPEC_ID (N rounds)" --push --files specs/$FILENAME
|
|
354
354
|
```
|
|
355
355
|
</step>
|
|
356
356
|
|
|
@@ -394,18 +394,16 @@ Source ideas moved to done: $IDEAS_MOVED
|
|
|
394
394
|
Research documents moved to done: $RESEARCH_DOCS_MOVED (if any)
|
|
395
395
|
|
|
396
396
|
What would you like to do next?
|
|
397
|
-
1.
|
|
398
|
-
2.
|
|
399
|
-
3. Nothing for now -- the spec is saved and ready when you are
|
|
397
|
+
1. Start a milestone from this spec -> /dgs:new-milestone --auto $SPEC_ID
|
|
398
|
+
2. Nothing for now -- the spec is saved and ready when you are
|
|
400
399
|
```
|
|
401
400
|
|
|
402
|
-
In interactive mode, use AskUserQuestion: "Choose 1
|
|
401
|
+
In interactive mode, use AskUserQuestion: "Choose 1 or 2 (or just press enter to defer):"
|
|
403
402
|
|
|
404
|
-
- If **1**: Tell user "Run `/dgs:new-
|
|
405
|
-
- If **2
|
|
406
|
-
- If **3** or empty/enter: Output "Spec saved. You can find it at `${project_root}/specs/$FILENAME`."
|
|
403
|
+
- If **1**: Tell user "Run `/dgs:new-milestone --auto $SPEC_ID` to start a milestone from this spec. If no project exists yet, run `/dgs:new-project` first to create the project holder, then `/dgs:new-milestone --auto $SPEC_ID`."
|
|
404
|
+
- If **2** or empty/enter: Output "Spec saved. You can find it at `specs/$FILENAME` (planning root)."
|
|
407
405
|
|
|
408
|
-
In `--auto` mode: skip the routing question, just output the summary with the
|
|
406
|
+
In `--auto` mode: skip the routing question, just output the summary with the two options listed for reference.
|
|
409
407
|
</step>
|
|
410
408
|
|
|
411
409
|
</process>
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// DGS Workflow Discipline Enforcement - PreToolUse + PostToolUse hook
|
|
3
|
+
//
|
|
4
|
+
// Ensures Edit/Write tool calls only happen inside /dgs:* commands.
|
|
5
|
+
// Works via a marker file that tracks active DGS command state:
|
|
6
|
+
//
|
|
7
|
+
// 1. When tool_name is "Skill" and the skill name starts with "dgs:":
|
|
8
|
+
// - PreToolUse: Write a marker file to /tmp/dgs-active-{session_id}.json
|
|
9
|
+
// - PostToolUse: Delete the marker, then check for uncommitted DGS files
|
|
10
|
+
//
|
|
11
|
+
// 2. When tool_name is "Edit" or "Write":
|
|
12
|
+
// - Check for marker file — if present, allow
|
|
13
|
+
// - Check if target path is in the allowlist — if so, allow
|
|
14
|
+
// - Check if cwd is a DGS planning folder — if not, allow (non-DGS project)
|
|
15
|
+
// - Otherwise, deny with explanation
|
|
16
|
+
//
|
|
17
|
+
// Safety net: After every /dgs:* command completes, checks for uncommitted
|
|
18
|
+
// DGS-managed files and auto-commits them. Logs a warning so the upstream
|
|
19
|
+
// workflow bug can be identified and fixed.
|
|
20
|
+
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const os = require('os');
|
|
23
|
+
const path = require('path');
|
|
24
|
+
const { execSync } = require('child_process');
|
|
25
|
+
|
|
26
|
+
// Paths where Edit/Write is allowed without a DGS command
|
|
27
|
+
const ALLOWED_PATH_PATTERNS = [
|
|
28
|
+
/\.claude\/projects\/.*\/memory\//, // Auto-memory system
|
|
29
|
+
/\.claude\/.*\/memory\//, // Memory in any .claude subfolder
|
|
30
|
+
/\/tmp\//, // Temp files
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
// DGS-managed paths that should be committed (relative to planning root)
|
|
34
|
+
// Used by the safety net to detect orphaned writes after a command completes
|
|
35
|
+
const DGS_MANAGED_PATTERNS = [
|
|
36
|
+
/^STATE\.md$/,
|
|
37
|
+
/^PROJECTS\.md$/,
|
|
38
|
+
/^MILESTONES\.md$/,
|
|
39
|
+
/^RETROSPECTIVE\.md$/,
|
|
40
|
+
/^CLAUDE\.md$/,
|
|
41
|
+
/^config\.json$/,
|
|
42
|
+
/^projects\/[^/]+\/STATE\.md$/,
|
|
43
|
+
/^projects\/[^/]+\/ROADMAP\.md$/,
|
|
44
|
+
/^projects\/[^/]+\/REQUIREMENTS\.md$/,
|
|
45
|
+
/^projects\/[^/]+\/PROJECT\.md$/,
|
|
46
|
+
/^projects\/[^/]+\/phases\//,
|
|
47
|
+
/^projects\/[^/]+\/milestones\//,
|
|
48
|
+
/^specs\//,
|
|
49
|
+
/^ideas\//,
|
|
50
|
+
/^todos\//,
|
|
51
|
+
/^jobs\//,
|
|
52
|
+
/^quick\//,
|
|
53
|
+
/^milestones\//,
|
|
54
|
+
/^codebase\//,
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
function getMarkerPath(sessionId) {
|
|
58
|
+
return path.join(os.tmpdir(), `dgs-active-${sessionId}.json`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isDgsProject(cwd) {
|
|
62
|
+
try {
|
|
63
|
+
const configPath = path.join(cwd, 'config.json');
|
|
64
|
+
if (!fs.existsSync(configPath)) return false;
|
|
65
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
66
|
+
return content.includes('"product_name"');
|
|
67
|
+
} catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isAllowedPath(filePath) {
|
|
73
|
+
if (!filePath) return false;
|
|
74
|
+
return ALLOWED_PATH_PATTERNS.some(pattern => pattern.test(filePath));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getTargetPath(toolName, toolInput) {
|
|
78
|
+
if (!toolInput) return null;
|
|
79
|
+
// Edit and Write both use file_path
|
|
80
|
+
return toolInput.file_path || null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let input = '';
|
|
84
|
+
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
85
|
+
process.stdin.setEncoding('utf8');
|
|
86
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
87
|
+
process.stdin.on('end', () => {
|
|
88
|
+
clearTimeout(stdinTimeout);
|
|
89
|
+
try {
|
|
90
|
+
const data = JSON.parse(input);
|
|
91
|
+
const sessionId = data.session_id;
|
|
92
|
+
const hookEvent = data.hook_event_name;
|
|
93
|
+
const toolName = data.tool_name;
|
|
94
|
+
const toolInput = data.tool_input || {};
|
|
95
|
+
const cwd = data.cwd || process.cwd();
|
|
96
|
+
|
|
97
|
+
// ── PostToolUse: Clean up marker + safety net when Skill completes ──
|
|
98
|
+
if (hookEvent === 'PostToolUse') {
|
|
99
|
+
if (toolName === 'Skill') {
|
|
100
|
+
const skillName = toolInput.skill || toolInput.name || '';
|
|
101
|
+
if (skillName.startsWith('dgs:')) {
|
|
102
|
+
// Delete the active marker
|
|
103
|
+
const markerPath = getMarkerPath(sessionId);
|
|
104
|
+
try { fs.unlinkSync(markerPath); } catch { /* already gone */ }
|
|
105
|
+
|
|
106
|
+
// Safety net: check for uncommitted DGS-managed files
|
|
107
|
+
if (isDgsProject(cwd)) {
|
|
108
|
+
try {
|
|
109
|
+
const status = execSync('git status --porcelain', { cwd, encoding: 'utf-8', timeout: 5000 });
|
|
110
|
+
if (status.trim()) {
|
|
111
|
+
const lines = status.trim().split('\n');
|
|
112
|
+
const dirty = lines
|
|
113
|
+
.map(l => l.slice(3).trim()) // strip status prefix (e.g., " M ", "?? ")
|
|
114
|
+
.filter(f => DGS_MANAGED_PATTERNS.some(p => p.test(f)));
|
|
115
|
+
|
|
116
|
+
if (dirty.length > 0) {
|
|
117
|
+
// Stage and commit orphaned DGS files
|
|
118
|
+
for (const f of dirty) {
|
|
119
|
+
execSync(`git add "${f}"`, { cwd, stdio: 'pipe', timeout: 5000 });
|
|
120
|
+
}
|
|
121
|
+
const msg = `chore: auto-commit ${dirty.length} uncommitted DGS file(s) after ${skillName}`;
|
|
122
|
+
execSync(`git commit -m "${msg}"`, { cwd, stdio: 'pipe', timeout: 10000 });
|
|
123
|
+
|
|
124
|
+
// Warn via additionalContext so Claude sees it
|
|
125
|
+
const result = {
|
|
126
|
+
continue: true,
|
|
127
|
+
suppressOutput: false,
|
|
128
|
+
hookSpecificOutput: {
|
|
129
|
+
hookEventName: 'PostToolUse',
|
|
130
|
+
additionalContext: `[DGS safety net] Auto-committed ${dirty.length} orphaned file(s) after ${skillName}: ${dirty.join(', ')}. This indicates a missing commit in the ${skillName} workflow — consider fixing upstream.`,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
process.stdout.write(JSON.stringify(result));
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch { /* git not available or commit failed — don't block */ }
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ── PreToolUse: Skill → write marker ──
|
|
145
|
+
if (hookEvent === 'PreToolUse' && toolName === 'Skill') {
|
|
146
|
+
const skillName = toolInput.skill || toolInput.name || '';
|
|
147
|
+
if (skillName.startsWith('dgs:')) {
|
|
148
|
+
const markerPath = getMarkerPath(sessionId);
|
|
149
|
+
const marker = {
|
|
150
|
+
command: skillName,
|
|
151
|
+
started: new Date().toISOString(),
|
|
152
|
+
session_id: sessionId,
|
|
153
|
+
};
|
|
154
|
+
fs.writeFileSync(markerPath, JSON.stringify(marker));
|
|
155
|
+
}
|
|
156
|
+
process.exit(0);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ── PreToolUse: Edit/Write → check marker ──
|
|
160
|
+
if (hookEvent === 'PreToolUse' && (toolName === 'Edit' || toolName === 'Write')) {
|
|
161
|
+
// Not a DGS project? Allow everything.
|
|
162
|
+
if (!isDgsProject(cwd)) {
|
|
163
|
+
process.exit(0);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Target path in allowlist? Allow.
|
|
167
|
+
const targetPath = getTargetPath(toolName, toolInput);
|
|
168
|
+
if (isAllowedPath(targetPath)) {
|
|
169
|
+
process.exit(0);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// DGS command active? Allow.
|
|
173
|
+
const markerPath = getMarkerPath(sessionId);
|
|
174
|
+
if (fs.existsSync(markerPath)) {
|
|
175
|
+
process.exit(0);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// No DGS command active in a DGS project — deny.
|
|
179
|
+
const result = {
|
|
180
|
+
hookSpecificOutput: {
|
|
181
|
+
hookEventName: 'PreToolUse',
|
|
182
|
+
permissionDecision: 'deny',
|
|
183
|
+
permissionDecisionReason: 'DGS workflow discipline: Edit/Write requires an active /dgs:* command. Use /dgs:fast (trivial), /dgs:quick (small), or /dgs:execute-phase (feature). Say "skip DGS" to bypass.',
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
process.stdout.write(JSON.stringify(result));
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Any other tool/event — allow
|
|
191
|
+
process.exit(0);
|
|
192
|
+
} catch {
|
|
193
|
+
// Parse error or unexpected input — don't block
|
|
194
|
+
process.exit(0);
|
|
195
|
+
}
|
|
196
|
+
});
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"bugs": {
|
|
9
9
|
"url": "https://github.com/KT-Partners-Ltd/dgs-platform-docs/issues"
|
|
10
10
|
},
|
|
11
|
-
"version": "
|
|
11
|
+
"version": "3.3.0",
|
|
12
12
|
"description": "Deliver Great Systems Platform — A meta-prompting, context engineering and spec-driven development system for Claude Code and Gemini by KT Partners.",
|
|
13
13
|
"bin": {
|
|
14
14
|
"dgs": "bin/install.js"
|