gsd-pi 2.15.1 → 2.17.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/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 +7 -0
- package/dist/resources/extensions/gsd/auto-dispatch.ts +40 -4
- package/dist/resources/extensions/gsd/auto-prompts.ts +156 -43
- package/dist/resources/extensions/gsd/auto-recovery.ts +52 -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 +80 -25
- package/dist/resources/extensions/gsd/commands.ts +113 -29
- package/dist/resources/extensions/gsd/complexity.ts +236 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -0
- package/dist/resources/extensions/gsd/doctor.ts +12 -22
- package/dist/resources/extensions/gsd/files.ts +160 -4
- package/dist/resources/extensions/gsd/git-self-heal.ts +4 -4
- package/dist/resources/extensions/gsd/git-service.ts +40 -29
- package/dist/resources/extensions/gsd/gitignore.ts +43 -7
- package/dist/resources/extensions/gsd/guided-flow.ts +19 -15
- package/dist/resources/extensions/gsd/index.ts +10 -3
- package/dist/resources/extensions/gsd/metrics.ts +44 -0
- package/dist/resources/extensions/gsd/native-git-bridge.ts +848 -12
- package/dist/resources/extensions/gsd/native-parser-bridge.ts +133 -1
- package/dist/resources/extensions/gsd/paths.ts +89 -0
- package/dist/resources/extensions/gsd/preferences.ts +122 -1
- 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/rewrite-docs.md +32 -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/routing-history.ts +290 -0
- 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-recovery.test.ts +50 -0
- package/dist/resources/extensions/gsd/tests/auto-worktree.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/budget-prediction.test.ts +220 -0
- package/dist/resources/extensions/gsd/tests/complexity-routing.test.ts +294 -0
- package/dist/resources/extensions/gsd/tests/context-compression.test.ts +180 -0
- package/dist/resources/extensions/gsd/tests/git-service.test.ts +132 -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 +33 -5
- package/dist/resources/extensions/gsd/tests/preferences-hooks.test.ts +7 -6
- package/dist/resources/extensions/gsd/tests/routing-history.test.ts +87 -0
- package/dist/resources/extensions/gsd/tests/stop-auto-remote.test.ts +130 -0
- package/dist/resources/extensions/gsd/tests/token-profile.test.ts +263 -0
- package/dist/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +1 -1
- package/dist/resources/extensions/gsd/types.ts +28 -0
- package/dist/resources/extensions/gsd/undo.ts +24 -18
- package/dist/resources/extensions/gsd/worktree-command.ts +2 -2
- package/dist/resources/extensions/gsd/worktree-manager.ts +81 -134
- package/dist/resources/extensions/gsd/worktree.ts +2 -2
- package/package.json +3 -2
- package/packages/pi-ai/dist/models.generated.d.ts +493 -13
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +422 -62
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.d.ts +12 -0
- package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.js +9 -22
- package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-shared.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-shared.test.js +125 -0
- package/packages/pi-ai/dist/providers/google-shared.test.js.map +1 -0
- package/packages/pi-ai/src/models.generated.ts +422 -62
- package/packages/pi-ai/src/providers/google-shared.test.ts +137 -0
- package/packages/pi-ai/src/providers/google-shared.ts +10 -19
- 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/core/tools/edit-diff.d.ts +7 -7
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.js +209 -13
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +67 -0
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -0
- 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/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +10 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.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/core/tools/edit-diff.test.ts +85 -0
- package/packages/pi-coding-agent/src/core/tools/edit-diff.ts +245 -17
- 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/interactive/theme/theme.ts +13 -0
- 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/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +10 -0
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- 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 +7 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +40 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +156 -43
- package/src/resources/extensions/gsd/auto-recovery.ts +52 -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 +80 -25
- package/src/resources/extensions/gsd/commands.ts +113 -29
- package/src/resources/extensions/gsd/complexity.ts +236 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -0
- package/src/resources/extensions/gsd/doctor.ts +12 -22
- package/src/resources/extensions/gsd/files.ts +160 -4
- package/src/resources/extensions/gsd/git-self-heal.ts +4 -4
- package/src/resources/extensions/gsd/git-service.ts +40 -29
- package/src/resources/extensions/gsd/gitignore.ts +43 -7
- package/src/resources/extensions/gsd/guided-flow.ts +19 -15
- package/src/resources/extensions/gsd/index.ts +10 -3
- package/src/resources/extensions/gsd/metrics.ts +44 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +848 -12
- package/src/resources/extensions/gsd/native-parser-bridge.ts +133 -1
- package/src/resources/extensions/gsd/paths.ts +89 -0
- package/src/resources/extensions/gsd/preferences.ts +122 -1
- 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/rewrite-docs.md +32 -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/routing-history.ts +290 -0
- 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-recovery.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +220 -0
- package/src/resources/extensions/gsd/tests/complexity-routing.test.ts +294 -0
- package/src/resources/extensions/gsd/tests/context-compression.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +132 -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 +33 -5
- package/src/resources/extensions/gsd/tests/preferences-hooks.test.ts +7 -6
- package/src/resources/extensions/gsd/tests/routing-history.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +130 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +263 -0
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +1 -1
- package/src/resources/extensions/gsd/types.ts +28 -0
- package/src/resources/extensions/gsd/undo.ts +24 -18
- package/src/resources/extensions/gsd/worktree-command.ts +2 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +81 -134
- package/src/resources/extensions/gsd/worktree.ts +2 -2
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) |
|
|
@@ -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
|
});
|
|
@@ -35,6 +35,10 @@ export interface AutoDashboardData {
|
|
|
35
35
|
/** Running cost and token totals from metrics ledger */
|
|
36
36
|
totalCost: number;
|
|
37
37
|
totalTokens: number;
|
|
38
|
+
/** Projected remaining cost based on unit-type averages (undefined if insufficient data) */
|
|
39
|
+
projectedRemainingCost?: number;
|
|
40
|
+
/** Whether token profile has been auto-downgraded due to budget prediction */
|
|
41
|
+
profileDowngraded?: boolean;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
// ─── Unit Description Helpers ─────────────────────────────────────────────────
|
|
@@ -49,6 +53,7 @@ export function unitVerb(unitType: string): string {
|
|
|
49
53
|
case "execute-task": return "executing";
|
|
50
54
|
case "complete-slice": return "completing";
|
|
51
55
|
case "replan-slice": return "replanning";
|
|
56
|
+
case "rewrite-docs": return "rewriting";
|
|
52
57
|
case "reassess-roadmap": return "reassessing";
|
|
53
58
|
case "run-uat": return "running UAT";
|
|
54
59
|
default: return unitType;
|
|
@@ -65,6 +70,7 @@ export function unitPhaseLabel(unitType: string): string {
|
|
|
65
70
|
case "execute-task": return "EXECUTE";
|
|
66
71
|
case "complete-slice": return "COMPLETE";
|
|
67
72
|
case "replan-slice": return "REPLAN";
|
|
73
|
+
case "rewrite-docs": return "REWRITE";
|
|
68
74
|
case "reassess-roadmap": return "REASSESS";
|
|
69
75
|
case "run-uat": return "UAT";
|
|
70
76
|
default: return unitType.toUpperCase();
|
|
@@ -88,6 +94,7 @@ function peekNext(unitType: string, state: GSDState): string {
|
|
|
88
94
|
case "execute-task": return `continue ${sid}`;
|
|
89
95
|
case "complete-slice": return "reassess roadmap";
|
|
90
96
|
case "replan-slice": return `re-execute ${sid}`;
|
|
97
|
+
case "rewrite-docs": return "continue execution";
|
|
91
98
|
case "reassess-roadmap": return "advance to next slice";
|
|
92
99
|
case "run-uat": return "reassess roadmap";
|
|
93
100
|
default: return "";
|
|
@@ -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 }) => {
|
|
@@ -92,7 +122,9 @@ const DISPATCH_RULES: DispatchRule[] = [
|
|
|
92
122
|
},
|
|
93
123
|
{
|
|
94
124
|
name: "reassess-roadmap (post-completion)",
|
|
95
|
-
match: async ({ state, mid, midTitle, basePath }) => {
|
|
125
|
+
match: async ({ state, mid, midTitle, basePath, prefs }) => {
|
|
126
|
+
// Phase skip: skip reassess when preference or profile says so
|
|
127
|
+
if (prefs?.phases?.skip_reassess) return null;
|
|
96
128
|
const needsReassess = await checkNeedsReassessment(basePath, mid, state);
|
|
97
129
|
if (!needsReassess) return null;
|
|
98
130
|
return {
|
|
@@ -130,8 +162,10 @@ const DISPATCH_RULES: DispatchRule[] = [
|
|
|
130
162
|
},
|
|
131
163
|
{
|
|
132
164
|
name: "pre-planning (no research) → research-milestone",
|
|
133
|
-
match: async ({ state, mid, midTitle, basePath }) => {
|
|
165
|
+
match: async ({ state, mid, midTitle, basePath, prefs }) => {
|
|
134
166
|
if (state.phase !== "pre-planning") return null;
|
|
167
|
+
// Phase skip: skip research when preference or profile says so
|
|
168
|
+
if (prefs?.phases?.skip_research) return null;
|
|
135
169
|
const researchFile = resolveMilestoneFile(basePath, mid, "RESEARCH");
|
|
136
170
|
if (researchFile) return null; // has research, fall through
|
|
137
171
|
return {
|
|
@@ -156,8 +190,10 @@ const DISPATCH_RULES: DispatchRule[] = [
|
|
|
156
190
|
},
|
|
157
191
|
{
|
|
158
192
|
name: "planning (no research, not S01) → research-slice",
|
|
159
|
-
match: async ({ state, mid, midTitle, basePath }) => {
|
|
193
|
+
match: async ({ state, mid, midTitle, basePath, prefs }) => {
|
|
160
194
|
if (state.phase !== "planning") return null;
|
|
195
|
+
// Phase skip: skip research when preference or profile says so
|
|
196
|
+
if (prefs?.phases?.skip_research || prefs?.phases?.skip_slice_research) return null;
|
|
161
197
|
const sid = state.activeSlice!.id;
|
|
162
198
|
const sTitle = state.activeSlice!.title;
|
|
163
199
|
const researchFile = resolveSliceFile(basePath, mid, sid, "RESEARCH");
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* utility.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { loadFile, parseContinue, parseRoadmap, parseSummary, extractUatType } from "./files.js";
|
|
10
|
-
import type { UatType } from "./files.js";
|
|
9
|
+
import { loadFile, parseContinue, parsePlan, parseRoadmap, parseSummary, extractUatType, loadActiveOverrides, formatOverridesSection } from "./files.js";
|
|
10
|
+
import type { Override, UatType } from "./files.js";
|
|
11
11
|
import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
|
|
12
12
|
import {
|
|
13
13
|
resolveMilestoneFile, resolveSliceFile, resolveSlicePath,
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
relMilestoneFile, relSliceFile, relSlicePath, relMilestonePath,
|
|
16
16
|
resolveGsdRootFile, relGsdRootFile,
|
|
17
17
|
} from "./paths.js";
|
|
18
|
-
import { resolveSkillDiscoveryMode } from "./preferences.js";
|
|
19
|
-
import type { GSDState } from "./types.js";
|
|
18
|
+
import { resolveSkillDiscoveryMode, resolveInlineLevel } from "./preferences.js";
|
|
19
|
+
import type { GSDState, InlineLevel } from "./types.js";
|
|
20
20
|
import type { GSDPreferences } from "./preferences.js";
|
|
21
21
|
import { join } from "node:path";
|
|
22
22
|
import { existsSync } from "node:fs";
|
|
@@ -393,7 +393,8 @@ export async function buildResearchMilestonePrompt(mid: string, midTitle: string
|
|
|
393
393
|
});
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
export async function buildPlanMilestonePrompt(mid: string, midTitle: string, base: string): Promise<string> {
|
|
396
|
+
export async function buildPlanMilestonePrompt(mid: string, midTitle: string, base: string, level?: InlineLevel): Promise<string> {
|
|
397
|
+
const inlineLevel = level ?? resolveInlineLevel();
|
|
397
398
|
const contextPath = resolveMilestoneFile(base, mid, "CONTEXT");
|
|
398
399
|
const contextRel = relMilestoneFile(base, mid, "CONTEXT");
|
|
399
400
|
const researchPath = resolveMilestoneFile(base, mid, "RESEARCH");
|
|
@@ -406,17 +407,23 @@ export async function buildPlanMilestonePrompt(mid: string, midTitle: string, ba
|
|
|
406
407
|
const { inlinePriorMilestoneSummary } = await import("./files.js");
|
|
407
408
|
const priorSummaryInline = await inlinePriorMilestoneSummary(mid, base);
|
|
408
409
|
if (priorSummaryInline) inlined.push(priorSummaryInline);
|
|
409
|
-
const projectInline = await inlineGsdRootFile(base, "project.md", "Project");
|
|
410
|
+
const projectInline = inlineLevel !== "minimal" ? await inlineGsdRootFile(base, "project.md", "Project") : null;
|
|
410
411
|
if (projectInline) inlined.push(projectInline);
|
|
411
|
-
const requirementsInline = await inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
412
|
+
const requirementsInline = inlineLevel !== "minimal" ? await inlineGsdRootFile(base, "requirements.md", "Requirements") : null;
|
|
412
413
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
413
|
-
const decisionsInline = await inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
414
|
+
const decisionsInline = inlineLevel !== "minimal" ? await inlineGsdRootFile(base, "decisions.md", "Decisions") : null;
|
|
414
415
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
415
416
|
inlined.push(inlineTemplate("roadmap", "Roadmap"));
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
417
|
+
if (inlineLevel === "full") {
|
|
418
|
+
inlined.push(inlineTemplate("decisions", "Decisions"));
|
|
419
|
+
inlined.push(inlineTemplate("plan", "Slice Plan"));
|
|
420
|
+
inlined.push(inlineTemplate("task-plan", "Task Plan"));
|
|
421
|
+
inlined.push(inlineTemplate("secrets-manifest", "Secrets Manifest"));
|
|
422
|
+
} else if (inlineLevel === "standard") {
|
|
423
|
+
inlined.push(inlineTemplate("decisions", "Decisions"));
|
|
424
|
+
inlined.push(inlineTemplate("plan", "Slice Plan"));
|
|
425
|
+
inlined.push(inlineTemplate("task-plan", "Task Plan"));
|
|
426
|
+
}
|
|
420
427
|
|
|
421
428
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
422
429
|
|
|
@@ -457,6 +464,9 @@ export async function buildResearchSlicePrompt(
|
|
|
457
464
|
inlined.push(inlineTemplate("research", "Research"));
|
|
458
465
|
|
|
459
466
|
const depContent = await inlineDependencySummaries(mid, sid, base);
|
|
467
|
+
const activeOverrides = await loadActiveOverrides(base);
|
|
468
|
+
const overridesInline = formatOverridesSection(activeOverrides);
|
|
469
|
+
if (overridesInline) inlined.unshift(overridesInline);
|
|
460
470
|
|
|
461
471
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
462
472
|
|
|
@@ -476,8 +486,9 @@ export async function buildResearchSlicePrompt(
|
|
|
476
486
|
}
|
|
477
487
|
|
|
478
488
|
export async function buildPlanSlicePrompt(
|
|
479
|
-
mid: string, _midTitle: string, sid: string, sTitle: string, base: string,
|
|
489
|
+
mid: string, _midTitle: string, sid: string, sTitle: string, base: string, level?: InlineLevel,
|
|
480
490
|
): Promise<string> {
|
|
491
|
+
const inlineLevel = level ?? resolveInlineLevel();
|
|
481
492
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
482
493
|
const roadmapRel = relMilestoneFile(base, mid, "ROADMAP");
|
|
483
494
|
const researchPath = resolveSliceFile(base, mid, sid, "RESEARCH");
|
|
@@ -487,14 +498,21 @@ export async function buildPlanSlicePrompt(
|
|
|
487
498
|
inlined.push(await inlineFile(roadmapPath, roadmapRel, "Milestone Roadmap"));
|
|
488
499
|
const researchInline = await inlineFileOptional(researchPath, researchRel, "Slice Research");
|
|
489
500
|
if (researchInline) inlined.push(researchInline);
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
501
|
+
if (inlineLevel !== "minimal") {
|
|
502
|
+
const decisionsInline = await inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
503
|
+
if (decisionsInline) inlined.push(decisionsInline);
|
|
504
|
+
const requirementsInline = await inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
505
|
+
if (requirementsInline) inlined.push(requirementsInline);
|
|
506
|
+
}
|
|
494
507
|
inlined.push(inlineTemplate("plan", "Slice Plan"));
|
|
495
|
-
|
|
508
|
+
if (inlineLevel === "full") {
|
|
509
|
+
inlined.push(inlineTemplate("task-plan", "Task Plan"));
|
|
510
|
+
}
|
|
496
511
|
|
|
497
512
|
const depContent = await inlineDependencySummaries(mid, sid, base);
|
|
513
|
+
const planActiveOverrides = await loadActiveOverrides(base);
|
|
514
|
+
const planOverridesInline = formatOverridesSection(planActiveOverrides);
|
|
515
|
+
if (planOverridesInline) inlined.unshift(planOverridesInline);
|
|
498
516
|
|
|
499
517
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
500
518
|
|
|
@@ -513,8 +531,9 @@ export async function buildPlanSlicePrompt(
|
|
|
513
531
|
|
|
514
532
|
export async function buildExecuteTaskPrompt(
|
|
515
533
|
mid: string, sid: string, sTitle: string,
|
|
516
|
-
tid: string, tTitle: string, base: string,
|
|
534
|
+
tid: string, tTitle: string, base: string, level?: InlineLevel,
|
|
517
535
|
): Promise<string> {
|
|
536
|
+
const inlineLevel = level ?? resolveInlineLevel();
|
|
518
537
|
|
|
519
538
|
const priorSummaries = await getPriorTaskSummaryPaths(mid, sid, tid, base);
|
|
520
539
|
const priorLines = priorSummaries.length > 0
|
|
@@ -554,15 +573,25 @@ export async function buildExecuteTaskPrompt(
|
|
|
554
573
|
legacyContinuePath ? `${relSlicePath(base, mid, sid)}/continue.md` : null,
|
|
555
574
|
);
|
|
556
575
|
|
|
557
|
-
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
576
|
+
// For minimal inline level, only carry forward the most recent prior summary
|
|
577
|
+
const effectivePriorSummaries = inlineLevel === "minimal" && priorSummaries.length > 1
|
|
578
|
+
? priorSummaries.slice(-1)
|
|
579
|
+
: priorSummaries;
|
|
580
|
+
const carryForwardSection = await buildCarryForwardSection(effectivePriorSummaries, base);
|
|
581
|
+
const inlinedTemplates = inlineLevel === "minimal"
|
|
582
|
+
? inlineTemplate("task-summary", "Task Summary")
|
|
583
|
+
: [
|
|
584
|
+
inlineTemplate("task-summary", "Task Summary"),
|
|
585
|
+
inlineTemplate("decisions", "Decisions"),
|
|
586
|
+
].join("\n\n---\n\n");
|
|
562
587
|
|
|
563
588
|
const taskSummaryPath = `${relSlicePath(base, mid, sid)}/tasks/${tid}-SUMMARY.md`;
|
|
564
589
|
|
|
590
|
+
const activeOverrides = await loadActiveOverrides(base);
|
|
591
|
+
const overridesSection = formatOverridesSection(activeOverrides);
|
|
592
|
+
|
|
565
593
|
return loadPrompt("execute-task", {
|
|
594
|
+
overridesSection,
|
|
566
595
|
workingDirectory: base,
|
|
567
596
|
milestoneId: mid, sliceId: sid, sliceTitle: sTitle, taskId: tid, taskTitle: tTitle,
|
|
568
597
|
planPath: relSliceFile(base, mid, sid, "PLAN"),
|
|
@@ -579,8 +608,9 @@ export async function buildExecuteTaskPrompt(
|
|
|
579
608
|
}
|
|
580
609
|
|
|
581
610
|
export async function buildCompleteSlicePrompt(
|
|
582
|
-
mid: string, _midTitle: string, sid: string, sTitle: string, base: string,
|
|
611
|
+
mid: string, _midTitle: string, sid: string, sTitle: string, base: string, level?: InlineLevel,
|
|
583
612
|
): Promise<string> {
|
|
613
|
+
const inlineLevel = level ?? resolveInlineLevel();
|
|
584
614
|
|
|
585
615
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
586
616
|
const roadmapRel = relMilestoneFile(base, mid, "ROADMAP");
|
|
@@ -590,8 +620,10 @@ export async function buildCompleteSlicePrompt(
|
|
|
590
620
|
const inlined: string[] = [];
|
|
591
621
|
inlined.push(await inlineFile(roadmapPath, roadmapRel, "Milestone Roadmap"));
|
|
592
622
|
inlined.push(await inlineFile(slicePlanPath, slicePlanRel, "Slice Plan"));
|
|
593
|
-
|
|
594
|
-
|
|
623
|
+
if (inlineLevel !== "minimal") {
|
|
624
|
+
const requirementsInline = await inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
625
|
+
if (requirementsInline) inlined.push(requirementsInline);
|
|
626
|
+
}
|
|
595
627
|
|
|
596
628
|
// Inline all task summaries for this slice
|
|
597
629
|
const tDir = resolveTasksDir(base, mid, sid);
|
|
@@ -608,7 +640,12 @@ export async function buildCompleteSlicePrompt(
|
|
|
608
640
|
}
|
|
609
641
|
}
|
|
610
642
|
inlined.push(inlineTemplate("slice-summary", "Slice Summary"));
|
|
611
|
-
|
|
643
|
+
if (inlineLevel !== "minimal") {
|
|
644
|
+
inlined.push(inlineTemplate("uat", "UAT"));
|
|
645
|
+
}
|
|
646
|
+
const completeActiveOverrides = await loadActiveOverrides(base);
|
|
647
|
+
const completeOverridesInline = formatOverridesSection(completeActiveOverrides);
|
|
648
|
+
if (completeOverridesInline) inlined.unshift(completeOverridesInline);
|
|
612
649
|
|
|
613
650
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
614
651
|
|
|
@@ -628,8 +665,9 @@ export async function buildCompleteSlicePrompt(
|
|
|
628
665
|
}
|
|
629
666
|
|
|
630
667
|
export async function buildCompleteMilestonePrompt(
|
|
631
|
-
mid: string, midTitle: string, base: string,
|
|
668
|
+
mid: string, midTitle: string, base: string, level?: InlineLevel,
|
|
632
669
|
): Promise<string> {
|
|
670
|
+
const inlineLevel = level ?? resolveInlineLevel();
|
|
633
671
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
634
672
|
const roadmapRel = relMilestoneFile(base, mid, "ROADMAP");
|
|
635
673
|
|
|
@@ -650,13 +688,15 @@ export async function buildCompleteMilestonePrompt(
|
|
|
650
688
|
}
|
|
651
689
|
}
|
|
652
690
|
|
|
653
|
-
// Inline root GSD files
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
691
|
+
// Inline root GSD files (skip for minimal — completion can read these if needed)
|
|
692
|
+
if (inlineLevel !== "minimal") {
|
|
693
|
+
const requirementsInline = await inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
694
|
+
if (requirementsInline) inlined.push(requirementsInline);
|
|
695
|
+
const decisionsInline = await inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
696
|
+
if (decisionsInline) inlined.push(decisionsInline);
|
|
697
|
+
const projectInline = await inlineGsdRootFile(base, "project.md", "Project");
|
|
698
|
+
if (projectInline) inlined.push(projectInline);
|
|
699
|
+
}
|
|
660
700
|
// Inline milestone context file (milestone-level, not GSD root)
|
|
661
701
|
const contextPath = resolveMilestoneFile(base, mid, "CONTEXT");
|
|
662
702
|
const contextRel = relMilestoneFile(base, mid, "CONTEXT");
|
|
@@ -712,6 +752,9 @@ export async function buildReplanSlicePrompt(
|
|
|
712
752
|
// Inline decisions
|
|
713
753
|
const decisionsInline = await inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
714
754
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
755
|
+
const replanActiveOverrides = await loadActiveOverrides(base);
|
|
756
|
+
const replanOverridesInline = formatOverridesSection(replanActiveOverrides);
|
|
757
|
+
if (replanOverridesInline) inlined.unshift(replanOverridesInline);
|
|
715
758
|
|
|
716
759
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
717
760
|
|
|
@@ -763,8 +806,9 @@ export async function buildRunUatPrompt(
|
|
|
763
806
|
}
|
|
764
807
|
|
|
765
808
|
export async function buildReassessRoadmapPrompt(
|
|
766
|
-
mid: string, midTitle: string, completedSliceId: string, base: string,
|
|
809
|
+
mid: string, midTitle: string, completedSliceId: string, base: string, level?: InlineLevel,
|
|
767
810
|
): Promise<string> {
|
|
811
|
+
const inlineLevel = level ?? resolveInlineLevel();
|
|
768
812
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
769
813
|
const roadmapRel = relMilestoneFile(base, mid, "ROADMAP");
|
|
770
814
|
const summaryPath = resolveSliceFile(base, mid, completedSliceId, "SUMMARY");
|
|
@@ -773,12 +817,14 @@ export async function buildReassessRoadmapPrompt(
|
|
|
773
817
|
const inlined: string[] = [];
|
|
774
818
|
inlined.push(await inlineFile(roadmapPath, roadmapRel, "Current Roadmap"));
|
|
775
819
|
inlined.push(await inlineFile(summaryPath, summaryRel, `${completedSliceId} Summary`));
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
820
|
+
if (inlineLevel !== "minimal") {
|
|
821
|
+
const projectInline = await inlineGsdRootFile(base, "project.md", "Project");
|
|
822
|
+
if (projectInline) inlined.push(projectInline);
|
|
823
|
+
const requirementsInline = await inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
824
|
+
if (requirementsInline) inlined.push(requirementsInline);
|
|
825
|
+
const decisionsInline = await inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
826
|
+
if (decisionsInline) inlined.push(decisionsInline);
|
|
827
|
+
}
|
|
782
828
|
|
|
783
829
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
784
830
|
|
|
@@ -795,3 +841,70 @@ export async function buildReassessRoadmapPrompt(
|
|
|
795
841
|
inlinedContext,
|
|
796
842
|
});
|
|
797
843
|
}
|
|
844
|
+
|
|
845
|
+
export async function buildRewriteDocsPrompt(
|
|
846
|
+
mid: string, midTitle: string,
|
|
847
|
+
activeSlice: { id: string; title: string } | null,
|
|
848
|
+
base: string,
|
|
849
|
+
overrides: Override[],
|
|
850
|
+
): Promise<string> {
|
|
851
|
+
const sid = activeSlice?.id;
|
|
852
|
+
const sTitle = activeSlice?.title ?? "";
|
|
853
|
+
const docList: string[] = [];
|
|
854
|
+
|
|
855
|
+
if (sid) {
|
|
856
|
+
const slicePlanPath = resolveSliceFile(base, mid, sid, "PLAN");
|
|
857
|
+
const slicePlanRel = relSliceFile(base, mid, sid, "PLAN");
|
|
858
|
+
if (slicePlanPath) {
|
|
859
|
+
docList.push(`- Slice plan: \`${slicePlanRel}\``);
|
|
860
|
+
const tDir = resolveTasksDir(base, mid, sid);
|
|
861
|
+
if (tDir) {
|
|
862
|
+
const planContent = await loadFile(slicePlanPath);
|
|
863
|
+
if (planContent) {
|
|
864
|
+
const plan = parsePlan(planContent);
|
|
865
|
+
for (const task of plan.tasks) {
|
|
866
|
+
if (!task.done) {
|
|
867
|
+
const taskPlanPath = resolveTaskFile(base, mid, sid, task.id, "PLAN");
|
|
868
|
+
if (taskPlanPath) {
|
|
869
|
+
const taskRelPath = `${relSlicePath(base, mid, sid)}/tasks/${task.id}-PLAN.md`;
|
|
870
|
+
docList.push(`- Task plan: \`${taskRelPath}\``);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
const decisionsPath = resolveGsdRootFile(base, "DECISIONS");
|
|
880
|
+
if (existsSync(decisionsPath)) docList.push(`- Decisions: \`${relGsdRootFile("DECISIONS")}\``);
|
|
881
|
+
const requirementsPath = resolveGsdRootFile(base, "REQUIREMENTS");
|
|
882
|
+
if (existsSync(requirementsPath)) docList.push(`- Requirements: \`${relGsdRootFile("REQUIREMENTS")}\``);
|
|
883
|
+
const projectPath = resolveGsdRootFile(base, "PROJECT");
|
|
884
|
+
if (existsSync(projectPath)) docList.push(`- Project: \`${relGsdRootFile("PROJECT")}\``);
|
|
885
|
+
const contextPath = resolveMilestoneFile(base, mid, "CONTEXT");
|
|
886
|
+
const contextRel = relMilestoneFile(base, mid, "CONTEXT");
|
|
887
|
+
if (contextPath) docList.push(`- Milestone context (reference only): \`${contextRel}\``);
|
|
888
|
+
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
889
|
+
const roadmapRel = relMilestoneFile(base, mid, "ROADMAP");
|
|
890
|
+
if (roadmapPath) docList.push(`- Roadmap: \`${roadmapRel}\``);
|
|
891
|
+
|
|
892
|
+
const overrideContent = overrides.map((o, i) => [
|
|
893
|
+
`### Override ${i + 1}`,
|
|
894
|
+
`**Change:** ${o.change}`,
|
|
895
|
+
`**Issued:** ${o.timestamp}`,
|
|
896
|
+
`**During:** ${o.appliedAt}`,
|
|
897
|
+
].join("\n")).join("\n\n");
|
|
898
|
+
|
|
899
|
+
const documentList = docList.length > 0 ? docList.join("\n") : "- No active plan documents found.";
|
|
900
|
+
|
|
901
|
+
return loadPrompt("rewrite-docs", {
|
|
902
|
+
milestoneId: mid,
|
|
903
|
+
milestoneTitle: midTitle,
|
|
904
|
+
sliceId: sid ?? "none",
|
|
905
|
+
sliceTitle: sTitle,
|
|
906
|
+
overrideContent,
|
|
907
|
+
documentList,
|
|
908
|
+
overridesPath: relGsdRootFile("OVERRIDES"),
|
|
909
|
+
});
|
|
910
|
+
}
|