gsd-pi 2.44.0-dev.73f2fd5 → 2.44.0-dev.8894d5b
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/dist/resources/extensions/gsd/auto/infra-errors.js +0 -3
- package/dist/resources/extensions/gsd/auto/phases.js +36 -36
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -24
- package/dist/resources/extensions/gsd/auto-timers.js +3 -57
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +0 -4
- package/dist/resources/extensions/gsd/auto-worktree.js +6 -9
- package/dist/resources/extensions/gsd/auto.js +3 -30
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +0 -136
- package/dist/resources/extensions/gsd/commands/catalog.js +1 -6
- package/dist/resources/extensions/gsd/commands/handlers/core.js +0 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +0 -5
- package/dist/resources/extensions/gsd/db-writer.js +16 -34
- package/dist/resources/extensions/gsd/doctor.js +0 -8
- package/dist/resources/extensions/gsd/git-service.js +3 -8
- package/dist/resources/extensions/gsd/gsd-db.js +1 -12
- package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +4 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +14 -3
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +37 -7
- package/dist/resources/extensions/gsd/provider-error-pause.js +0 -7
- package/dist/resources/extensions/gsd/tools/plan-slice.js +0 -1
- package/dist/resources/extensions/gsd/tools/plan-task.js +0 -1
- package/dist/resources/extensions/gsd/tools/replan-slice.js +0 -2
- package/dist/resources/extensions/gsd/worktree-resolver.js +0 -6
- package/dist/resources/extensions/mcp-client/index.js +0 -14
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -20
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +20 -20
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +1 -3
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +1 -15
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -11
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +1 -20
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +0 -3
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +0 -6
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +0 -17
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +1 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +0 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +0 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +2 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +2 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +8 -17
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -7
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.ts +1 -15
- package/packages/pi-coding-agent/src/core/model-registry.ts +1 -21
- package/packages/pi-coding-agent/src/core/settings-manager.ts +0 -9
- package/packages/pi-coding-agent/src/main.ts +0 -19
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -10
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +0 -15
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +3 -18
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -16
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +1 -8
- package/src/resources/extensions/gsd/auto/infra-errors.ts +0 -3
- package/src/resources/extensions/gsd/auto/phases.ts +48 -45
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -24
- package/src/resources/extensions/gsd/auto-timers.ts +3 -64
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -5
- package/src/resources/extensions/gsd/auto-worktree.ts +6 -9
- package/src/resources/extensions/gsd/auto.ts +3 -37
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +0 -129
- package/src/resources/extensions/gsd/commands/catalog.ts +1 -6
- package/src/resources/extensions/gsd/commands/handlers/core.ts +0 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +0 -5
- package/src/resources/extensions/gsd/db-writer.ts +17 -39
- package/src/resources/extensions/gsd/doctor.ts +1 -7
- package/src/resources/extensions/gsd/git-service.ts +2 -6
- package/src/resources/extensions/gsd/gsd-db.ts +1 -16
- package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +4 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/src/resources/extensions/gsd/prompts/replan-slice.md +14 -3
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +37 -7
- package/src/resources/extensions/gsd/provider-error-pause.ts +0 -9
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -20
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +7 -11
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -2
- package/src/resources/extensions/gsd/tools/plan-slice.ts +0 -2
- package/src/resources/extensions/gsd/tools/plan-task.ts +0 -2
- package/src/resources/extensions/gsd/tools/replan-slice.ts +0 -3
- package/src/resources/extensions/gsd/worktree-resolver.ts +0 -7
- package/src/resources/extensions/mcp-client/index.ts +0 -20
- package/dist/resources/extensions/gsd/commands-mcp-status.js +0 -187
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +0 -88
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +0 -15
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/core/local-model-check.js +0 -41
- package/packages/pi-coding-agent/dist/core/local-model-check.js.map +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +0 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +0 -32
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +0 -15
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +0 -40
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +0 -1
- package/packages/pi-coding-agent/src/core/local-model-check.ts +0 -45
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +0 -38
- package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +0 -48
- package/src/resources/extensions/gsd/commands-mcp-status.ts +0 -247
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +0 -88
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +0 -114
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +0 -120
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +0 -103
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +0 -66
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +0 -67
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +0 -49
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +0 -127
- /package/dist/web/standalone/.next/static/{kxxAA66bah_yhPYqLBHE2 → oZMtyM-zfu6Inx-S59cOl}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{kxxAA66bah_yhPYqLBHE2 → oZMtyM-zfu6Inx-S59cOl}/_ssgManifest.js +0 -0
|
@@ -17,9 +17,6 @@ export const INFRA_ERROR_CODES = new Set([
|
|
|
17
17
|
"EDQUOT", // disk quota exceeded
|
|
18
18
|
"EMFILE", // too many open files (process)
|
|
19
19
|
"ENFILE", // too many open files (system)
|
|
20
|
-
"ECONNREFUSED", // connection refused (offline / local server down)
|
|
21
|
-
"ENOTFOUND", // DNS lookup failed (offline / no network)
|
|
22
|
-
"ENETUNREACH", // network unreachable (offline / no route)
|
|
23
20
|
]);
|
|
24
21
|
/**
|
|
25
22
|
* Detect whether an error is an unrecoverable infrastructure failure.
|
|
@@ -14,9 +14,7 @@ import { debugLog } from "../debug-logger.js";
|
|
|
14
14
|
import { gsdRoot } from "../paths.js";
|
|
15
15
|
import { atomicWriteSync } from "../atomic-write.js";
|
|
16
16
|
import { PROJECT_FILES } from "../detection.js";
|
|
17
|
-
import { MergeConflictError } from "../git-service.js";
|
|
18
17
|
import { join } from "node:path";
|
|
19
|
-
import { existsSync, cpSync } from "node:fs";
|
|
20
18
|
// ─── generateMilestoneReport ──────────────────────────────────────────────────
|
|
21
19
|
/**
|
|
22
20
|
* Generate and write an HTML milestone report snapshot.
|
|
@@ -147,19 +145,20 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
147
145
|
loopState.recentUnits.length = 0;
|
|
148
146
|
loopState.stuckRecoveryAttempts = 0;
|
|
149
147
|
// Worktree lifecycle on milestone transition — merge current, enter next
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
148
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
149
|
+
// Opt-in: create draft PR on milestone completion
|
|
150
|
+
if (prefs?.git?.auto_pr) {
|
|
151
|
+
try {
|
|
152
|
+
const { createDraftPR } = await import("../git-service.js");
|
|
153
|
+
const prUrl = createDraftPR(s.basePath, s.currentMilestoneId, `[GSD] ${s.currentMilestoneId} complete`, `Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`);
|
|
154
|
+
if (prUrl) {
|
|
155
|
+
ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Non-fatal — PR creation is best-effort
|
|
159
160
|
}
|
|
160
|
-
// Non-conflict errors — log and continue
|
|
161
161
|
}
|
|
162
|
-
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
163
162
|
deps.invalidateAllCaches();
|
|
164
163
|
state = await deps.deriveState(s.basePath);
|
|
165
164
|
mid = state.activeMilestone?.id;
|
|
@@ -180,14 +179,9 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
180
179
|
// Reset completed-units tracking for the new milestone — stale entries
|
|
181
180
|
// from the previous milestone cause the dispatch loop to skip units
|
|
182
181
|
// that haven't actually been completed in the new milestone's context.
|
|
183
|
-
// Archive the old completed-units.json instead of wiping it (#2313).
|
|
184
182
|
s.completedUnits = [];
|
|
185
183
|
try {
|
|
186
184
|
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
187
|
-
if (existsSync(completedKeysPath) && s.currentMilestoneId) {
|
|
188
|
-
const archivePath = join(gsdRoot(s.basePath), `completed-units-${s.currentMilestoneId}.json`);
|
|
189
|
-
cpSync(completedKeysPath, archivePath);
|
|
190
|
-
}
|
|
191
185
|
atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
|
|
192
186
|
}
|
|
193
187
|
catch { /* non-fatal */ }
|
|
@@ -215,17 +209,20 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
215
209
|
if (incomplete.length === 0 && state.registry.length > 0) {
|
|
216
210
|
// All milestones complete — merge milestone branch before stopping
|
|
217
211
|
if (s.currentMilestoneId) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
212
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
213
|
+
// Opt-in: create draft PR on milestone completion
|
|
214
|
+
if (prefs?.git?.auto_pr) {
|
|
215
|
+
try {
|
|
216
|
+
const { createDraftPR } = await import("../git-service.js");
|
|
217
|
+
const prUrl = createDraftPR(s.basePath, s.currentMilestoneId, `[GSD] ${s.currentMilestoneId} complete`, `Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`);
|
|
218
|
+
if (prUrl) {
|
|
219
|
+
ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// Non-fatal — PR creation is best-effort
|
|
226
224
|
}
|
|
227
225
|
}
|
|
228
|
-
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
229
226
|
}
|
|
230
227
|
deps.sendDesktopNotification("GSD", "All milestones complete!", "success", "milestone");
|
|
231
228
|
deps.logCmuxEvent(prefs, "All milestones complete.", "success");
|
|
@@ -280,17 +277,20 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
280
277
|
if (state.phase === "complete") {
|
|
281
278
|
// Milestone merge on complete (before closeout so branch state is clean)
|
|
282
279
|
if (s.currentMilestoneId) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
280
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
281
|
+
// Opt-in: create draft PR on milestone completion
|
|
282
|
+
if (prefs?.git?.auto_pr) {
|
|
283
|
+
try {
|
|
284
|
+
const { createDraftPR } = await import("../git-service.js");
|
|
285
|
+
const prUrl = createDraftPR(s.basePath, s.currentMilestoneId, `[GSD] ${s.currentMilestoneId} complete`, `Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`);
|
|
286
|
+
if (prUrl) {
|
|
287
|
+
ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
// Non-fatal — PR creation is best-effort
|
|
291
292
|
}
|
|
292
293
|
}
|
|
293
|
-
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
294
294
|
}
|
|
295
295
|
deps.sendDesktopNotification("GSD", `Milestone ${mid} complete!`, "success", "milestone");
|
|
296
296
|
deps.logCmuxEvent(prefs, `Milestone ${mid} complete.`, "success");
|
|
@@ -1156,12 +1156,6 @@ export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1156
1156
|
roadmapPath: roadmapRel,
|
|
1157
1157
|
inlinedContext,
|
|
1158
1158
|
milestoneSummaryPath,
|
|
1159
|
-
skillActivation: buildSkillActivationBlock({
|
|
1160
|
-
base,
|
|
1161
|
-
milestoneId: mid,
|
|
1162
|
-
milestoneTitle: midTitle,
|
|
1163
|
-
extraContext: [inlinedContext],
|
|
1164
|
-
}),
|
|
1165
1159
|
});
|
|
1166
1160
|
}
|
|
1167
1161
|
export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
@@ -1242,12 +1236,6 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1242
1236
|
inlinedContext,
|
|
1243
1237
|
validationPath: validationOutputPath,
|
|
1244
1238
|
remediationRound: String(remediationRound),
|
|
1245
|
-
skillActivation: buildSkillActivationBlock({
|
|
1246
|
-
base,
|
|
1247
|
-
milestoneId: mid,
|
|
1248
|
-
milestoneTitle: midTitle,
|
|
1249
|
-
extraContext: [inlinedContext],
|
|
1250
|
-
}),
|
|
1251
1239
|
});
|
|
1252
1240
|
}
|
|
1253
1241
|
export async function buildReplanSlicePrompt(mid, midTitle, sid, sTitle, base) {
|
|
@@ -1344,12 +1332,6 @@ export async function buildRunUatPrompt(mid, sliceId, uatPath, uatContent, base)
|
|
|
1344
1332
|
uatResultPath,
|
|
1345
1333
|
uatType,
|
|
1346
1334
|
inlinedContext,
|
|
1347
|
-
skillActivation: buildSkillActivationBlock({
|
|
1348
|
-
base,
|
|
1349
|
-
milestoneId: mid,
|
|
1350
|
-
sliceId,
|
|
1351
|
-
extraContext: [inlinedContext],
|
|
1352
|
-
}),
|
|
1353
1335
|
});
|
|
1354
1336
|
}
|
|
1355
1337
|
export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId, base, level) {
|
|
@@ -1396,16 +1378,11 @@ export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId
|
|
|
1396
1378
|
milestoneTitle: midTitle,
|
|
1397
1379
|
completedSliceId,
|
|
1398
1380
|
roadmapPath: roadmapRel,
|
|
1381
|
+
completedSliceSummaryPath: summaryRel,
|
|
1399
1382
|
assessmentPath,
|
|
1400
1383
|
inlinedContext,
|
|
1401
1384
|
deferredCaptures,
|
|
1402
1385
|
commitInstruction: reassessCommitInstruction,
|
|
1403
|
-
skillActivation: buildSkillActivationBlock({
|
|
1404
|
-
base,
|
|
1405
|
-
milestoneId: mid,
|
|
1406
|
-
milestoneTitle: midTitle,
|
|
1407
|
-
extraContext: [inlinedContext, deferredCaptures],
|
|
1408
|
-
}),
|
|
1409
1386
|
});
|
|
1410
1387
|
}
|
|
1411
1388
|
// ─── Reactive Execute Prompt ──────────────────────────────────────────────
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* via startUnitSupervision() and torn down by the caller via clearUnitTimeout().
|
|
7
7
|
*/
|
|
8
8
|
import { readUnitRuntimeRecord, writeUnitRuntimeRecord } from "./unit-runtime.js";
|
|
9
|
-
import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
10
9
|
import { resolveAutoSupervisorConfig } from "./preferences.js";
|
|
11
10
|
import { computeBudgets, resolveExecutorContextWindow } from "./context-budget.js";
|
|
12
11
|
import { getInFlightToolCount, getOldestInFlightToolStart, } from "./auto-tool-tracking.js";
|
|
@@ -22,65 +21,12 @@ import { resolveAgentEndCancelled } from "./auto/resolve.js";
|
|
|
22
21
|
* 3. Hard timeout (pause + recovery)
|
|
23
22
|
* 4. Context-pressure monitor (continue-here)
|
|
24
23
|
*/
|
|
25
|
-
/**
|
|
26
|
-
* Parse a task estimate string (e.g. "30m", "2h", "1h30m") into minutes.
|
|
27
|
-
* Returns null if the string cannot be parsed.
|
|
28
|
-
*/
|
|
29
|
-
export function parseEstimateMinutes(estimate) {
|
|
30
|
-
if (!estimate || typeof estimate !== "string")
|
|
31
|
-
return null;
|
|
32
|
-
const trimmed = estimate.trim();
|
|
33
|
-
if (!trimmed)
|
|
34
|
-
return null;
|
|
35
|
-
let totalMinutes = 0;
|
|
36
|
-
let matched = false;
|
|
37
|
-
// Match hours component
|
|
38
|
-
const hoursMatch = trimmed.match(/(\d+)\s*h/i);
|
|
39
|
-
if (hoursMatch) {
|
|
40
|
-
totalMinutes += Number(hoursMatch[1]) * 60;
|
|
41
|
-
matched = true;
|
|
42
|
-
}
|
|
43
|
-
// Match minutes component
|
|
44
|
-
const minutesMatch = trimmed.match(/(\d+)\s*m/i);
|
|
45
|
-
if (minutesMatch) {
|
|
46
|
-
totalMinutes += Number(minutesMatch[1]);
|
|
47
|
-
matched = true;
|
|
48
|
-
}
|
|
49
|
-
return matched ? totalMinutes : null;
|
|
50
|
-
}
|
|
51
24
|
export function startUnitSupervision(sctx) {
|
|
52
25
|
const { s, ctx, pi, unitType, unitId, prefs, buildSnapshotOpts, buildRecoveryContext, pauseAuto } = sctx;
|
|
53
26
|
const supervisor = resolveAutoSupervisorConfig();
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
let taskEstimate = sctx.taskEstimate;
|
|
58
|
-
if (!taskEstimate && unitType === "task" && isDbAvailable()) {
|
|
59
|
-
// Look up the task estimate from the DB (#2243).
|
|
60
|
-
try {
|
|
61
|
-
if (s.currentMilestoneId) {
|
|
62
|
-
const slices = getMilestoneSlices(s.currentMilestoneId);
|
|
63
|
-
for (const slice of slices) {
|
|
64
|
-
const tasks = getSliceTasks(s.currentMilestoneId, slice.id);
|
|
65
|
-
const task = tasks.find(t => t.id === unitId);
|
|
66
|
-
if (task?.estimate) {
|
|
67
|
-
taskEstimate = task.estimate;
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
// Non-fatal — fall through with no estimate
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
const estimateMinutes = taskEstimate ? parseEstimateMinutes(taskEstimate) : null;
|
|
78
|
-
const timeoutScale = estimateMinutes && estimateMinutes > 0
|
|
79
|
-
? Math.max(1, estimateMinutes / 10) // 10min task = 1x, 30min = 3x, 2h = 12x
|
|
80
|
-
: 1;
|
|
81
|
-
const softTimeoutMs = (supervisor.soft_timeout_minutes ?? 0) * 60 * 1000 * timeoutScale;
|
|
82
|
-
const idleTimeoutMs = (supervisor.idle_timeout_minutes ?? 0) * 60 * 1000; // idle not scaled — idle is idle
|
|
83
|
-
const hardTimeoutMs = (supervisor.hard_timeout_minutes ?? 0) * 60 * 1000 * timeoutScale;
|
|
27
|
+
const softTimeoutMs = (supervisor.soft_timeout_minutes ?? 0) * 60 * 1000;
|
|
28
|
+
const idleTimeoutMs = (supervisor.idle_timeout_minutes ?? 0) * 60 * 1000;
|
|
29
|
+
const hardTimeoutMs = (supervisor.hard_timeout_minutes ?? 0) * 60 * 1000;
|
|
84
30
|
// ── 1. Soft timeout warning ──
|
|
85
31
|
s.wrapupWarningHandle = setTimeout(() => {
|
|
86
32
|
s.wrapupWarningHandle = null;
|
|
@@ -63,10 +63,6 @@ export function syncStateToProjectRoot(worktreePath, projectRoot, milestoneId) {
|
|
|
63
63
|
// 2. Milestone directory — ROADMAP, slice PLANs, task summaries
|
|
64
64
|
// Copy the entire milestone .gsd subtree so deriveState reads current checkboxes
|
|
65
65
|
safeCopyRecursive(join(wtGsd, "milestones", milestoneId), join(prGsd, "milestones", milestoneId), { force: true });
|
|
66
|
-
// 3. metrics.json — session cost/token tracking (#2313).
|
|
67
|
-
// Without this, metrics accumulated in the worktree are invisible from the
|
|
68
|
-
// project root and never appear in the dashboard or skill-health reports.
|
|
69
|
-
safeCopy(join(wtGsd, "metrics.json"), join(prGsd, "metrics.json"), { force: true });
|
|
70
66
|
// 4. Runtime records — unit dispatch state used by selfHealRuntimeRecords().
|
|
71
67
|
// Without this, a crash during a unit leaves the runtime record only in the
|
|
72
68
|
// worktree. If the next session resolves basePath before worktree re-entry,
|
|
@@ -109,7 +109,6 @@ export function syncGsdStateToWorktree(mainBasePath, worktreePath_) {
|
|
|
109
109
|
"OVERRIDES.md",
|
|
110
110
|
"QUEUE.md",
|
|
111
111
|
"completed-units.json",
|
|
112
|
-
"metrics.json",
|
|
113
112
|
];
|
|
114
113
|
for (const f of rootFiles) {
|
|
115
114
|
const src = join(mainGsd, f);
|
|
@@ -270,9 +269,8 @@ export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
|
|
|
270
269
|
// ── 1. Sync root-level .gsd/ files back ──────────────────────────────
|
|
271
270
|
// The worktree is authoritative — complete-milestone updates REQUIREMENTS,
|
|
272
271
|
// PROJECT, etc. These must overwrite main's copies so they survive teardown.
|
|
273
|
-
// Also includes QUEUE.md
|
|
274
|
-
//
|
|
275
|
-
// (#1787, #2313).
|
|
272
|
+
// Also includes QUEUE.md and completed-units.json which are written during
|
|
273
|
+
// milestone closeout and lost on teardown without explicit sync (#1787).
|
|
276
274
|
const rootFiles = [
|
|
277
275
|
"DECISIONS.md",
|
|
278
276
|
"REQUIREMENTS.md",
|
|
@@ -281,7 +279,6 @@ export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
|
|
|
281
279
|
"OVERRIDES.md",
|
|
282
280
|
"QUEUE.md",
|
|
283
281
|
"completed-units.json",
|
|
284
|
-
"metrics.json",
|
|
285
282
|
];
|
|
286
283
|
for (const f of rootFiles) {
|
|
287
284
|
const src = join(wtGsd, f);
|
|
@@ -1136,9 +1133,9 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1136
1133
|
// Push failure is non-fatal
|
|
1137
1134
|
}
|
|
1138
1135
|
}
|
|
1139
|
-
// 9b. Auto-create PR if enabled (
|
|
1136
|
+
// 9b. Auto-create PR if enabled (requires push_branches + push succeeded)
|
|
1140
1137
|
let prCreated = false;
|
|
1141
|
-
if (prefs.auto_pr === true &&
|
|
1138
|
+
if (prefs.auto_pr === true && pushed) {
|
|
1142
1139
|
const remote = prefs.remote ?? "origin";
|
|
1143
1140
|
const prTarget = prefs.pr_target_branch ?? mainBranch;
|
|
1144
1141
|
try {
|
|
@@ -1148,9 +1145,9 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1148
1145
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1149
1146
|
encoding: "utf-8",
|
|
1150
1147
|
});
|
|
1151
|
-
// Create PR via gh CLI
|
|
1148
|
+
// Create PR via gh CLI
|
|
1152
1149
|
execFileSync("gh", [
|
|
1153
|
-
"pr", "create",
|
|
1150
|
+
"pr", "create",
|
|
1154
1151
|
"--base", prTarget,
|
|
1155
1152
|
"--head", milestoneBranch,
|
|
1156
1153
|
"--title", `Milestone ${milestoneId} complete`,
|
|
@@ -369,41 +369,14 @@ export async function stopAuto(ctx, pi, reason) {
|
|
|
369
369
|
debugLog("stop-cleanup-sigterm", { error: e instanceof Error ? e.message : String(e) });
|
|
370
370
|
}
|
|
371
371
|
// ── Step 4: Auto-worktree exit ──
|
|
372
|
-
// When the milestone is complete (has a SUMMARY), merge the worktree branch
|
|
373
|
-
// back to main so code isn't stranded on the worktree branch (#2317).
|
|
374
|
-
// For incomplete milestones, preserve the branch for later resumption.
|
|
375
372
|
try {
|
|
376
373
|
if (s.currentMilestoneId) {
|
|
377
374
|
const notifyCtx = ctx
|
|
378
375
|
? { notify: ctx.ui.notify.bind(ctx.ui) }
|
|
379
376
|
: { notify: () => { } };
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
try {
|
|
384
|
-
const summaryPath = resolveMilestoneFile(s.originalBasePath || s.basePath, s.currentMilestoneId, "SUMMARY");
|
|
385
|
-
if (!summaryPath) {
|
|
386
|
-
// Also check in the worktree path (SUMMARY may not be synced yet)
|
|
387
|
-
const wtSummaryPath = resolveMilestoneFile(s.basePath, s.currentMilestoneId, "SUMMARY");
|
|
388
|
-
milestoneComplete = wtSummaryPath !== null;
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
milestoneComplete = true;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
catch {
|
|
395
|
-
// Non-fatal — fall through to preserveBranch path
|
|
396
|
-
}
|
|
397
|
-
if (milestoneComplete) {
|
|
398
|
-
// Milestone is complete — merge worktree branch back to main
|
|
399
|
-
resolver.mergeAndExit(s.currentMilestoneId, notifyCtx);
|
|
400
|
-
}
|
|
401
|
-
else {
|
|
402
|
-
// Milestone still in progress — preserve branch for later resumption
|
|
403
|
-
resolver.exitMilestone(s.currentMilestoneId, notifyCtx, {
|
|
404
|
-
preserveBranch: true,
|
|
405
|
-
});
|
|
406
|
-
}
|
|
377
|
+
buildResolver().exitMilestone(s.currentMilestoneId, notifyCtx, {
|
|
378
|
+
preserveBranch: true,
|
|
379
|
+
});
|
|
407
380
|
}
|
|
408
381
|
}
|
|
409
382
|
catch (e) {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
|
-
import { Text } from "@gsd/pi-tui";
|
|
3
2
|
import { findMilestoneIds, nextMilestoneId, claimReservedId, getReservedMilestoneIds } from "../guided-flow.js";
|
|
4
3
|
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
5
4
|
import { ensureDbOpen } from "./dynamic-tools.js";
|
|
6
|
-
import { StringEnum } from "@gsd/pi-ai";
|
|
7
5
|
/**
|
|
8
6
|
* Register an alias tool that shares the same execute function as its canonical counterpart.
|
|
9
7
|
* The alias description and promptGuidelines direct the LLM to prefer the canonical name.
|
|
@@ -79,26 +77,6 @@ export function registerDbTools(pi) {
|
|
|
79
77
|
], { description: "Who made this decision: 'human' (user directed), 'agent' (LLM decided autonomously), or 'collaborative' (discussed and agreed). Default: 'agent'" })),
|
|
80
78
|
}),
|
|
81
79
|
execute: decisionSaveExecute,
|
|
82
|
-
renderCall(args, theme) {
|
|
83
|
-
let text = theme.fg("toolTitle", theme.bold("decision_save "));
|
|
84
|
-
if (args.scope)
|
|
85
|
-
text += theme.fg("accent", `[${args.scope}] `);
|
|
86
|
-
if (args.decision)
|
|
87
|
-
text += theme.fg("muted", args.decision);
|
|
88
|
-
if (args.choice)
|
|
89
|
-
text += theme.fg("dim", ` — ${args.choice}`);
|
|
90
|
-
return new Text(text, 0, 0);
|
|
91
|
-
},
|
|
92
|
-
renderResult(result, _options, theme) {
|
|
93
|
-
const d = result.details;
|
|
94
|
-
if (result.isError || d?.error) {
|
|
95
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
96
|
-
}
|
|
97
|
-
let text = theme.fg("success", `Decision ${d?.id ?? ""} saved`);
|
|
98
|
-
if (d?.id)
|
|
99
|
-
text += theme.fg("dim", ` → DECISIONS.md`);
|
|
100
|
-
return new Text(text, 0, 0);
|
|
101
|
-
},
|
|
102
80
|
};
|
|
103
81
|
pi.registerTool(decisionSaveTool);
|
|
104
82
|
registerAlias(pi, decisionSaveTool, "gsd_save_decision", "gsd_decision_save");
|
|
@@ -171,24 +149,6 @@ export function registerDbTools(pi) {
|
|
|
171
149
|
supporting_slices: Type.Optional(Type.String({ description: "Supporting slices" })),
|
|
172
150
|
}),
|
|
173
151
|
execute: requirementUpdateExecute,
|
|
174
|
-
renderCall(args, theme) {
|
|
175
|
-
let text = theme.fg("toolTitle", theme.bold("requirement_update "));
|
|
176
|
-
if (args.id)
|
|
177
|
-
text += theme.fg("accent", args.id);
|
|
178
|
-
const fields = ["status", "validation", "notes", "description"].filter((f) => args[f]);
|
|
179
|
-
if (fields.length > 0)
|
|
180
|
-
text += theme.fg("dim", ` (${fields.join(", ")})`);
|
|
181
|
-
return new Text(text, 0, 0);
|
|
182
|
-
},
|
|
183
|
-
renderResult(result, _options, theme) {
|
|
184
|
-
const d = result.details;
|
|
185
|
-
if (result.isError || d?.error) {
|
|
186
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
187
|
-
}
|
|
188
|
-
let text = theme.fg("success", `Requirement ${d?.id ?? ""} updated`);
|
|
189
|
-
text += theme.fg("dim", ` → REQUIREMENTS.md`);
|
|
190
|
-
return new Text(text, 0, 0);
|
|
191
|
-
},
|
|
192
152
|
};
|
|
193
153
|
pi.registerTool(requirementUpdateTool);
|
|
194
154
|
registerAlias(pi, requirementUpdateTool, "gsd_update_requirement", "gsd_requirement_update");
|
|
@@ -262,25 +222,6 @@ export function registerDbTools(pi) {
|
|
|
262
222
|
content: Type.String({ description: "The full markdown content of the artifact" }),
|
|
263
223
|
}),
|
|
264
224
|
execute: summarySaveExecute,
|
|
265
|
-
renderCall(args, theme) {
|
|
266
|
-
let text = theme.fg("toolTitle", theme.bold("summary_save "));
|
|
267
|
-
if (args.artifact_type)
|
|
268
|
-
text += theme.fg("accent", args.artifact_type);
|
|
269
|
-
const path = [args.milestone_id, args.slice_id, args.task_id].filter(Boolean).join("/");
|
|
270
|
-
if (path)
|
|
271
|
-
text += theme.fg("dim", ` ${path}`);
|
|
272
|
-
return new Text(text, 0, 0);
|
|
273
|
-
},
|
|
274
|
-
renderResult(result, _options, theme) {
|
|
275
|
-
const d = result.details;
|
|
276
|
-
if (result.isError || d?.error) {
|
|
277
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
278
|
-
}
|
|
279
|
-
let text = theme.fg("success", `${d?.artifact_type ?? "Artifact"} saved`);
|
|
280
|
-
if (d?.path)
|
|
281
|
-
text += theme.fg("dim", ` → ${d.path}`);
|
|
282
|
-
return new Text(text, 0, 0);
|
|
283
|
-
},
|
|
284
225
|
};
|
|
285
226
|
pi.registerTool(summarySaveTool);
|
|
286
227
|
registerAlias(pi, summarySaveTool, "gsd_save_summary", "gsd_summary_save");
|
|
@@ -349,19 +290,6 @@ export function registerDbTools(pi) {
|
|
|
349
290
|
],
|
|
350
291
|
parameters: Type.Object({}),
|
|
351
292
|
execute: milestoneGenerateIdExecute,
|
|
352
|
-
renderCall(_args, theme) {
|
|
353
|
-
return new Text(theme.fg("toolTitle", theme.bold("milestone_generate_id")), 0, 0);
|
|
354
|
-
},
|
|
355
|
-
renderResult(result, _options, theme) {
|
|
356
|
-
const d = result.details;
|
|
357
|
-
if (result.isError || d?.error) {
|
|
358
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
359
|
-
}
|
|
360
|
-
let text = theme.fg("success", `Generated ${d?.id ?? "ID"}`);
|
|
361
|
-
if (d?.source === "reserved")
|
|
362
|
-
text += theme.fg("dim", " (reserved)");
|
|
363
|
-
return new Text(text, 0, 0);
|
|
364
|
-
},
|
|
365
293
|
};
|
|
366
294
|
pi.registerTool(milestoneGenerateIdTool);
|
|
367
295
|
registerAlias(pi, milestoneGenerateIdTool, "gsd_generate_milestone_id", "gsd_milestone_generate_id");
|
|
@@ -824,70 +752,6 @@ export function registerDbTools(pi) {
|
|
|
824
752
|
};
|
|
825
753
|
pi.registerTool(milestoneCompleteTool);
|
|
826
754
|
registerAlias(pi, milestoneCompleteTool, "gsd_milestone_complete", "gsd_complete_milestone");
|
|
827
|
-
// ─── gsd_validate_milestone (gsd_milestone_validate alias) ─────────────
|
|
828
|
-
const milestoneValidateExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
829
|
-
const dbAvailable = await ensureDbOpen();
|
|
830
|
-
if (!dbAvailable) {
|
|
831
|
-
return {
|
|
832
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot validate milestone." }],
|
|
833
|
-
details: { operation: "validate_milestone", error: "db_unavailable" },
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
try {
|
|
837
|
-
const { handleValidateMilestone } = await import("../tools/validate-milestone.js");
|
|
838
|
-
const result = await handleValidateMilestone(params, process.cwd());
|
|
839
|
-
if ("error" in result) {
|
|
840
|
-
return {
|
|
841
|
-
content: [{ type: "text", text: `Error validating milestone: ${result.error}` }],
|
|
842
|
-
details: { operation: "validate_milestone", error: result.error },
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
return {
|
|
846
|
-
content: [{ type: "text", text: `Validated milestone ${result.milestoneId} — verdict: ${result.verdict}. Written to ${result.validationPath}` }],
|
|
847
|
-
details: {
|
|
848
|
-
operation: "validate_milestone",
|
|
849
|
-
milestoneId: result.milestoneId,
|
|
850
|
-
verdict: result.verdict,
|
|
851
|
-
validationPath: result.validationPath,
|
|
852
|
-
},
|
|
853
|
-
};
|
|
854
|
-
}
|
|
855
|
-
catch (err) {
|
|
856
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
857
|
-
process.stderr.write(`gsd-db: validate_milestone tool failed: ${msg}\n`);
|
|
858
|
-
return {
|
|
859
|
-
content: [{ type: "text", text: `Error validating milestone: ${msg}` }],
|
|
860
|
-
details: { operation: "validate_milestone", error: msg },
|
|
861
|
-
};
|
|
862
|
-
}
|
|
863
|
-
};
|
|
864
|
-
const milestoneValidateTool = {
|
|
865
|
-
name: "gsd_validate_milestone",
|
|
866
|
-
label: "Validate Milestone",
|
|
867
|
-
description: "Validate a milestone before completion — persist validation results to the DB, render VALIDATION.md to disk. " +
|
|
868
|
-
"Records verdict (pass/needs-attention/needs-remediation) and rationale.",
|
|
869
|
-
promptSnippet: "Validate a GSD milestone (DB write + VALIDATION.md render)",
|
|
870
|
-
promptGuidelines: [
|
|
871
|
-
"Use gsd_validate_milestone when all slices are done and the milestone needs validation before completion.",
|
|
872
|
-
"Parameters: milestoneId, verdict, remediationRound, successCriteriaChecklist, sliceDeliveryAudit, crossSliceIntegration, requirementCoverage, verdictRationale, remediationPlan (optional).",
|
|
873
|
-
"If verdict is 'needs-remediation', also provide remediationPlan and use gsd_reassess_roadmap to add remediation slices to the roadmap.",
|
|
874
|
-
"On success, returns validationPath where VALIDATION.md was written.",
|
|
875
|
-
],
|
|
876
|
-
parameters: Type.Object({
|
|
877
|
-
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
878
|
-
verdict: StringEnum(["pass", "needs-attention", "needs-remediation"], { description: "Validation verdict" }),
|
|
879
|
-
remediationRound: Type.Number({ description: "Remediation round (0 for first validation)" }),
|
|
880
|
-
successCriteriaChecklist: Type.String({ description: "Markdown checklist of success criteria with pass/fail and evidence" }),
|
|
881
|
-
sliceDeliveryAudit: Type.String({ description: "Markdown table auditing each slice's claimed vs delivered output" }),
|
|
882
|
-
crossSliceIntegration: Type.String({ description: "Markdown describing any cross-slice boundary mismatches" }),
|
|
883
|
-
requirementCoverage: Type.String({ description: "Markdown describing any unaddressed requirements" }),
|
|
884
|
-
verdictRationale: Type.String({ description: "Why this verdict was chosen" }),
|
|
885
|
-
remediationPlan: Type.Optional(Type.String({ description: "Remediation plan (required if verdict is needs-remediation)" })),
|
|
886
|
-
}),
|
|
887
|
-
execute: milestoneValidateExecute,
|
|
888
|
-
};
|
|
889
|
-
pi.registerTool(milestoneValidateTool);
|
|
890
|
-
registerAlias(pi, milestoneValidateTool, "gsd_milestone_validate", "gsd_validate_milestone");
|
|
891
755
|
// ─── gsd_replan_slice (gsd_slice_replan alias) ─────────────────────────
|
|
892
756
|
const replanSliceExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
893
757
|
const dbAvailable = await ensureDbOpen();
|
|
@@ -4,7 +4,7 @@ import { join } from "node:path";
|
|
|
4
4
|
import { loadRegistry } from "../workflow-templates.js";
|
|
5
5
|
import { resolveProjectRoot } from "../worktree.js";
|
|
6
6
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
7
|
-
export const GSD_COMMAND_DESCRIPTION = "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast
|
|
7
|
+
export const GSD_COMMAND_DESCRIPTION = "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast";
|
|
8
8
|
export const TOP_LEVEL_SUBCOMMANDS = [
|
|
9
9
|
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
10
10
|
{ cmd: "next", desc: "Explicit step mode (same as /gsd)" },
|
|
@@ -56,7 +56,6 @@ export const TOP_LEVEL_SUBCOMMANDS = [
|
|
|
56
56
|
{ cmd: "templates", desc: "List available workflow templates" },
|
|
57
57
|
{ cmd: "extensions", desc: "Manage extensions (list, enable, disable, info)" },
|
|
58
58
|
{ cmd: "fast", desc: "Toggle OpenAI service tier (on/off/flex/status)" },
|
|
59
|
-
{ cmd: "mcp", desc: "MCP server status and connectivity check (status, check <server>)" },
|
|
60
59
|
{ cmd: "workflow", desc: "Custom workflow lifecycle (new, run, list, validate, pause, resume)" },
|
|
61
60
|
];
|
|
62
61
|
const NESTED_COMPLETIONS = {
|
|
@@ -175,10 +174,6 @@ const NESTED_COMPLETIONS = {
|
|
|
175
174
|
{ cmd: "flex", desc: "Flex tier (0.5x cost, slower)" },
|
|
176
175
|
{ cmd: "status", desc: "Show current service tier setting" },
|
|
177
176
|
],
|
|
178
|
-
mcp: [
|
|
179
|
-
{ cmd: "status", desc: "Show all MCP server statuses (default)" },
|
|
180
|
-
{ cmd: "check", desc: "Detailed status for a specific server" },
|
|
181
|
-
],
|
|
182
177
|
doctor: [
|
|
183
178
|
{ cmd: "fix", desc: "Auto-fix detected issues" },
|
|
184
179
|
{ cmd: "heal", desc: "AI-driven deep healing" },
|
|
@@ -49,7 +49,6 @@ export function showHelp(ctx) {
|
|
|
49
49
|
" /gsd hooks Show post-unit hook configuration",
|
|
50
50
|
" /gsd extensions Manage extensions [list|enable|disable|info]",
|
|
51
51
|
" /gsd fast Toggle OpenAI service tier [on|off|flex|status]",
|
|
52
|
-
" /gsd mcp MCP server status and connectivity [status|check <server>]",
|
|
53
52
|
"",
|
|
54
53
|
"MAINTENANCE",
|
|
55
54
|
" /gsd doctor Diagnose and repair .gsd/ state [audit|fix|heal] [scope]",
|
|
@@ -188,11 +188,6 @@ Examples:
|
|
|
188
188
|
await handleFast(trimmed.replace(/^fast\s*/, "").trim(), ctx);
|
|
189
189
|
return true;
|
|
190
190
|
}
|
|
191
|
-
if (trimmed === "mcp" || trimmed.startsWith("mcp ")) {
|
|
192
|
-
const { handleMcpStatus } = await import("../../commands-mcp-status.js");
|
|
193
|
-
await handleMcpStatus(trimmed.replace(/^mcp\s*/, "").trim(), ctx);
|
|
194
|
-
return true;
|
|
195
|
-
}
|
|
196
191
|
if (trimmed === "extensions" || trimmed.startsWith("extensions ")) {
|
|
197
192
|
const { handleExtensions } = await import("../../commands-extensions.js");
|
|
198
193
|
await handleExtensions(trimmed.replace(/^extensions\s*/, "").trim(), ctx);
|