gsd-pi 2.59.0-dev.023bd39 → 2.59.0-dev.d77b3dd
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/phases.js +54 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +8 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +40 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +13 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +70 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +51 -5
- package/dist/resources/extensions/gsd/captures.js +54 -1
- package/dist/resources/extensions/gsd/complexity-classifier.js +1 -1
- package/dist/resources/extensions/gsd/context-masker.js +68 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +7 -0
- package/dist/resources/extensions/gsd/gsd-db.js +2 -2
- package/dist/resources/extensions/gsd/model-router.js +123 -4
- package/dist/resources/extensions/gsd/phase-anchor.js +56 -0
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +46 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +7 -0
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +6 -1
- package/dist/resources/extensions/gsd/rethink.js +5 -2
- package/dist/resources/extensions/gsd/state.js +1 -1
- package/dist/resources/extensions/gsd/status-guards.js +4 -3
- package/dist/resources/extensions/gsd/triage-resolution.js +128 -1
- package/dist/resources/extensions/gsd/triage-ui.js +12 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- 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/required-server-files.json +1 -1
- 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 +14 -14
- 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/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/src/resources/extensions/gsd/auto/phases.ts +60 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +12 -3
- package/src/resources/extensions/gsd/auto-post-unit.ts +48 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +17 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +78 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +53 -4
- package/src/resources/extensions/gsd/captures.ts +71 -2
- package/src/resources/extensions/gsd/complexity-classifier.ts +1 -1
- package/src/resources/extensions/gsd/context-masker.ts +74 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +7 -0
- package/src/resources/extensions/gsd/gsd-db.ts +2 -2
- package/src/resources/extensions/gsd/model-router.ts +171 -8
- package/src/resources/extensions/gsd/phase-anchor.ts +71 -0
- package/src/resources/extensions/gsd/preferences-types.ts +9 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +38 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +7 -0
- package/src/resources/extensions/gsd/prompts/triage-captures.md +6 -1
- package/src/resources/extensions/gsd/rethink.ts +5 -2
- package/src/resources/extensions/gsd/state.ts +1 -1
- package/src/resources/extensions/gsd/status-guards.ts +4 -3
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +87 -1
- package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/stop-backtrack.test.ts +216 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -1
- package/src/resources/extensions/gsd/triage-resolution.ts +144 -1
- package/src/resources/extensions/gsd/triage-ui.ts +12 -3
- /package/dist/web/standalone/.next/static/{QlWL-8CXgQpzV3ehkNMzh → t_cBZAENjaOJIRST3dw08}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{QlWL-8CXgQpzV3ehkNMzh → t_cBZAENjaOJIRST3dw08}/_ssgManifest.js +0 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Also provides detectFileOverlap() for surfacing downstream impact on quick tasks.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "node:fs";
|
|
14
14
|
import { join } from "node:path";
|
|
15
15
|
import { createRequire } from "node:module";
|
|
16
16
|
import { gsdRoot, milestonesDir } from "./paths.js";
|
|
@@ -129,6 +129,129 @@ export function executeReplan(
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
// ─── Backtrack (Milestone Regression) ────────────────────────────────────────
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Execute a backtrack directive — user wants to abandon current milestone
|
|
136
|
+
* and return to a previous one (milestone regression).
|
|
137
|
+
*
|
|
138
|
+
* Writes a BACKTRACK-TRIGGER.md marker at `.gsd/BACKTRACK-TRIGGER.md` with
|
|
139
|
+
* the target milestone, reason, and timestamp. The state machine (deriveState)
|
|
140
|
+
* detects this and transitions the project to the target milestone, resetting
|
|
141
|
+
* its slices to allow re-planning.
|
|
142
|
+
*
|
|
143
|
+
* Returns the extracted target milestone ID, or null if extraction failed.
|
|
144
|
+
*/
|
|
145
|
+
export function executeBacktrack(
|
|
146
|
+
basePath: string,
|
|
147
|
+
currentMilestoneId: string,
|
|
148
|
+
capture: CaptureEntry,
|
|
149
|
+
): string | null {
|
|
150
|
+
try {
|
|
151
|
+
// Extract target milestone from capture text or resolution
|
|
152
|
+
const targetMatch = (capture.resolution ?? capture.text)
|
|
153
|
+
.match(/\b(M\d{3}(?:-[a-z0-9]{6})?)\b/);
|
|
154
|
+
const targetMilestoneId = targetMatch?.[1] ?? null;
|
|
155
|
+
|
|
156
|
+
const ts = new Date().toISOString();
|
|
157
|
+
const triggerPath = join(gsdRoot(basePath), "BACKTRACK-TRIGGER.md");
|
|
158
|
+
const content = [
|
|
159
|
+
`# Backtrack Trigger`,
|
|
160
|
+
``,
|
|
161
|
+
`**Source:** Capture ${capture.id}`,
|
|
162
|
+
`**Capture:** ${capture.text}`,
|
|
163
|
+
`**Rationale:** ${capture.rationale ?? "User-initiated milestone backtrack"}`,
|
|
164
|
+
`**From:** ${currentMilestoneId}`,
|
|
165
|
+
`**Target:** ${targetMilestoneId ?? "(user to specify)"}`,
|
|
166
|
+
`**Triggered:** ${ts}`,
|
|
167
|
+
``,
|
|
168
|
+
`Auto-mode was paused by this backtrack directive. The user directed`,
|
|
169
|
+
`that the current milestone (${currentMilestoneId}) be abandoned and work`,
|
|
170
|
+
`should return to ${targetMilestoneId ?? "a previous milestone"}.`,
|
|
171
|
+
``,
|
|
172
|
+
`## Recovery Steps`,
|
|
173
|
+
``,
|
|
174
|
+
`1. Review what went wrong in ${currentMilestoneId}`,
|
|
175
|
+
`2. Identify missing features/requirements from the target milestone`,
|
|
176
|
+
`3. Resume auto-mode — the state machine will re-enter discussion for the target`,
|
|
177
|
+
].join("\n");
|
|
178
|
+
|
|
179
|
+
writeFileSync(triggerPath, content, "utf-8");
|
|
180
|
+
|
|
181
|
+
// If we have a valid target, also reset that milestone's completion status
|
|
182
|
+
// so deriveState() will re-enter it as the active milestone.
|
|
183
|
+
if (targetMilestoneId) {
|
|
184
|
+
try {
|
|
185
|
+
const targetDir = join(milestonesDir(basePath), targetMilestoneId);
|
|
186
|
+
if (existsSync(targetDir)) {
|
|
187
|
+
// Write a regression marker so the state machine knows this milestone
|
|
188
|
+
// needs re-discussion, not just re-execution
|
|
189
|
+
const regressionPath = join(targetDir, `${targetMilestoneId}-REGRESSION.md`);
|
|
190
|
+
writeFileSync(regressionPath, [
|
|
191
|
+
`# Milestone Regression`,
|
|
192
|
+
``,
|
|
193
|
+
`**From:** ${currentMilestoneId}`,
|
|
194
|
+
`**Reason:** ${capture.text}`,
|
|
195
|
+
`**Triggered:** ${ts}`,
|
|
196
|
+
``,
|
|
197
|
+
`This milestone is being revisited because downstream milestone`,
|
|
198
|
+
`${currentMilestoneId} failed or missed critical features that should`,
|
|
199
|
+
`have been part of this milestone's scope.`,
|
|
200
|
+
``,
|
|
201
|
+
`The discuss phase should re-evaluate requirements and identify gaps.`,
|
|
202
|
+
].join("\n"), "utf-8");
|
|
203
|
+
}
|
|
204
|
+
} catch { /* best-effort */ }
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return targetMilestoneId;
|
|
208
|
+
} catch {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Read the backtrack trigger file if it exists.
|
|
215
|
+
* Returns the parsed target milestone and metadata, or null.
|
|
216
|
+
*/
|
|
217
|
+
export function readBacktrackTrigger(basePath: string): {
|
|
218
|
+
target: string | null;
|
|
219
|
+
from: string | null;
|
|
220
|
+
capture: string;
|
|
221
|
+
triggeredAt: string;
|
|
222
|
+
} | null {
|
|
223
|
+
const triggerPath = join(gsdRoot(basePath), "BACKTRACK-TRIGGER.md");
|
|
224
|
+
if (!existsSync(triggerPath)) return null;
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
const content = readFileSync(triggerPath, "utf-8");
|
|
228
|
+
const target = content.match(/\*\*Target:\*\*\s*(.+)/)?.[1]?.trim() ?? null;
|
|
229
|
+
const from = content.match(/\*\*From:\*\*\s*(.+)/)?.[1]?.trim() ?? null;
|
|
230
|
+
const capture = content.match(/\*\*Capture:\*\*\s*(.+)/)?.[1]?.trim() ?? "";
|
|
231
|
+
const triggeredAt = content.match(/\*\*Triggered:\*\*\s*(.+)/)?.[1]?.trim() ?? "";
|
|
232
|
+
return {
|
|
233
|
+
target: target === "(user to specify)" ? null : target,
|
|
234
|
+
from,
|
|
235
|
+
capture,
|
|
236
|
+
triggeredAt,
|
|
237
|
+
};
|
|
238
|
+
} catch {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Remove the backtrack trigger after it has been processed.
|
|
245
|
+
*/
|
|
246
|
+
export function clearBacktrackTrigger(basePath: string): void {
|
|
247
|
+
const triggerPath = join(gsdRoot(basePath), "BACKTRACK-TRIGGER.md");
|
|
248
|
+
try {
|
|
249
|
+
if (existsSync(triggerPath)) {
|
|
250
|
+
unlinkSync(triggerPath);
|
|
251
|
+
}
|
|
252
|
+
} catch { /* best-effort */ }
|
|
253
|
+
}
|
|
254
|
+
|
|
132
255
|
// ─── File Overlap Detection ───────────────────────────────────────────────────
|
|
133
256
|
|
|
134
257
|
/**
|
|
@@ -298,6 +421,10 @@ export interface TriageExecutionResult {
|
|
|
298
421
|
deferredMilestones: number;
|
|
299
422
|
/** Captures classified as quick-task that need dispatch */
|
|
300
423
|
quickTasks: CaptureEntry[];
|
|
424
|
+
/** Number of stop directives (will pause auto-mode via guard) */
|
|
425
|
+
stopped: number;
|
|
426
|
+
/** Backtrack captures (will trigger milestone regression via guard) */
|
|
427
|
+
backtracks: CaptureEntry[];
|
|
301
428
|
/** Details of each action taken, for logging */
|
|
302
429
|
actions: string[];
|
|
303
430
|
}
|
|
@@ -326,6 +453,8 @@ export function executeTriageResolutions(
|
|
|
326
453
|
replanned: 0,
|
|
327
454
|
deferredMilestones: 0,
|
|
328
455
|
quickTasks: [],
|
|
456
|
+
stopped: 0,
|
|
457
|
+
backtracks: [],
|
|
329
458
|
actions: [],
|
|
330
459
|
};
|
|
331
460
|
|
|
@@ -409,5 +538,19 @@ export function executeTriageResolutions(
|
|
|
409
538
|
}
|
|
410
539
|
}
|
|
411
540
|
|
|
541
|
+
// Count stop/backtrack captures — these are handled by the pre-dispatch guard
|
|
542
|
+
// in runGuards(), not here. We just report them for logging purposes.
|
|
543
|
+
const allCaptures = loadAllCaptures(basePath);
|
|
544
|
+
for (const cap of allCaptures) {
|
|
545
|
+
if (cap.status !== "resolved" || cap.executed) continue;
|
|
546
|
+
if (cap.classification === "stop") {
|
|
547
|
+
result.stopped++;
|
|
548
|
+
result.actions.push(`Stop directive from ${cap.id}: "${cap.text}" — will pause on next dispatch`);
|
|
549
|
+
} else if (cap.classification === "backtrack") {
|
|
550
|
+
result.backtracks.push(cap);
|
|
551
|
+
result.actions.push(`Backtrack directive from ${cap.id}: "${cap.text}" — will trigger milestone regression on next dispatch`);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
412
555
|
return result;
|
|
413
556
|
}
|
|
@@ -49,10 +49,18 @@ const CLASSIFICATION_LABELS: Record<Classification, { label: string; description
|
|
|
49
49
|
label: "Note",
|
|
50
50
|
description: "Informational only — no action needed.",
|
|
51
51
|
},
|
|
52
|
+
"stop": {
|
|
53
|
+
label: "Stop",
|
|
54
|
+
description: "Halt auto-mode immediately — user directive to cease execution.",
|
|
55
|
+
},
|
|
56
|
+
"backtrack": {
|
|
57
|
+
label: "Backtrack",
|
|
58
|
+
description: "Abandon current milestone and return to a previous one.",
|
|
59
|
+
},
|
|
52
60
|
};
|
|
53
61
|
|
|
54
62
|
const ALL_CLASSIFICATIONS: Classification[] = [
|
|
55
|
-
"quick-task", "inject", "defer", "replan", "note",
|
|
63
|
+
"quick-task", "inject", "defer", "replan", "note", "stop", "backtrack",
|
|
56
64
|
];
|
|
57
65
|
|
|
58
66
|
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
@@ -83,8 +91,9 @@ export async function showTriageConfirmation(
|
|
|
83
91
|
const capture = captureMap.get(result.captureId);
|
|
84
92
|
if (!capture) continue;
|
|
85
93
|
|
|
86
|
-
// Auto-confirm note and
|
|
87
|
-
if (result.classification === "note" || result.classification === "defer"
|
|
94
|
+
// Auto-confirm note, defer, stop, and backtrack — low-impact or urgent directives
|
|
95
|
+
if (result.classification === "note" || result.classification === "defer"
|
|
96
|
+
|| result.classification === "stop" || result.classification === "backtrack") {
|
|
88
97
|
const resolution = result.classification === "note"
|
|
89
98
|
? "acknowledged as note"
|
|
90
99
|
: `deferred${result.targetSlice ? ` to ${result.targetSlice}` : ""}`;
|
|
File without changes
|
|
File without changes
|