get-shit-done-cc 1.22.0 → 1.22.2
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/agents/gsd-codebase-mapper.md +9 -1
- package/agents/gsd-debugger.md +10 -0
- package/agents/gsd-executor.md +11 -2
- package/agents/gsd-integration-checker.md +2 -0
- package/agents/gsd-phase-researcher.md +9 -1
- package/agents/gsd-plan-checker.md +3 -1
- package/agents/gsd-planner.md +16 -3
- package/agents/gsd-project-researcher.md +10 -0
- package/agents/gsd-research-synthesizer.md +10 -0
- package/agents/gsd-roadmapper.md +11 -1
- package/agents/gsd-verifier.md +8 -0
- package/bin/install.js +51 -26
- package/commands/gsd/discuss-phase.md +14 -10
- package/commands/gsd/reapply-patches.md +17 -4
- package/commands/gsd/research-phase.md +4 -4
- package/get-shit-done/bin/gsd-tools.cjs +6 -2
- package/get-shit-done/bin/lib/commands.cjs +3 -3
- package/get-shit-done/bin/lib/core.cjs +53 -2
- package/get-shit-done/bin/lib/milestone.cjs +22 -48
- package/get-shit-done/bin/lib/phase.cjs +27 -4
- package/get-shit-done/bin/lib/state.cjs +100 -59
- package/get-shit-done/bin/lib/template.cjs +3 -3
- package/get-shit-done/references/checkpoints.md +1 -1
- package/get-shit-done/references/decimal-phase-calculation.md +2 -2
- package/get-shit-done/references/phase-argument-parsing.md +1 -1
- package/get-shit-done/references/questioning.md +17 -0
- package/get-shit-done/workflows/diagnose-issues.md +1 -1
- package/get-shit-done/workflows/discuss-phase.md +106 -46
- package/get-shit-done/workflows/execute-phase.md +13 -4
- package/get-shit-done/workflows/new-milestone.md +3 -2
- package/get-shit-done/workflows/new-project.md +10 -18
- package/get-shit-done/workflows/plan-milestone-gaps.md +1 -1
- package/get-shit-done/workflows/plan-phase.md +27 -48
- package/get-shit-done/workflows/quick.md +2 -2
- package/get-shit-done/workflows/transition.md +2 -2
- package/get-shit-done/workflows/update.md +35 -10
- package/hooks/dist/gsd-check-update.js +22 -3
- package/hooks/dist/gsd-context-monitor.js +28 -9
- package/hooks/dist/gsd-statusline.js +19 -12
- package/package.json +1 -1
- package/commands/gsd/new-project.md.bak +0 -1041
|
@@ -3,6 +3,14 @@ name: gsd-codebase-mapper
|
|
|
3
3
|
description: Explores codebase and writes structured analysis documents. Spawned by map-codebase with a focus area (tech, arch, quality, concerns). Writes documents directly to reduce orchestrator context load.
|
|
4
4
|
tools: Read, Bash, Grep, Glob, Write
|
|
5
5
|
color: cyan
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-mapper-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
|
@@ -148,7 +156,7 @@ Write document(s) to `.planning/codebase/` using the templates below.
|
|
|
148
156
|
3. If something is not found, use "Not detected" or "Not applicable"
|
|
149
157
|
4. Always include file paths with backticks
|
|
150
158
|
|
|
151
|
-
|
|
159
|
+
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
|
|
152
160
|
</step>
|
|
153
161
|
|
|
154
162
|
<step name="return_confirmation">
|
package/agents/gsd-debugger.md
CHANGED
|
@@ -3,6 +3,14 @@ name: gsd-debugger
|
|
|
3
3
|
description: Investigates bugs using scientific method, manages debug sessions, handles checkpoints. Spawned by /gsd:debug orchestrator.
|
|
4
4
|
tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch
|
|
5
5
|
color: orange
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-debugger-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
|
@@ -849,6 +857,8 @@ ls .planning/debug/*.md 2>/dev/null | grep -v resolved
|
|
|
849
857
|
<step name="create_debug_file">
|
|
850
858
|
**Create debug file IMMEDIATELY.**
|
|
851
859
|
|
|
860
|
+
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
|
|
861
|
+
|
|
852
862
|
1. Generate slug from user input (lowercase, hyphens, max 30 chars)
|
|
853
863
|
2. `mkdir -p .planning/debug`
|
|
854
864
|
3. Create file with initial state:
|
package/agents/gsd-executor.md
CHANGED
|
@@ -3,6 +3,14 @@ name: gsd-executor
|
|
|
3
3
|
description: Executes GSD plans with atomic commits, deviation handling, checkpoint protocols, and state management. Spawned by execute-phase orchestrator or execute-plan command.
|
|
4
4
|
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
5
|
color: yellow
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-executor-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
|
@@ -197,13 +205,14 @@ Do NOT continue reading. Analysis without action is a stuck signal.
|
|
|
197
205
|
</authentication_gates>
|
|
198
206
|
|
|
199
207
|
<auto_mode_detection>
|
|
200
|
-
Check if auto mode is active at executor start:
|
|
208
|
+
Check if auto mode is active at executor start (chain flag or user preference):
|
|
201
209
|
|
|
202
210
|
```bash
|
|
211
|
+
AUTO_CHAIN=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get workflow._auto_chain_active 2>/dev/null || echo "false")
|
|
203
212
|
AUTO_CFG=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get workflow.auto_advance 2>/dev/null || echo "false")
|
|
204
213
|
```
|
|
205
214
|
|
|
206
|
-
Store the result for checkpoint handling below.
|
|
215
|
+
Auto mode is active if either `AUTO_CHAIN` or `AUTO_CFG` is `"true"`. Store the result for checkpoint handling below.
|
|
207
216
|
</auto_mode_detection>
|
|
208
217
|
|
|
209
218
|
<checkpoint_protocol>
|
|
@@ -3,6 +3,8 @@ name: gsd-integration-checker
|
|
|
3
3
|
description: Verifies cross-phase integration and E2E flows. Checks that phases connect properly and user workflows complete end-to-end.
|
|
4
4
|
tools: Read, Bash, Grep, Glob
|
|
5
5
|
color: blue
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-integration-workflow
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
<role>
|
|
@@ -3,6 +3,14 @@ name: gsd-phase-researcher
|
|
|
3
3
|
description: Researches how to implement a phase before planning. Produces RESEARCH.md consumed by gsd-planner. Spawned by /gsd:plan-phase orchestrator.
|
|
4
4
|
tools: Read, Write, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*
|
|
5
5
|
color: cyan
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-researcher-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
|
@@ -421,7 +429,7 @@ List missing test files, framework config, or shared fixtures needed before impl
|
|
|
421
429
|
|
|
422
430
|
## Step 6: Write RESEARCH.md
|
|
423
431
|
|
|
424
|
-
**ALWAYS use Write tool to
|
|
432
|
+
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation. Mandatory regardless of `commit_docs` setting.
|
|
425
433
|
|
|
426
434
|
**CRITICAL: If CONTEXT.md exists, FIRST content section MUST be `<user_constraints>`:**
|
|
427
435
|
|
|
@@ -3,6 +3,8 @@ name: gsd-plan-checker
|
|
|
3
3
|
description: Verifies plans will achieve phase goal before execution. Goal-backward analysis of plan quality. Spawned by /gsd:plan-phase orchestrator.
|
|
4
4
|
tools: Read, Bash, Glob, Grep
|
|
5
5
|
color: green
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-plan-checker-workflow
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
<role>
|
|
@@ -445,7 +447,7 @@ Session persists | 01 | 3 | COVERED
|
|
|
445
447
|
|
|
446
448
|
For each requirement: find covering task(s), verify action is specific, flag gaps.
|
|
447
449
|
|
|
448
|
-
**Exhaustive cross-check:** Also read PROJECT.md requirements (not just phase goal). Verify no PROJECT.md requirement relevant to this phase is silently dropped. Any unmapped requirement is an automatic blocker — list it explicitly in issues.
|
|
450
|
+
**Exhaustive cross-check:** Also read PROJECT.md requirements (not just phase goal). Verify no PROJECT.md requirement relevant to this phase is silently dropped. A requirement is "relevant" if the ROADMAP.md explicitly maps it to this phase or if the phase goal directly implies it — do NOT flag requirements that belong to other phases or future work. Any unmapped relevant requirement is an automatic blocker — list it explicitly in issues.
|
|
449
451
|
|
|
450
452
|
## Step 5: Validate Task Structure
|
|
451
453
|
|
package/agents/gsd-planner.md
CHANGED
|
@@ -3,6 +3,14 @@ name: gsd-planner
|
|
|
3
3
|
description: Creates executable phase plans with task breakdown, dependency analysis, and goal-backward verification. Spawned by /gsd:plan-phase orchestrator.
|
|
4
4
|
tools: Read, Write, Bash, Glob, Grep, WebFetch, mcp__context7__*
|
|
5
5
|
color: green
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-planner-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
|
@@ -844,15 +852,20 @@ grep -l "status: diagnosed" "$phase_dir"/*-UAT.md 2>/dev/null
|
|
|
844
852
|
</task>
|
|
845
853
|
```
|
|
846
854
|
|
|
847
|
-
**7.
|
|
855
|
+
**7. Assign waves using standard dependency analysis** (same as `assign_waves` step):
|
|
856
|
+
- Plans with no dependencies → wave 1
|
|
857
|
+
- Plans that depend on other gap closure plans → max(dependency waves) + 1
|
|
858
|
+
- Also consider dependencies on existing (non-gap) plans in the phase
|
|
859
|
+
|
|
860
|
+
**8. Write PLAN.md files:**
|
|
848
861
|
|
|
849
862
|
```yaml
|
|
850
863
|
---
|
|
851
864
|
phase: XX-name
|
|
852
865
|
plan: NN # Sequential after existing
|
|
853
866
|
type: execute
|
|
854
|
-
wave:
|
|
855
|
-
depends_on: []
|
|
867
|
+
wave: N # Computed from depends_on (see assign_waves)
|
|
868
|
+
depends_on: [...] # Other plans this depends on (gap or existing)
|
|
856
869
|
files_modified: [...]
|
|
857
870
|
autonomous: true
|
|
858
871
|
gap_closure: true # Flag for tracking
|
|
@@ -3,6 +3,14 @@ name: gsd-project-researcher
|
|
|
3
3
|
description: Researches domain ecosystem before roadmap creation. Produces files in .planning/research/ consumed during roadmap creation. Spawned by /gsd:new-project or /gsd:new-milestone orchestrators.
|
|
4
4
|
tools: Read, Write, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*
|
|
5
5
|
color: cyan
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-researcher-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
|
@@ -518,6 +526,8 @@ Run pre-submission checklist (see verification_protocol).
|
|
|
518
526
|
|
|
519
527
|
## Step 5: Write Output Files
|
|
520
528
|
|
|
529
|
+
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
|
|
530
|
+
|
|
521
531
|
In `.planning/research/`:
|
|
522
532
|
1. **SUMMARY.md** — Always
|
|
523
533
|
2. **STACK.md** — Always
|
|
@@ -3,6 +3,14 @@ name: gsd-research-synthesizer
|
|
|
3
3
|
description: Synthesizes research outputs from parallel researcher agents into SUMMARY.md. Spawned by /gsd:new-project after 4 researcher agents complete.
|
|
4
4
|
tools: Read, Write, Bash
|
|
5
5
|
color: purple
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-synthesizer-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
|
@@ -122,6 +130,8 @@ Identify gaps that couldn't be resolved and need attention during planning.
|
|
|
122
130
|
|
|
123
131
|
## Step 6: Write SUMMARY.md
|
|
124
132
|
|
|
133
|
+
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
|
|
134
|
+
|
|
125
135
|
Use template: ~/.claude/get-shit-done/templates/research-project/SUMMARY.md
|
|
126
136
|
|
|
127
137
|
Write to `.planning/research/SUMMARY.md`
|
package/agents/gsd-roadmapper.md
CHANGED
|
@@ -3,6 +3,14 @@ name: gsd-roadmapper
|
|
|
3
3
|
description: Creates project roadmaps with phase breakdown, requirement mapping, success criteria derivation, and coverage validation. Spawned by /gsd:new-project orchestrator.
|
|
4
4
|
tools: Read, Write, Bash, Glob, Grep
|
|
5
5
|
color: purple
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-roadmapper-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
|
@@ -449,7 +457,9 @@ If gaps found, include in draft for user decision.
|
|
|
449
457
|
|
|
450
458
|
## Step 7: Write Files Immediately
|
|
451
459
|
|
|
452
|
-
**Write files
|
|
460
|
+
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
|
|
461
|
+
|
|
462
|
+
Write files first, then return. This ensures artifacts persist even if context is lost.
|
|
453
463
|
|
|
454
464
|
1. **Write ROADMAP.md** using output format
|
|
455
465
|
|
package/agents/gsd-verifier.md
CHANGED
|
@@ -3,6 +3,14 @@ name: gsd-verifier
|
|
|
3
3
|
description: Verifies phase goal achievement through goal-backward analysis. Checks codebase delivers what phase promised, not just that tasks completed. Creates VERIFICATION.md report.
|
|
4
4
|
tools: Read, Write, Bash, Grep, Glob
|
|
5
5
|
color: green
|
|
6
|
+
skills:
|
|
7
|
+
- gsd-verifier-workflow
|
|
8
|
+
# hooks:
|
|
9
|
+
# PostToolUse:
|
|
10
|
+
# - matcher: "Write|Edit"
|
|
11
|
+
# hooks:
|
|
12
|
+
# - type: command
|
|
13
|
+
# command: "npx eslint --fix $FILE 2>/dev/null || true"
|
|
6
14
|
---
|
|
7
15
|
|
|
8
16
|
<role>
|
package/bin/install.js
CHANGED
|
@@ -638,9 +638,31 @@ function mergeCodexConfig(configPath, gsdBlock) {
|
|
|
638
638
|
|
|
639
639
|
// Case 2: Has GSD marker — truncate and re-append
|
|
640
640
|
if (markerIndex !== -1) {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
641
|
+
let before = existing.substring(0, markerIndex).trimEnd();
|
|
642
|
+
if (before) {
|
|
643
|
+
// Strip any GSD-managed sections that leaked above the marker from previous installs
|
|
644
|
+
before = before.replace(/^\[agents\.gsd-[^\]]+\]\n(?:(?!\[)[^\n]*\n?)*/gm, '');
|
|
645
|
+
before = before.replace(/^\[agents\]\n(?:(?!\[)[^\n]*\n?)*/m, '');
|
|
646
|
+
before = before.replace(/\n{3,}/g, '\n\n').trimEnd();
|
|
647
|
+
|
|
648
|
+
// Re-inject feature keys if user has [features] above the marker
|
|
649
|
+
const hasFeatures = /^\[features\]\s*$/m.test(before);
|
|
650
|
+
if (hasFeatures) {
|
|
651
|
+
if (!before.includes('multi_agent')) {
|
|
652
|
+
before = before.replace(/^\[features\]\s*$/m, '[features]\nmulti_agent = true');
|
|
653
|
+
}
|
|
654
|
+
if (!before.includes('default_mode_request_user_input')) {
|
|
655
|
+
before = before.replace(/^\[features\].*$/m, '$&\ndefault_mode_request_user_input = true');
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
// Skip [features] from gsdBlock if user already has it
|
|
659
|
+
const block = hasFeatures
|
|
660
|
+
? GSD_CODEX_MARKER + '\n' + gsdBlock.substring(gsdBlock.indexOf('[agents]'))
|
|
661
|
+
: gsdBlock;
|
|
662
|
+
fs.writeFileSync(configPath, before + '\n\n' + block + '\n');
|
|
663
|
+
} else {
|
|
664
|
+
fs.writeFileSync(configPath, gsdBlock + '\n');
|
|
665
|
+
}
|
|
644
666
|
return;
|
|
645
667
|
}
|
|
646
668
|
|
|
@@ -1403,24 +1425,26 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
1403
1425
|
}
|
|
1404
1426
|
}
|
|
1405
1427
|
|
|
1406
|
-
// Remove GSD hooks from PostToolUse
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1428
|
+
// Remove GSD hooks from PostToolUse and AfterTool (Gemini uses AfterTool)
|
|
1429
|
+
for (const eventName of ['PostToolUse', 'AfterTool']) {
|
|
1430
|
+
if (settings.hooks && settings.hooks[eventName]) {
|
|
1431
|
+
const before = settings.hooks[eventName].length;
|
|
1432
|
+
settings.hooks[eventName] = settings.hooks[eventName].filter(entry => {
|
|
1433
|
+
if (entry.hooks && Array.isArray(entry.hooks)) {
|
|
1434
|
+
const hasGsdHook = entry.hooks.some(h =>
|
|
1435
|
+
h.command && h.command.includes('gsd-context-monitor')
|
|
1436
|
+
);
|
|
1437
|
+
return !hasGsdHook;
|
|
1438
|
+
}
|
|
1439
|
+
return true;
|
|
1440
|
+
});
|
|
1441
|
+
if (settings.hooks[eventName].length < before) {
|
|
1442
|
+
settingsModified = true;
|
|
1443
|
+
console.log(` ${green}✓${reset} Removed context monitor hook from settings`);
|
|
1444
|
+
}
|
|
1445
|
+
if (settings.hooks[eventName].length === 0) {
|
|
1446
|
+
delete settings.hooks[eventName];
|
|
1415
1447
|
}
|
|
1416
|
-
return true;
|
|
1417
|
-
});
|
|
1418
|
-
if (settings.hooks.PostToolUse.length < before) {
|
|
1419
|
-
settingsModified = true;
|
|
1420
|
-
console.log(` ${green}✓${reset} Removed context monitor hook from settings`);
|
|
1421
|
-
}
|
|
1422
|
-
if (settings.hooks.PostToolUse.length === 0) {
|
|
1423
|
-
delete settings.hooks.PostToolUse;
|
|
1424
1448
|
}
|
|
1425
1449
|
}
|
|
1426
1450
|
|
|
@@ -2031,7 +2055,8 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
2031
2055
|
}
|
|
2032
2056
|
|
|
2033
2057
|
// Configure statusline and hooks in settings.json
|
|
2034
|
-
// Gemini
|
|
2058
|
+
// Gemini uses AfterTool instead of PostToolUse for post-tool hooks
|
|
2059
|
+
const postToolEvent = runtime === 'gemini' ? 'AfterTool' : 'PostToolUse';
|
|
2035
2060
|
const settingsPath = path.join(targetDir, 'settings.json');
|
|
2036
2061
|
const settings = cleanupOrphanedHooks(readSettings(settingsPath));
|
|
2037
2062
|
const statuslineCommand = isGlobal
|
|
@@ -2080,17 +2105,17 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
2080
2105
|
console.log(` ${green}✓${reset} Configured update check hook`);
|
|
2081
2106
|
}
|
|
2082
2107
|
|
|
2083
|
-
// Configure
|
|
2084
|
-
if (!settings.hooks
|
|
2085
|
-
settings.hooks
|
|
2108
|
+
// Configure post-tool hook for context window monitoring
|
|
2109
|
+
if (!settings.hooks[postToolEvent]) {
|
|
2110
|
+
settings.hooks[postToolEvent] = [];
|
|
2086
2111
|
}
|
|
2087
2112
|
|
|
2088
|
-
const hasContextMonitorHook = settings.hooks.
|
|
2113
|
+
const hasContextMonitorHook = settings.hooks[postToolEvent].some(entry =>
|
|
2089
2114
|
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('gsd-context-monitor'))
|
|
2090
2115
|
);
|
|
2091
2116
|
|
|
2092
2117
|
if (!hasContextMonitorHook) {
|
|
2093
|
-
settings.hooks.
|
|
2118
|
+
settings.hooks[postToolEvent].push({
|
|
2094
2119
|
hooks: [
|
|
2095
2120
|
{
|
|
2096
2121
|
type: 'command',
|
|
@@ -18,10 +18,12 @@ allowed-tools:
|
|
|
18
18
|
Extract implementation decisions that downstream agents need — researcher and planner will use CONTEXT.md to know what to investigate and what choices are locked.
|
|
19
19
|
|
|
20
20
|
**How it works:**
|
|
21
|
-
1.
|
|
22
|
-
2.
|
|
23
|
-
3.
|
|
24
|
-
4.
|
|
21
|
+
1. Load prior context (PROJECT.md, REQUIREMENTS.md, STATE.md, prior CONTEXT.md files)
|
|
22
|
+
2. Scout codebase for reusable assets and patterns
|
|
23
|
+
3. Analyze phase — skip gray areas already decided in prior phases
|
|
24
|
+
4. Present remaining gray areas — user selects which to discuss
|
|
25
|
+
5. Deep-dive each selected area until satisfied
|
|
26
|
+
6. Create CONTEXT.md with decisions that guide research and planning
|
|
25
27
|
|
|
26
28
|
**Output:** `{phase_num}-CONTEXT.md` — decisions clear enough that downstream agents can act without asking the user again
|
|
27
29
|
</objective>
|
|
@@ -40,12 +42,13 @@ Context files are resolved in-workflow using `init phase-op` and roadmap/state t
|
|
|
40
42
|
<process>
|
|
41
43
|
1. Validate phase number (error if missing or not in roadmap)
|
|
42
44
|
2. Check if CONTEXT.md exists (offer update/view/skip if yes)
|
|
43
|
-
3. **
|
|
44
|
-
4. **
|
|
45
|
-
5. **
|
|
46
|
-
6. **
|
|
47
|
-
7. **
|
|
48
|
-
8.
|
|
45
|
+
3. **Load prior context** — Read PROJECT.md, REQUIREMENTS.md, STATE.md, and all prior CONTEXT.md files
|
|
46
|
+
4. **Scout codebase** — Find reusable assets, patterns, and integration points
|
|
47
|
+
5. **Analyze phase** — Check prior decisions, skip already-decided areas, generate remaining gray areas
|
|
48
|
+
6. **Present gray areas** — Multi-select: which to discuss? Annotate with prior decisions + code context
|
|
49
|
+
7. **Deep-dive each area** — 4 questions per area, code-informed options, Context7 for library choices
|
|
50
|
+
8. **Write CONTEXT.md** — Sections match areas discussed + code_context section
|
|
51
|
+
9. Offer next steps (research or plan)
|
|
49
52
|
|
|
50
53
|
**CRITICAL: Scope guardrail**
|
|
51
54
|
- Phase boundary from ROADMAP.md is FIXED
|
|
@@ -77,6 +80,7 @@ Generate 3-4 **phase-specific** gray areas, not generic categories.
|
|
|
77
80
|
</process>
|
|
78
81
|
|
|
79
82
|
<success_criteria>
|
|
83
|
+
- Prior context loaded and applied (no re-asking decided questions)
|
|
80
84
|
- Gray areas identified through intelligent analysis
|
|
81
85
|
- User chose which areas to discuss
|
|
82
86
|
- Each selected area explored until satisfied
|
|
@@ -14,11 +14,24 @@ After a GSD update wipes and reinstalls files, this command merges user's previo
|
|
|
14
14
|
Check for local patches directory:
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
# Global install
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
# Global install — detect runtime config directory
|
|
18
|
+
if [ -d "$HOME/.config/opencode/gsd-local-patches" ]; then
|
|
19
|
+
PATCHES_DIR="$HOME/.config/opencode/gsd-local-patches"
|
|
20
|
+
elif [ -d "$HOME/.opencode/gsd-local-patches" ]; then
|
|
21
|
+
PATCHES_DIR="$HOME/.opencode/gsd-local-patches"
|
|
22
|
+
elif [ -d "$HOME/.gemini/gsd-local-patches" ]; then
|
|
23
|
+
PATCHES_DIR="$HOME/.gemini/gsd-local-patches"
|
|
24
|
+
else
|
|
25
|
+
PATCHES_DIR="$HOME/.claude/gsd-local-patches"
|
|
26
|
+
fi
|
|
27
|
+
# Local install fallback — check all runtime directories
|
|
20
28
|
if [ ! -d "$PATCHES_DIR" ]; then
|
|
21
|
-
|
|
29
|
+
for dir in .config/opencode .opencode .gemini .claude; do
|
|
30
|
+
if [ -d "./$dir/gsd-local-patches" ]; then
|
|
31
|
+
PATCHES_DIR="./$dir/gsd-local-patches"
|
|
32
|
+
break
|
|
33
|
+
fi
|
|
34
|
+
done
|
|
22
35
|
fi
|
|
23
36
|
```
|
|
24
37
|
|
|
@@ -135,8 +135,8 @@ Write to: .planning/phases/${PHASE}-{slug}/${PHASE}-RESEARCH.md
|
|
|
135
135
|
|
|
136
136
|
```
|
|
137
137
|
Task(
|
|
138
|
-
prompt=
|
|
139
|
-
subagent_type="
|
|
138
|
+
prompt=filled_prompt,
|
|
139
|
+
subagent_type="gsd-phase-researcher",
|
|
140
140
|
model="{researcher_model}",
|
|
141
141
|
description="Research Phase {phase}"
|
|
142
142
|
)
|
|
@@ -171,8 +171,8 @@ Continue research for Phase {phase_number}: {phase_name}
|
|
|
171
171
|
|
|
172
172
|
```
|
|
173
173
|
Task(
|
|
174
|
-
prompt=
|
|
175
|
-
subagent_type="
|
|
174
|
+
prompt=continuation_prompt,
|
|
175
|
+
subagent_type="gsd-phase-researcher",
|
|
176
176
|
model="{researcher_model}",
|
|
177
177
|
description="Continue research Phase {phase}"
|
|
178
178
|
)
|
|
@@ -259,9 +259,13 @@ async function main() {
|
|
|
259
259
|
|
|
260
260
|
case 'commit': {
|
|
261
261
|
const amend = args.includes('--amend');
|
|
262
|
-
const message = args[1];
|
|
263
|
-
// Parse --files flag (collect args after --files, stopping at other flags)
|
|
264
262
|
const filesIndex = args.indexOf('--files');
|
|
263
|
+
// Collect all positional args between command name and first flag,
|
|
264
|
+
// then join them — handles both quoted ("multi word msg") and
|
|
265
|
+
// unquoted (multi word msg) invocations from different shells
|
|
266
|
+
const endIndex = filesIndex !== -1 ? filesIndex : args.length;
|
|
267
|
+
const messageArgs = args.slice(1, endIndex).filter(a => !a.startsWith('--'));
|
|
268
|
+
const message = messageArgs.join(' ') || undefined;
|
|
265
269
|
const files = filesIndex !== -1 ? args.slice(filesIndex + 1).filter(a => !a.startsWith('--')) : [];
|
|
266
270
|
commands.cmdCommit(cwd, message, files, raw, amend);
|
|
267
271
|
break;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const { execSync } = require('child_process');
|
|
7
|
-
const { safeReadFile, loadConfig, isGitIgnored, execGit, normalizePhaseName, comparePhaseNum, getArchivedPhaseDirs, generateSlugInternal, getMilestoneInfo, resolveModelInternal, MODEL_PROFILES, output, error, findPhaseInternal } = require('./core.cjs');
|
|
7
|
+
const { safeReadFile, loadConfig, isGitIgnored, execGit, normalizePhaseName, comparePhaseNum, getArchivedPhaseDirs, generateSlugInternal, getMilestoneInfo, resolveModelInternal, MODEL_PROFILES, toPosixPath, output, error, findPhaseInternal } = require('./core.cjs');
|
|
8
8
|
const { extractFrontmatter } = require('./frontmatter.cjs');
|
|
9
9
|
|
|
10
10
|
function cmdGenerateSlug(text, raw) {
|
|
@@ -68,7 +68,7 @@ function cmdListTodos(cwd, area, raw) {
|
|
|
68
68
|
created: createdMatch ? createdMatch[1].trim() : 'unknown',
|
|
69
69
|
title: titleMatch ? titleMatch[1].trim() : 'Untitled',
|
|
70
70
|
area: todoArea,
|
|
71
|
-
path: path.join('.planning', 'todos', 'pending', file),
|
|
71
|
+
path: toPosixPath(path.join('.planning', 'todos', 'pending', file)),
|
|
72
72
|
});
|
|
73
73
|
} catch {}
|
|
74
74
|
}
|
|
@@ -528,7 +528,7 @@ function cmdScaffold(cwd, type, options, raw) {
|
|
|
528
528
|
}
|
|
529
529
|
|
|
530
530
|
fs.writeFileSync(filePath, content, 'utf-8');
|
|
531
|
-
const relPath = path.relative(cwd, filePath);
|
|
531
|
+
const relPath = toPosixPath(path.relative(cwd, filePath));
|
|
532
532
|
output({ created: true, path: relPath }, raw, relPath);
|
|
533
533
|
}
|
|
534
534
|
|
|
@@ -124,7 +124,11 @@ function loadConfig(cwd) {
|
|
|
124
124
|
|
|
125
125
|
function isGitIgnored(cwd, targetPath) {
|
|
126
126
|
try {
|
|
127
|
-
|
|
127
|
+
// --no-index checks .gitignore rules regardless of whether the file is tracked.
|
|
128
|
+
// Without it, git check-ignore returns "not ignored" for tracked files even when
|
|
129
|
+
// .gitignore explicitly lists them — a common source of confusion when .planning/
|
|
130
|
+
// was committed before being added to .gitignore.
|
|
131
|
+
execSync('git check-ignore -q --no-index -- ' + targetPath.replace(/[^a-zA-Z0-9._\-/]/g, ''), {
|
|
128
132
|
cwd,
|
|
129
133
|
stdio: 'pipe',
|
|
130
134
|
});
|
|
@@ -388,7 +392,18 @@ function generateSlugInternal(text) {
|
|
|
388
392
|
function getMilestoneInfo(cwd) {
|
|
389
393
|
try {
|
|
390
394
|
const roadmap = fs.readFileSync(path.join(cwd, '.planning', 'ROADMAP.md'), 'utf-8');
|
|
391
|
-
|
|
395
|
+
|
|
396
|
+
// First: check for list-format roadmaps using 🚧 (in-progress) marker
|
|
397
|
+
// e.g. "- 🚧 **v2.1 Belgium** — Phases 24-28 (in progress)"
|
|
398
|
+
const inProgressMatch = roadmap.match(/🚧\s*\*\*v(\d+\.\d+)\s+([^*]+)\*\*/);
|
|
399
|
+
if (inProgressMatch) {
|
|
400
|
+
return {
|
|
401
|
+
version: 'v' + inProgressMatch[1],
|
|
402
|
+
name: inProgressMatch[2].trim(),
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Second: heading-format roadmaps — strip shipped milestones in <details> blocks
|
|
392
407
|
const cleaned = roadmap.replace(/<details>[\s\S]*?<\/details>/gi, '');
|
|
393
408
|
// Extract version and name from the same ## heading for consistency
|
|
394
409
|
const headingMatch = cleaned.match(/## .*v(\d+\.\d+)[:\s]+([^\n(]+)/);
|
|
@@ -409,6 +424,41 @@ function getMilestoneInfo(cwd) {
|
|
|
409
424
|
}
|
|
410
425
|
}
|
|
411
426
|
|
|
427
|
+
/**
|
|
428
|
+
* Returns a filter function that checks whether a phase directory belongs
|
|
429
|
+
* to the current milestone based on ROADMAP.md phase headings.
|
|
430
|
+
* If no ROADMAP exists or no phases are listed, returns a pass-all filter.
|
|
431
|
+
*/
|
|
432
|
+
function getMilestonePhaseFilter(cwd) {
|
|
433
|
+
const milestonePhaseNums = new Set();
|
|
434
|
+
try {
|
|
435
|
+
const roadmap = fs.readFileSync(path.join(cwd, '.planning', 'ROADMAP.md'), 'utf-8');
|
|
436
|
+
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
|
|
437
|
+
let m;
|
|
438
|
+
while ((m = phasePattern.exec(roadmap)) !== null) {
|
|
439
|
+
milestonePhaseNums.add(m[1]);
|
|
440
|
+
}
|
|
441
|
+
} catch {}
|
|
442
|
+
|
|
443
|
+
if (milestonePhaseNums.size === 0) {
|
|
444
|
+
const passAll = () => true;
|
|
445
|
+
passAll.phaseCount = 0;
|
|
446
|
+
return passAll;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const normalized = new Set(
|
|
450
|
+
[...milestonePhaseNums].map(n => (n.replace(/^0+/, '') || '0').toLowerCase())
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
function isDirInMilestone(dirName) {
|
|
454
|
+
const m = dirName.match(/^0*(\d+[A-Za-z]?(?:\.\d+)*)/);
|
|
455
|
+
if (!m) return false;
|
|
456
|
+
return normalized.has(m[1].toLowerCase());
|
|
457
|
+
}
|
|
458
|
+
isDirInMilestone.phaseCount = milestonePhaseNums.size;
|
|
459
|
+
return isDirInMilestone;
|
|
460
|
+
}
|
|
461
|
+
|
|
412
462
|
module.exports = {
|
|
413
463
|
MODEL_PROFILES,
|
|
414
464
|
output,
|
|
@@ -428,5 +478,6 @@ module.exports = {
|
|
|
428
478
|
pathExistsInternal,
|
|
429
479
|
generateSlugInternal,
|
|
430
480
|
getMilestoneInfo,
|
|
481
|
+
getMilestonePhaseFilter,
|
|
431
482
|
toPosixPath,
|
|
432
483
|
};
|