gsd-pi 2.15.0 → 2.16.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/README.md +1 -0
- package/dist/resource-loader.d.ts +1 -0
- package/dist/resource-loader.js +10 -1
- package/dist/resources/GSD-WORKFLOW.md +70 -68
- package/dist/resources/extensions/async-jobs/async-bash-tool.ts +2 -1
- package/dist/resources/extensions/async-jobs/await-tool.ts +5 -3
- package/dist/resources/extensions/async-jobs/cancel-job-tool.ts +2 -1
- package/dist/resources/extensions/async-jobs/index.ts +3 -3
- package/dist/resources/extensions/gsd/auto-dashboard.ts +14 -0
- package/dist/resources/extensions/gsd/auto-dispatch.ts +31 -1
- package/dist/resources/extensions/gsd/auto-prompts.ts +91 -2
- package/dist/resources/extensions/gsd/auto-recovery.ts +64 -28
- package/dist/resources/extensions/gsd/auto-supervisor.ts +2 -7
- package/dist/resources/extensions/gsd/auto-worktree.ts +53 -106
- package/dist/resources/extensions/gsd/auto.ts +70 -13
- package/dist/resources/extensions/gsd/commands.ts +93 -27
- package/dist/resources/extensions/gsd/doctor.ts +12 -22
- package/dist/resources/extensions/gsd/files.ts +154 -2
- package/dist/resources/extensions/gsd/git-self-heal.ts +4 -4
- package/dist/resources/extensions/gsd/git-service.ts +23 -23
- package/dist/resources/extensions/gsd/gitignore.ts +2 -5
- package/dist/resources/extensions/gsd/guided-flow.ts +11 -11
- package/dist/resources/extensions/gsd/index.ts +10 -3
- package/dist/resources/extensions/gsd/native-git-bridge.ts +843 -12
- package/dist/resources/extensions/gsd/native-parser-bridge.ts +128 -1
- package/dist/resources/extensions/gsd/paths.ts +89 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +4 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +4 -0
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +4 -0
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +4 -0
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +4 -0
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +32 -0
- package/dist/resources/extensions/gsd/prompts/run-uat.md +4 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/provider-error-pause.ts +1 -1
- package/dist/resources/extensions/gsd/session-forensics.ts +29 -12
- package/dist/resources/extensions/gsd/state.ts +1 -38
- package/dist/resources/extensions/gsd/tests/agent-end-provider-error.test.ts +2 -2
- package/dist/resources/extensions/gsd/tests/auto-dashboard.test.ts +153 -0
- package/dist/resources/extensions/gsd/tests/auto-recovery.test.ts +272 -0
- package/dist/resources/extensions/gsd/tests/auto-worktree.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/complete-milestone.test.ts +3 -0
- package/dist/resources/extensions/gsd/tests/crash-recovery.test.ts +134 -0
- package/dist/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/overrides.test.ts +131 -0
- package/dist/resources/extensions/gsd/tests/preferences-git.test.ts +5 -5
- package/dist/resources/extensions/gsd/tests/preferences-hooks.test.ts +7 -6
- package/dist/resources/extensions/gsd/tests/reassess-prompt.test.ts +3 -0
- package/dist/resources/extensions/gsd/tests/replan-slice.test.ts +3 -0
- package/dist/resources/extensions/gsd/tests/run-uat.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +1 -1
- package/dist/resources/extensions/gsd/undo.ts +26 -19
- package/dist/resources/extensions/gsd/worktree-command.ts +2 -2
- package/dist/resources/extensions/gsd/worktree-manager.ts +81 -134
- package/package.json +3 -2
- package/packages/pi-ai/dist/providers/google-shared.d.ts +3 -0
- package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.js +63 -5
- package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/packages/pi-ai/src/providers/google-shared.ts +66 -6
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-editor.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/extensions/types.ts +1 -1
- package/packages/pi-coding-agent/src/core/model-resolver.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/custom-editor.ts +8 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +1 -1
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +1 -1
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +4 -2
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/src/components/editor.ts +5 -3
- package/src/resources/GSD-WORKFLOW.md +70 -68
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +2 -1
- package/src/resources/extensions/async-jobs/await-tool.ts +5 -3
- package/src/resources/extensions/async-jobs/cancel-job-tool.ts +2 -1
- package/src/resources/extensions/async-jobs/index.ts +3 -3
- package/src/resources/extensions/gsd/auto-dashboard.ts +14 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +31 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +91 -2
- package/src/resources/extensions/gsd/auto-recovery.ts +64 -28
- package/src/resources/extensions/gsd/auto-supervisor.ts +2 -7
- package/src/resources/extensions/gsd/auto-worktree.ts +53 -106
- package/src/resources/extensions/gsd/auto.ts +70 -13
- package/src/resources/extensions/gsd/commands.ts +93 -27
- package/src/resources/extensions/gsd/doctor.ts +12 -22
- package/src/resources/extensions/gsd/files.ts +154 -2
- package/src/resources/extensions/gsd/git-self-heal.ts +4 -4
- package/src/resources/extensions/gsd/git-service.ts +23 -23
- package/src/resources/extensions/gsd/gitignore.ts +2 -5
- package/src/resources/extensions/gsd/guided-flow.ts +11 -11
- package/src/resources/extensions/gsd/index.ts +10 -3
- package/src/resources/extensions/gsd/native-git-bridge.ts +843 -12
- package/src/resources/extensions/gsd/native-parser-bridge.ts +128 -1
- package/src/resources/extensions/gsd/paths.ts +89 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +4 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +4 -0
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +4 -0
- package/src/resources/extensions/gsd/prompts/replan-slice.md +4 -0
- package/src/resources/extensions/gsd/prompts/research-milestone.md +4 -0
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +32 -0
- package/src/resources/extensions/gsd/prompts/run-uat.md +4 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/provider-error-pause.ts +1 -1
- package/src/resources/extensions/gsd/session-forensics.ts +29 -12
- package/src/resources/extensions/gsd/state.ts +1 -38
- package/src/resources/extensions/gsd/tests/agent-end-provider-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +153 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +272 -0
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/overrides.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/preferences-git.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/preferences-hooks.test.ts +7 -6
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +1 -1
- package/src/resources/extensions/gsd/undo.ts +26 -19
- package/src/resources/extensions/gsd/worktree-command.ts +2 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +81 -134
package/README.md
CHANGED
|
@@ -213,6 +213,7 @@ On first run, GSD launches a branded setup wizard that walks you through LLM pro
|
|
|
213
213
|
| `/gsd next` | Explicit step mode (same as bare `/gsd`) |
|
|
214
214
|
| `/gsd auto` | Autonomous mode — researches, plans, executes, commits, repeats |
|
|
215
215
|
| `/gsd stop` | Stop auto mode gracefully |
|
|
216
|
+
| `/gsd steer` | Hard-steer plan documents during execution |
|
|
216
217
|
| `/gsd discuss` | Discuss architecture and decisions (works alongside auto mode) |
|
|
217
218
|
| `/gsd status` | Progress dashboard |
|
|
218
219
|
| `/gsd queue` | Queue future milestones (safe during auto mode) |
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DefaultResourceLoader } from '@gsd/pi-coding-agent';
|
|
2
2
|
export declare function discoverExtensionEntryPaths(extensionsDir: string): string[];
|
|
3
3
|
export declare function readManagedResourceVersion(agentDir: string): string | null;
|
|
4
|
+
export declare function readManagedResourceSyncedAt(agentDir: string): number | null;
|
|
4
5
|
export declare function getNewerManagedResourceVersion(agentDir: string, currentVersion: string): string | null;
|
|
5
6
|
/**
|
|
6
7
|
* Syncs all bundled resources to agentDir (~/.gsd/agent/) on every launch.
|
package/dist/resource-loader.js
CHANGED
|
@@ -85,7 +85,7 @@ function getBundledGsdVersion() {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
function writeManagedResourceManifest(agentDir) {
|
|
88
|
-
const manifest = { gsdVersion: getBundledGsdVersion() };
|
|
88
|
+
const manifest = { gsdVersion: getBundledGsdVersion(), syncedAt: Date.now() };
|
|
89
89
|
writeFileSync(getManagedResourceManifestPath(agentDir), JSON.stringify(manifest));
|
|
90
90
|
}
|
|
91
91
|
export function readManagedResourceVersion(agentDir) {
|
|
@@ -97,6 +97,15 @@ export function readManagedResourceVersion(agentDir) {
|
|
|
97
97
|
return null;
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
+
export function readManagedResourceSyncedAt(agentDir) {
|
|
101
|
+
try {
|
|
102
|
+
const manifest = JSON.parse(readFileSync(getManagedResourceManifestPath(agentDir), 'utf-8'));
|
|
103
|
+
return typeof manifest?.syncedAt === 'number' ? manifest.syncedAt : null;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
100
109
|
export function getNewerManagedResourceVersion(agentDir, currentVersion) {
|
|
101
110
|
const managedVersion = readManagedResourceVersion(agentDir);
|
|
102
111
|
if (!managedVersion) {
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
>
|
|
5
5
|
> **When to read this:** At the start of any session working on GSD-managed work, or when loaded by `/gsd`.
|
|
6
6
|
>
|
|
7
|
-
> **After reading this, always read `.gsd/
|
|
8
|
-
> If the milestone has a `
|
|
7
|
+
> **After reading this, always read `.gsd/STATE.md` to find out what's next.**
|
|
8
|
+
> If the milestone has a `M###-CONTEXT.md`, read that too. If the active slice has an `S##-CONTEXT.md`, read that as well — these files contain project-specific decisions, reference paths, and implementation guidance that this generic methodology doc does not.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -13,13 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
Read these files in order and act on what they say:
|
|
15
15
|
|
|
16
|
-
1. **`.gsd/
|
|
17
|
-
2. **`.gsd/milestones/<active>/
|
|
18
|
-
3. **`.gsd/milestones/<active>/
|
|
19
|
-
4. If a slice is active, read
|
|
20
|
-
5. If a
|
|
16
|
+
1. **`.gsd/STATE.md`** — Where are we? What's the next action?
|
|
17
|
+
2. **`.gsd/milestones/<active>/M###-ROADMAP.md`** — What's the plan? Which slices are done? (`STATE.md` tells you which milestone is active)
|
|
18
|
+
3. **`.gsd/milestones/<active>/M###-CONTEXT.md`** — Milestone-level project decisions, reference paths, constraints. Read this before doing implementation work.
|
|
19
|
+
4. If a slice is active and has one, read **`S##-CONTEXT.md`** — Slice-specific decisions and constraints.
|
|
20
|
+
5. If a slice is active, read its **`S##-PLAN.md`** — Which tasks exist? Which are done?
|
|
21
|
+
6. If a task was interrupted, check for **`continue.md`** in the active slice directory — Resume from there.
|
|
21
22
|
|
|
22
|
-
Then do the thing `
|
|
23
|
+
Then do the thing `STATE.md` says to do next.
|
|
23
24
|
|
|
24
25
|
---
|
|
25
26
|
|
|
@@ -41,32 +42,32 @@ All artifacts live in `.gsd/` at the project root:
|
|
|
41
42
|
|
|
42
43
|
```
|
|
43
44
|
.gsd/
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
STATE.md # Dashboard — always read first (derived cache; runtime, gitignored)
|
|
46
|
+
DECISIONS.md # Append-only decisions register
|
|
46
47
|
milestones/
|
|
47
48
|
M001/
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
M001-ROADMAP.md # Milestone plan (checkboxes = state)
|
|
50
|
+
M001-CONTEXT.md # Optional: user decisions from discuss phase
|
|
51
|
+
M001-RESEARCH.md # Optional: codebase/tech research
|
|
52
|
+
M001-SUMMARY.md # Milestone rollup (updated as slices complete)
|
|
52
53
|
slices/
|
|
53
54
|
S01/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
S01-PLAN.md # Task decomposition for this slice
|
|
56
|
+
S01-CONTEXT.md # Optional: slice-level user decisions
|
|
57
|
+
S01-RESEARCH.md # Optional: slice-level research
|
|
58
|
+
S01-SUMMARY.md # Slice summary (written on completion)
|
|
59
|
+
S01-UAT.md # Non-blocking human test script (written on completion)
|
|
59
60
|
continue.md # Ephemeral: resume point if interrupted
|
|
60
61
|
tasks/
|
|
61
|
-
T01-
|
|
62
|
-
T01-
|
|
62
|
+
T01-PLAN.md # Individual task plan
|
|
63
|
+
T01-SUMMARY.md # Task summary with frontmatter
|
|
63
64
|
```
|
|
64
65
|
|
|
65
66
|
---
|
|
66
67
|
|
|
67
68
|
## File Format Reference
|
|
68
69
|
|
|
69
|
-
### `
|
|
70
|
+
### `M###-ROADMAP.md`
|
|
70
71
|
|
|
71
72
|
```markdown
|
|
72
73
|
# M001: Title of the Milestone
|
|
@@ -93,7 +94,7 @@ All artifacts live in `.gsd/` at the project root:
|
|
|
93
94
|
|
|
94
95
|
**Parsing rules:** `- [x]` = done, `- [ ]` = not done. The `risk:` and `depends:[]` tags are inline metadata parsed from the line. `depends:[]` lists slice IDs this slice requires to be complete first.
|
|
95
96
|
|
|
96
|
-
**Boundary Map** (required section in
|
|
97
|
+
**Boundary Map** (required section in M###-ROADMAP.md):
|
|
97
98
|
|
|
98
99
|
After the slices section, include a `## Boundary Map` that shows what each slice produces and consumes:
|
|
99
100
|
|
|
@@ -123,7 +124,7 @@ The boundary map is a **planning artifact** — not runnable code. It:
|
|
|
123
124
|
- Enables deterministic verification that slices actually connect
|
|
124
125
|
- Gets updated during slice planning if new interfaces emerge
|
|
125
126
|
|
|
126
|
-
### `
|
|
127
|
+
### `S##-PLAN.md` (slice-level)
|
|
127
128
|
|
|
128
129
|
```markdown
|
|
129
130
|
# S01: Slice Title
|
|
@@ -148,7 +149,7 @@ The boundary map is a **planning artifact** — not runnable code. It:
|
|
|
148
149
|
- path/to/another.ts
|
|
149
150
|
```
|
|
150
151
|
|
|
151
|
-
### `
|
|
152
|
+
### `T##-PLAN.md` (task-level)
|
|
152
153
|
|
|
153
154
|
```markdown
|
|
154
155
|
# T01: Task Title
|
|
@@ -188,7 +189,7 @@ Critical wiring between artifacts:
|
|
|
188
189
|
|
|
189
190
|
**Must-haves are what make verification mechanically checkable.** Truths are checked by running commands or reading output. Artifacts are checked by confirming files exist with real content. Key links are checked by confirming imports/references actually connect the pieces.
|
|
190
191
|
|
|
191
|
-
### `
|
|
192
|
+
### `STATE.md`
|
|
192
193
|
|
|
193
194
|
```markdown
|
|
194
195
|
# GSD State
|
|
@@ -209,10 +210,10 @@ Critical wiring between artifacts:
|
|
|
209
210
|
Exact next thing to do.
|
|
210
211
|
```
|
|
211
212
|
|
|
212
|
-
### `
|
|
213
|
+
### `M###-CONTEXT.md` / `S##-CONTEXT.md` (from discuss phase)
|
|
213
214
|
|
|
214
215
|
```markdown
|
|
215
|
-
#
|
|
216
|
+
# M001: Milestone or Slice Title — Context
|
|
216
217
|
|
|
217
218
|
**Gathered:** 2026-03-07
|
|
218
219
|
**Status:** Ready for planning
|
|
@@ -228,7 +229,7 @@ Exact next thing to do.
|
|
|
228
229
|
- Ideas that came up but belong in other slices
|
|
229
230
|
```
|
|
230
231
|
|
|
231
|
-
### `
|
|
232
|
+
### `DECISIONS.md` (append-only register)
|
|
232
233
|
|
|
233
234
|
```markdown
|
|
234
235
|
# Decisions Register
|
|
@@ -265,7 +266,7 @@ Work flows through these phases. Each phase produces a file.
|
|
|
265
266
|
### Phase 1: Discuss (Optional)
|
|
266
267
|
|
|
267
268
|
**Purpose:** Capture user decisions on gray areas before planning.
|
|
268
|
-
**Produces:** `
|
|
269
|
+
**Produces:** `M###-CONTEXT.md` for milestone-level discussion or `S##-CONTEXT.md` for slice-level discussion.
|
|
269
270
|
**When to use:** When the scope has ambiguities the user should weigh in on.
|
|
270
271
|
**When to skip:** When the user already knows exactly what they want, or told you to just go.
|
|
271
272
|
|
|
@@ -273,18 +274,18 @@ Work flows through these phases. Each phase produces a file.
|
|
|
273
274
|
1. Read the roadmap to understand the scope.
|
|
274
275
|
2. Identify 3-5 gray areas — implementation decisions the user cares about.
|
|
275
276
|
3. Use `ask_user_questions` to discuss each area.
|
|
276
|
-
4. Write decisions to `
|
|
277
|
+
4. Write decisions to the appropriate context file (`M###-CONTEXT.md` or `S##-CONTEXT.md`).
|
|
277
278
|
5. Do NOT discuss how to implement — only what the user wants.
|
|
278
279
|
|
|
279
280
|
### Phase 2: Research (Optional)
|
|
280
281
|
|
|
281
282
|
**Purpose:** Scout the codebase and relevant docs before planning.
|
|
282
|
-
**Produces:** `
|
|
283
|
+
**Produces:** `M###-RESEARCH.md` at milestone level or `S##-RESEARCH.md` at slice level.
|
|
283
284
|
**When to use:** When working in unfamiliar code, with unfamiliar libraries, or on complex integrations.
|
|
284
285
|
**When to skip:** When the codebase is familiar and the work is straightforward.
|
|
285
286
|
|
|
286
287
|
**How to do it manually:**
|
|
287
|
-
1. Read `
|
|
288
|
+
1. Read `M###-CONTEXT.md` and/or `S##-CONTEXT.md` if they exist — know what decisions are locked.
|
|
288
289
|
2. Scout relevant code: `rg`, `find`, read key files.
|
|
289
290
|
3. Use `resolve_library` / `get_library_docs` if needed.
|
|
290
291
|
4. Write findings to `research.md` with these sections:
|
|
@@ -324,24 +325,24 @@ The **Don't Hand-Roll** and **Common Pitfalls** sections prevent the most expens
|
|
|
324
325
|
### Phase 3: Plan
|
|
325
326
|
|
|
326
327
|
**Purpose:** Decompose work into context-window-sized tasks with must-haves.
|
|
327
|
-
**Produces:** `
|
|
328
|
+
**Produces:** `S##-PLAN.md` + individual `T01-PLAN.md` files.
|
|
328
329
|
|
|
329
330
|
**For a milestone (roadmap):**
|
|
330
|
-
1. Read `
|
|
331
|
+
1. Read `M###-CONTEXT.md`, `M###-RESEARCH.md`, and `.gsd/DECISIONS.md` if they exist.
|
|
331
332
|
2. Decompose the vision into 4-10 demoable vertical slices.
|
|
332
333
|
3. Order by risk (high-risk first to validate feasibility early).
|
|
333
|
-
4. Write `
|
|
334
|
+
4. Write `M###-ROADMAP.md` with checkboxes, risk levels, dependencies, demo sentences.
|
|
334
335
|
5. **Write the boundary map** — for each slice, specify what it produces (functions, types, interfaces, endpoints) and what it consumes from upstream slices. This forces interface thinking before implementation and enables deterministic verification that slices actually connect.
|
|
335
336
|
|
|
336
337
|
**For a slice (task decomposition):**
|
|
337
|
-
1. Read the slice's entry in `
|
|
338
|
-
2. Read `
|
|
338
|
+
1. Read the slice's entry in `M###-ROADMAP.md` **and its boundary map section** — know what interfaces this slice must produce and consume.
|
|
339
|
+
2. Read `M###-CONTEXT.md`, `S##-CONTEXT.md`, `M###-RESEARCH.md`, `S##-RESEARCH.md`, and `.gsd/DECISIONS.md` if they exist for this slice.
|
|
339
340
|
3. Read summaries from dependency slices (check `depends:[]` in roadmap).
|
|
340
341
|
4. Verify that upstream slices' actual outputs match what the boundary map says this slice consumes. If they diverge, update the boundary map.
|
|
341
342
|
5. Decompose into 1-7 tasks, each fitting one context window.
|
|
342
343
|
6. Each task needs: title, description, steps (3-10), must-haves (observable verification criteria).
|
|
343
344
|
7. Must-haves should reference boundary map contracts — e.g. "exports `generateToken()` as specified in boundary map S01→S02".
|
|
344
|
-
8. Write `
|
|
345
|
+
8. Write `S##-PLAN.md` and individual `T##-PLAN.md` files.
|
|
345
346
|
|
|
346
347
|
### Phase 4: Execute
|
|
347
348
|
|
|
@@ -349,10 +350,10 @@ The **Don't Hand-Roll** and **Common Pitfalls** sections prevent the most expens
|
|
|
349
350
|
**Produces:** Code changes + `[DONE:n]` markers.
|
|
350
351
|
|
|
351
352
|
**How to do it manually:**
|
|
352
|
-
1. Read the task's `
|
|
353
|
+
1. Read the task's `T##-PLAN.md`.
|
|
353
354
|
2. Read relevant summaries from prior tasks (for context on what's already built).
|
|
354
355
|
3. Execute each step. Mark progress with `[DONE:n]` in responses.
|
|
355
|
-
4. If you made an architectural, pattern, or library decision, append it to `.gsd/
|
|
356
|
+
4. If you made an architectural, pattern, or library decision, append it to `.gsd/DECISIONS.md`.
|
|
356
357
|
5. If interrupted or context is getting full, write `continue.md` (see below).
|
|
357
358
|
|
|
358
359
|
### Phase 5: Verify
|
|
@@ -400,7 +401,7 @@ When verification finds gaps, include a **Gaps** section with what's missing, im
|
|
|
400
401
|
### Phase 6: Summarize
|
|
401
402
|
|
|
402
403
|
**Purpose:** Record what happened for downstream tasks.
|
|
403
|
-
**Produces:** `
|
|
404
|
+
**Produces:** `T##-SUMMARY.md`, and when slice completes, `S##-SUMMARY.md`.
|
|
404
405
|
|
|
405
406
|
**Task summary format:**
|
|
406
407
|
```markdown
|
|
@@ -421,7 +422,7 @@ key_decisions:
|
|
|
421
422
|
patterns_established:
|
|
422
423
|
- "Pattern name and where it lives"
|
|
423
424
|
drill_down_paths:
|
|
424
|
-
- .gsd/milestones/M001/slices/S01/tasks/T01-
|
|
425
|
+
- .gsd/milestones/M001/slices/S01/tasks/T01-PLAN.md
|
|
425
426
|
duration: 15min
|
|
426
427
|
verification_result: pass
|
|
427
428
|
completed_at: 2026-03-07T16:00:00Z
|
|
@@ -445,7 +446,7 @@ What differed from the plan and why (or "None").
|
|
|
445
446
|
|
|
446
447
|
The one-liner must be substantive: "JWT auth with refresh rotation using jose" not "Authentication implemented."
|
|
447
448
|
|
|
448
|
-
**Slice summary:** Written when all tasks in a slice complete. Compresses all task summaries. Includes `drill_down_paths` to each task summary. During slice completion, review task summaries for `key_decisions` and ensure any significant ones are captured in `.gsd/
|
|
449
|
+
**Slice summary:** Written when all tasks in a slice complete. Compresses all task summaries. Includes `drill_down_paths` to each task summary. During slice completion, review task summaries for `key_decisions` and ensure any significant ones are captured in `.gsd/DECISIONS.md`.
|
|
449
450
|
|
|
450
451
|
**Milestone summary:** Updated each time a slice completes. Compresses all slice summaries. This is what gets injected into later slice planning instead of loading many individual summaries.
|
|
451
452
|
|
|
@@ -454,16 +455,16 @@ The one-liner must be substantive: "JWT auth with refresh rotation using jose" n
|
|
|
454
455
|
**Purpose:** Mark work done and move to the next thing.
|
|
455
456
|
|
|
456
457
|
**After a task completes:**
|
|
457
|
-
1. Mark the task done in `
|
|
458
|
+
1. Mark the task done in `S##-PLAN.md` (checkbox).
|
|
458
459
|
2. Check if there's a next task in the slice → execute it.
|
|
459
|
-
3. If slice is complete → write slice summary, mark slice done in `
|
|
460
|
+
3. If slice is complete → write slice summary, mark slice done in `M###-ROADMAP.md`.
|
|
460
461
|
|
|
461
462
|
**After a slice completes:**
|
|
462
|
-
1. Write slice `
|
|
463
|
-
2. Write slice `
|
|
464
|
-
3. Mark the slice checkbox in `
|
|
465
|
-
4. Update `
|
|
466
|
-
5. Update milestone `
|
|
463
|
+
1. Write slice `S##-SUMMARY.md` (compresses all task summaries).
|
|
464
|
+
2. Write slice `S##-UAT.md` — a non-blocking human test script derived from the slice's must-haves and demo sentence. The agent does NOT wait for UAT results.
|
|
465
|
+
3. Mark the slice checkbox in `M###-ROADMAP.md` as `[x]`.
|
|
466
|
+
4. Update `STATE.md` with new position.
|
|
467
|
+
5. Update milestone `M###-SUMMARY.md` with the completed slice's contributions.
|
|
467
468
|
6. Continue to next slice immediately. The user tests the UAT whenever convenient.
|
|
468
469
|
7. If the user reports UAT failures later, create fix tasks in the current or a new slice.
|
|
469
470
|
8. If all slices done → milestone complete.
|
|
@@ -513,17 +514,17 @@ The EXACT first thing to do when resuming. Not vague. Specific.
|
|
|
513
514
|
|
|
514
515
|
## State Management
|
|
515
516
|
|
|
516
|
-
### `
|
|
517
|
+
### `STATE.md` is a derived cache
|
|
517
518
|
|
|
518
519
|
It is NOT the source of truth. It's a convenience dashboard.
|
|
519
520
|
|
|
520
521
|
**Sources of truth:**
|
|
521
|
-
- `
|
|
522
|
-
- `
|
|
523
|
-
- `
|
|
524
|
-
- `
|
|
522
|
+
- `M###-ROADMAP.md` → which slices exist and which are done
|
|
523
|
+
- `S##-PLAN.md` → which tasks exist within a slice
|
|
524
|
+
- `T##-SUMMARY.md` → what happened during a task
|
|
525
|
+
- `S##-SUMMARY.md` and `M###-SUMMARY.md` → compressed slice and milestone outcomes
|
|
525
526
|
|
|
526
|
-
**Update `
|
|
527
|
+
**Update `STATE.md`** after every significant action:
|
|
527
528
|
- Active milestone/slice/task
|
|
528
529
|
- Recent decisions (last 3-5)
|
|
529
530
|
- Blockers
|
|
@@ -611,9 +612,9 @@ Tasks completed:
|
|
|
611
612
|
|
|
612
613
|
When planning or executing a task, load relevant prior context:
|
|
613
614
|
|
|
614
|
-
1. Check the current slice's `depends:[]` in `
|
|
615
|
+
1. Check the current slice's `depends:[]` in `M###-ROADMAP.md`.
|
|
615
616
|
2. Load summaries from those dependency slices.
|
|
616
|
-
3. Start with the **highest available level** — milestone `
|
|
617
|
+
3. Start with the **highest available level** — milestone `M###-SUMMARY.md` first.
|
|
617
618
|
4. Only drill down to slice/task summaries if you need specific detail.
|
|
618
619
|
5. Stay within **~2500 tokens** of total injected summary context.
|
|
619
620
|
6. If the dependency chain is too large, drop the oldest/least-relevant summaries first.
|
|
@@ -630,32 +631,33 @@ These are soft caps — exceed them when genuinely needed, but don't let summari
|
|
|
630
631
|
|
|
631
632
|
## Project-Specific Context
|
|
632
633
|
|
|
633
|
-
This methodology doc is generic. Project-specific guidance belongs in the milestone
|
|
634
|
+
This methodology doc is generic. Project-specific guidance belongs in the milestone and slice context files:
|
|
634
635
|
|
|
635
|
-
- **`.gsd/milestones/<active>/
|
|
636
|
+
- **`.gsd/milestones/<active>/M###-CONTEXT.md`** — milestone-level architecture decisions, reference file paths, and implementation constraints
|
|
637
|
+
- **`.gsd/milestones/<active>/slices/S##/S##-CONTEXT.md`** — slice-level decisions, edge cases, and narrow implementation guidance when present
|
|
636
638
|
|
|
637
|
-
**Always read the active milestone's `
|
|
639
|
+
**Always read the active milestone's `M###-CONTEXT.md` before starting implementation work.** If the active slice also has `S##-CONTEXT.md`, read that too. These files tell you what decisions are locked, what files to reference, and how to verify your work in this specific project.
|
|
638
640
|
|
|
639
641
|
---
|
|
640
642
|
|
|
641
643
|
## Checklist for a Fresh Session
|
|
642
644
|
|
|
643
|
-
1. Read `.gsd/
|
|
645
|
+
1. Read `.gsd/STATE.md` — what's the next action?
|
|
644
646
|
2. Check for `continue.md` in the active slice — is there interrupted work?
|
|
645
647
|
3. If resuming: read `continue.md`, delete it, pick up from "Next Action".
|
|
646
|
-
4. If starting fresh: read the active slice's `
|
|
647
|
-
5. If in a planning or research phase, read `.gsd/
|
|
648
|
+
4. If starting fresh: read the active slice's `S##-PLAN.md`, find the next incomplete task.
|
|
649
|
+
5. If in a planning or research phase, read `.gsd/DECISIONS.md` — respect existing decisions.
|
|
648
650
|
6. Read relevant summaries from prior tasks/slices for context.
|
|
649
651
|
7. Do the work.
|
|
650
652
|
8. Verify the must-haves.
|
|
651
653
|
9. Write the summary.
|
|
652
|
-
10. Mark done, update `
|
|
653
|
-
11. If context is getting full or you're done for now: write `continue.md` if mid-task, or update `
|
|
654
|
+
10. Mark done, update `STATE.md`, advance.
|
|
655
|
+
11. If context is getting full or you're done for now: write `continue.md` if mid-task, or update `STATE.md` with next action if between tasks.
|
|
654
656
|
|
|
655
657
|
## When Context Gets Large
|
|
656
658
|
|
|
657
659
|
If you sense context pressure (many files read, long execution, lots of tool output):
|
|
658
660
|
|
|
659
661
|
1. **If mid-task:** Write `continue.md` with exact resume state. Tell the user: "Context is getting full. I've saved progress to continue.md. Start a new session and run `/gsd` to pick up where you left off, or `/gsd auto` to resume in auto-execution mode."
|
|
660
|
-
2. **If between tasks:** Just update `
|
|
662
|
+
2. **If between tasks:** Just update `STATE.md` with the next action. No continue file needed — the next session will read STATE.md and pick up the next task cleanly.
|
|
661
663
|
3. **Don't fight it.** The whole system is designed for this. A fresh session with the right files loaded is better than a stale session with degraded reasoning.
|
|
@@ -71,7 +71,7 @@ export function createAsyncBashTool(
|
|
|
71
71
|
"Check /jobs to see all running and recent background jobs.",
|
|
72
72
|
],
|
|
73
73
|
parameters: schema,
|
|
74
|
-
async execute(_toolCallId, params) {
|
|
74
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
75
75
|
const manager = getManager();
|
|
76
76
|
const cwd = getCwd();
|
|
77
77
|
const { command, timeout, label } = params;
|
|
@@ -91,6 +91,7 @@ export function createAsyncBashTool(
|
|
|
91
91
|
"Use `await_job` to get results when ready, or `cancel_job` to stop.",
|
|
92
92
|
].join("\n"),
|
|
93
93
|
}],
|
|
94
|
+
details: undefined,
|
|
94
95
|
};
|
|
95
96
|
},
|
|
96
97
|
};
|
|
@@ -24,7 +24,7 @@ export function createAwaitTool(getManager: () => AsyncJobManager): ToolDefiniti
|
|
|
24
24
|
description:
|
|
25
25
|
"Wait for background jobs to complete. Provide specific job IDs or omit to wait for the next job that finishes. Returns results of completed jobs.",
|
|
26
26
|
parameters: schema,
|
|
27
|
-
async execute(_toolCallId, params) {
|
|
27
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
28
28
|
const manager = getManager();
|
|
29
29
|
const { jobs: jobIds } = params;
|
|
30
30
|
|
|
@@ -43,6 +43,7 @@ export function createAwaitTool(getManager: () => AsyncJobManager): ToolDefiniti
|
|
|
43
43
|
if (notFound.length > 0 && watched.length === 0) {
|
|
44
44
|
return {
|
|
45
45
|
content: [{ type: "text", text: `No jobs found: ${notFound.join(", ")}` }],
|
|
46
|
+
details: undefined,
|
|
46
47
|
};
|
|
47
48
|
}
|
|
48
49
|
} else {
|
|
@@ -50,6 +51,7 @@ export function createAwaitTool(getManager: () => AsyncJobManager): ToolDefiniti
|
|
|
50
51
|
if (watched.length === 0) {
|
|
51
52
|
return {
|
|
52
53
|
content: [{ type: "text", text: "No running background jobs." }],
|
|
54
|
+
details: undefined,
|
|
53
55
|
};
|
|
54
56
|
}
|
|
55
57
|
}
|
|
@@ -59,7 +61,7 @@ export function createAwaitTool(getManager: () => AsyncJobManager): ToolDefiniti
|
|
|
59
61
|
if (running.length === 0) {
|
|
60
62
|
const result = formatResults(watched);
|
|
61
63
|
manager.acknowledgeDeliveries(watched.map((j) => j.id));
|
|
62
|
-
return { content: [{ type: "text", text: result }] };
|
|
64
|
+
return { content: [{ type: "text", text: result }], details: undefined };
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
// Wait for at least one to complete
|
|
@@ -75,7 +77,7 @@ export function createAwaitTool(getManager: () => AsyncJobManager): ToolDefiniti
|
|
|
75
77
|
result += `\n\n**Still running:** ${stillRunning.map((j) => `${j.id} (${j.label})`).join(", ")}`;
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
return { content: [{ type: "text", text: result }] };
|
|
80
|
+
return { content: [{ type: "text", text: result }], details: undefined };
|
|
79
81
|
},
|
|
80
82
|
};
|
|
81
83
|
}
|
|
@@ -16,7 +16,7 @@ export function createCancelJobTool(getManager: () => AsyncJobManager): ToolDefi
|
|
|
16
16
|
label: "Cancel Background Job",
|
|
17
17
|
description: "Cancel a running background job by its ID.",
|
|
18
18
|
parameters: schema,
|
|
19
|
-
async execute(_toolCallId, params) {
|
|
19
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
20
20
|
const manager = getManager();
|
|
21
21
|
const result = manager.cancel(params.job_id);
|
|
22
22
|
|
|
@@ -28,6 +28,7 @@ export function createCancelJobTool(getManager: () => AsyncJobManager): ToolDefi
|
|
|
28
28
|
|
|
29
29
|
return {
|
|
30
30
|
content: [{ type: "text", text: messages[result] ?? `Unknown result: ${result}` }],
|
|
31
|
+
details: undefined,
|
|
31
32
|
};
|
|
32
33
|
},
|
|
33
34
|
};
|
|
@@ -62,7 +62,7 @@ export default function AsyncJobs(pi: ExtensionAPI) {
|
|
|
62
62
|
"",
|
|
63
63
|
truncatedOutput,
|
|
64
64
|
].join("\n"),
|
|
65
|
-
display:
|
|
65
|
+
display: true,
|
|
66
66
|
},
|
|
67
67
|
{ deliverAs: "followUp", triggerTurn: true },
|
|
68
68
|
);
|
|
@@ -92,7 +92,7 @@ export default function AsyncJobs(pi: ExtensionAPI) {
|
|
|
92
92
|
pi.sendMessage({
|
|
93
93
|
customType: "async_jobs_list",
|
|
94
94
|
content: "No async job manager active.",
|
|
95
|
-
display:
|
|
95
|
+
display: true,
|
|
96
96
|
});
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
@@ -126,7 +126,7 @@ export default function AsyncJobs(pi: ExtensionAPI) {
|
|
|
126
126
|
pi.sendMessage({
|
|
127
127
|
customType: "async_jobs_list",
|
|
128
128
|
content: lines.join("\n"),
|
|
129
|
-
display:
|
|
129
|
+
display: true,
|
|
130
130
|
});
|
|
131
131
|
},
|
|
132
132
|
});
|
|
@@ -49,6 +49,7 @@ export function unitVerb(unitType: string): string {
|
|
|
49
49
|
case "execute-task": return "executing";
|
|
50
50
|
case "complete-slice": return "completing";
|
|
51
51
|
case "replan-slice": return "replanning";
|
|
52
|
+
case "rewrite-docs": return "rewriting";
|
|
52
53
|
case "reassess-roadmap": return "reassessing";
|
|
53
54
|
case "run-uat": return "running UAT";
|
|
54
55
|
default: return unitType;
|
|
@@ -65,6 +66,7 @@ export function unitPhaseLabel(unitType: string): string {
|
|
|
65
66
|
case "execute-task": return "EXECUTE";
|
|
66
67
|
case "complete-slice": return "COMPLETE";
|
|
67
68
|
case "replan-slice": return "REPLAN";
|
|
69
|
+
case "rewrite-docs": return "REWRITE";
|
|
68
70
|
case "reassess-roadmap": return "REASSESS";
|
|
69
71
|
case "run-uat": return "UAT";
|
|
70
72
|
default: return unitType.toUpperCase();
|
|
@@ -88,6 +90,7 @@ function peekNext(unitType: string, state: GSDState): string {
|
|
|
88
90
|
case "execute-task": return `continue ${sid}`;
|
|
89
91
|
case "complete-slice": return "reassess roadmap";
|
|
90
92
|
case "replan-slice": return `re-execute ${sid}`;
|
|
93
|
+
case "rewrite-docs": return "continue execution";
|
|
91
94
|
case "reassess-roadmap": return "advance to next slice";
|
|
92
95
|
case "run-uat": return "reassess roadmap";
|
|
93
96
|
default: return "";
|
|
@@ -265,6 +268,16 @@ export function updateProgressWidget(
|
|
|
265
268
|
tui.requestRender();
|
|
266
269
|
}, 800);
|
|
267
270
|
|
|
271
|
+
// Refresh progress cache from disk every 5s so the widget reflects
|
|
272
|
+
// task/slice completion mid-unit. Without this, the progress bar only
|
|
273
|
+
// updates at dispatch time, appearing frozen during long-running units.
|
|
274
|
+
const progressRefreshTimer = mid ? setInterval(() => {
|
|
275
|
+
try {
|
|
276
|
+
updateSliceProgressCache(accessors.getBasePath(), mid.id, slice?.id);
|
|
277
|
+
cachedLines = undefined;
|
|
278
|
+
} catch { /* non-fatal */ }
|
|
279
|
+
}, 5_000) : null;
|
|
280
|
+
|
|
268
281
|
return {
|
|
269
282
|
render(width: number): string[] {
|
|
270
283
|
if (cachedLines && cachedWidth === width) return cachedLines;
|
|
@@ -416,6 +429,7 @@ export function updateProgressWidget(
|
|
|
416
429
|
},
|
|
417
430
|
dispose() {
|
|
418
431
|
clearInterval(pulseTimer);
|
|
432
|
+
if (progressRefreshTimer) clearInterval(progressRefreshTimer);
|
|
419
433
|
},
|
|
420
434
|
};
|
|
421
435
|
});
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import type { GSDState } from "./types.js";
|
|
13
13
|
import type { GSDPreferences } from "./preferences.js";
|
|
14
14
|
import type { UatType } from "./files.js";
|
|
15
|
-
import { loadFile, extractUatType } from "./files.js";
|
|
15
|
+
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
16
16
|
import {
|
|
17
17
|
resolveMilestoneFile, resolveSliceFile,
|
|
18
18
|
relSliceFile,
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
buildReplanSlicePrompt,
|
|
29
29
|
buildRunUatPrompt,
|
|
30
30
|
buildReassessRoadmapPrompt,
|
|
31
|
+
buildRewriteDocsPrompt,
|
|
31
32
|
checkNeedsReassessment,
|
|
32
33
|
checkNeedsRunUat,
|
|
33
34
|
} from "./auto-prompts.js";
|
|
@@ -54,9 +55,38 @@ interface DispatchRule {
|
|
|
54
55
|
match: (ctx: DispatchContext) => Promise<DispatchAction | null>;
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
// ─── Rewrite Circuit Breaker ──────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
const MAX_REWRITE_ATTEMPTS = 3;
|
|
61
|
+
let rewriteAttemptCount = 0;
|
|
62
|
+
export function resetRewriteCircuitBreaker(): void {
|
|
63
|
+
rewriteAttemptCount = 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
57
66
|
// ─── Rules ────────────────────────────────────────────────────────────────
|
|
58
67
|
|
|
59
68
|
const DISPATCH_RULES: DispatchRule[] = [
|
|
69
|
+
{
|
|
70
|
+
name: "rewrite-docs (override gate)",
|
|
71
|
+
match: async ({ mid, midTitle, state, basePath }) => {
|
|
72
|
+
const pendingOverrides = await loadActiveOverrides(basePath);
|
|
73
|
+
if (pendingOverrides.length === 0) return null;
|
|
74
|
+
if (rewriteAttemptCount >= MAX_REWRITE_ATTEMPTS) {
|
|
75
|
+
const { resolveAllOverrides } = await import("./files.js");
|
|
76
|
+
await resolveAllOverrides(basePath);
|
|
77
|
+
rewriteAttemptCount = 0;
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
rewriteAttemptCount++;
|
|
81
|
+
const unitId = state.activeSlice ? `${mid}/${state.activeSlice.id}` : mid;
|
|
82
|
+
return {
|
|
83
|
+
action: "dispatch",
|
|
84
|
+
unitType: "rewrite-docs",
|
|
85
|
+
unitId,
|
|
86
|
+
prompt: await buildRewriteDocsPrompt(mid, midTitle, state.activeSlice, basePath, pendingOverrides),
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
},
|
|
60
90
|
{
|
|
61
91
|
name: "summarizing → complete-slice",
|
|
62
92
|
match: async ({ state, mid, midTitle, basePath }) => {
|