gsd-pi 2.78.1-dev.eccf86e27 → 2.79.0-dev.579e14e9b
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 +94 -47
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +52 -29
- package/dist/resources/extensions/gsd/auto-recovery.js +18 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -37
- package/dist/resources/extensions/gsd/commands/context.js +1 -1
- package/dist/resources/extensions/gsd/preferences-types.js +20 -2
- package/dist/resources/extensions/gsd/preferences-validation.js +3 -3
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +41 -2
- package/dist/resources/extensions/gsd/unit-context-composer.js +32 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +21 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- 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 +1 -1
- 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 +10 -10
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +1 -0
- package/dist/web/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.17.3 +0 -0
- package/dist/web/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +42 -0
- package/dist/web/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +30 -0
- package/dist/web/standalone/node_modules/@img/sharp-linuxmusl-x64/LICENSE +191 -0
- package/dist/web/standalone/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64.node +0 -0
- package/dist/web/standalone/node_modules/@img/sharp-linuxmusl-x64/package.json +46 -0
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +53 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +116 -0
- package/packages/mcp-server/src/workflow-tools.ts +81 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +106 -28
- package/src/resources/extensions/gsd/auto-recovery.ts +17 -3
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +38 -38
- package/src/resources/extensions/gsd/commands/context.ts +1 -1
- package/src/resources/extensions/gsd/preferences-types.ts +23 -4
- package/src/resources/extensions/gsd/preferences-validation.ts +3 -3
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/current-directory-root-homedir-fallback.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/guided-flow-prompt-consolidation.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +3 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +41 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +49 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +34 -0
- /package/dist/web/standalone/.next/static/{Y5UeGFkXTYM9WIQOWHkot → X6D0ObmOxuQCMG5piZpbE}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Y5UeGFkXTYM9WIQOWHkot → X6D0ObmOxuQCMG5piZpbE}/_ssgManifest.js +0 -0
|
@@ -51,6 +51,34 @@ async function applyDisabledModelProviderPolicy(ctx) {
|
|
|
51
51
|
// Non-fatal: keep default provider visibility if preferences cannot be loaded.
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
+
async function writeContextModeCompactionSnapshot(basePath) {
|
|
55
|
+
try {
|
|
56
|
+
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
57
|
+
const { isContextModeEnabled } = await import("../preferences-types.js");
|
|
58
|
+
const prefs = loadEffectiveGSDPreferences(basePath);
|
|
59
|
+
if (!isContextModeEnabled(prefs?.preferences))
|
|
60
|
+
return;
|
|
61
|
+
const { writeCompactionSnapshot } = await import("../compaction-snapshot.js");
|
|
62
|
+
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
63
|
+
await ensureDbOpen(basePath);
|
|
64
|
+
let activeContext = null;
|
|
65
|
+
try {
|
|
66
|
+
const state = await deriveGsdState(basePath);
|
|
67
|
+
if (state.activeMilestone && state.activeSlice && state.activeTask) {
|
|
68
|
+
activeContext =
|
|
69
|
+
`Active: ${state.activeMilestone.id} / ${state.activeSlice.id} / ${state.activeTask.id}` +
|
|
70
|
+
(state.activeTask.title ? ` - ${state.activeTask.title}` : "");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
/* non-fatal */
|
|
75
|
+
}
|
|
76
|
+
writeCompactionSnapshot(basePath, { activeContext });
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
safetyLogWarning("context-mode", `failed to write compaction snapshot: ${err instanceof Error ? err.message : String(err)}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
54
82
|
export function registerHooks(pi, ecosystemHandlers) {
|
|
55
83
|
pi.on("session_start", async (_event, ctx) => {
|
|
56
84
|
initNotificationStore(process.cwd());
|
|
@@ -204,15 +232,18 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
204
232
|
}
|
|
205
233
|
});
|
|
206
234
|
pi.on("session_before_compact", async () => {
|
|
235
|
+
const basePath = process.cwd();
|
|
236
|
+
// Context Mode is default-on. Write the resumable snapshot before any
|
|
237
|
+
// active-auto cancel return so auto sessions still leave re-entry context.
|
|
238
|
+
await writeContextModeCompactionSnapshot(basePath);
|
|
207
239
|
// Only cancel compaction while auto-mode is actively running.
|
|
208
240
|
// Paused auto-mode should allow compaction — the user may be doing
|
|
209
241
|
// interactive work (#3165).
|
|
210
242
|
if (isAutoActive()) {
|
|
211
243
|
return { cancel: true };
|
|
212
244
|
}
|
|
213
|
-
const basePath = process.cwd();
|
|
214
245
|
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
215
|
-
await ensureDbOpen();
|
|
246
|
+
await ensureDbOpen(basePath);
|
|
216
247
|
const state = await deriveGsdState(basePath);
|
|
217
248
|
if (!state.activeMilestone || !state.activeSlice)
|
|
218
249
|
return;
|
|
@@ -256,41 +287,6 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
256
287
|
: `Resume ${phaseLabel} work for slice ${state.activeSlice.id}.`,
|
|
257
288
|
}));
|
|
258
289
|
});
|
|
259
|
-
// Context-mode snapshot: write .gsd/last-snapshot.md before compaction so
|
|
260
|
-
// agents can call gsd_resume (or Read the file) to re-orient. Opt-in via
|
|
261
|
-
// preferences.context_mode.enabled. Runs after the auto-cancel handler
|
|
262
|
-
// above — if that one returned cancel:true, pi still fires us but the
|
|
263
|
-
// compaction won't actually happen; the snapshot is still useful then,
|
|
264
|
-
// since auto may pause and resume later.
|
|
265
|
-
pi.on("session_before_compact", async () => {
|
|
266
|
-
try {
|
|
267
|
-
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
268
|
-
const { isContextModeEnabled } = await import("../preferences-types.js");
|
|
269
|
-
const prefs = loadEffectiveGSDPreferences();
|
|
270
|
-
if (!isContextModeEnabled(prefs?.preferences))
|
|
271
|
-
return;
|
|
272
|
-
const { writeCompactionSnapshot } = await import("../compaction-snapshot.js");
|
|
273
|
-
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
274
|
-
await ensureDbOpen();
|
|
275
|
-
const basePath = process.cwd();
|
|
276
|
-
let activeContext = null;
|
|
277
|
-
try {
|
|
278
|
-
const state = await deriveGsdState(basePath);
|
|
279
|
-
if (state.activeMilestone && state.activeSlice && state.activeTask) {
|
|
280
|
-
activeContext =
|
|
281
|
-
`Active: ${state.activeMilestone.id} / ${state.activeSlice.id} / ${state.activeTask.id}` +
|
|
282
|
-
(state.activeTask.title ? ` — ${state.activeTask.title}` : "");
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
catch {
|
|
286
|
-
/* non-fatal */
|
|
287
|
-
}
|
|
288
|
-
writeCompactionSnapshot(basePath, { activeContext });
|
|
289
|
-
}
|
|
290
|
-
catch (err) {
|
|
291
|
-
safetyLogWarning("context-mode", `failed to write compaction snapshot: ${err instanceof Error ? err.message : String(err)}`);
|
|
292
|
-
}
|
|
293
|
-
});
|
|
294
290
|
pi.on("message_update", async (event, ctx) => {
|
|
295
291
|
if (approvalQuestionAbortInFlight)
|
|
296
292
|
return;
|
|
@@ -100,8 +100,26 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
|
|
|
100
100
|
"context_mode",
|
|
101
101
|
"planning_depth",
|
|
102
102
|
]);
|
|
103
|
-
/**
|
|
104
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Broad union of every recognized unit-type *label* used across the codebase.
|
|
105
|
+
*
|
|
106
|
+
* This intentionally covers more than the manifest-tracked dispatch units in
|
|
107
|
+
* `unit-context-manifest.ts:KNOWN_UNIT_TYPES`. Examples that live here but not
|
|
108
|
+
* in the manifest:
|
|
109
|
+
* - `discuss-slice` — dispatched by `guided-flow.ts` rather than auto-mode;
|
|
110
|
+
* composer falls through to default behavior via `resolveManifest()` null path.
|
|
111
|
+
* - `worktree-merge` — used as a model-routing case, prompt-template name, and
|
|
112
|
+
* commit-message label, not as an LLM-dispatched unit.
|
|
113
|
+
*
|
|
114
|
+
* Used by `preferences-validation.ts` to validate user-provided unit-type
|
|
115
|
+
* references in preferences (model overrides, skill rules, etc.) — preferences
|
|
116
|
+
* may legitimately reference any label, including non-dispatched ones.
|
|
117
|
+
*
|
|
118
|
+
* The manifest-strict subset lives in `unit-context-manifest.ts:KNOWN_UNIT_TYPES`
|
|
119
|
+
* and is enforced 1:1 against `UNIT_MANIFESTS` by the parity test in
|
|
120
|
+
* `tests/unit-context-manifest.test.ts`.
|
|
121
|
+
*/
|
|
122
|
+
export const KNOWN_UNIT_LABELS = [
|
|
105
123
|
"research-milestone", "plan-milestone", "research-slice", "plan-slice", "refine-slice",
|
|
106
124
|
"execute-task", "reactive-execute", "gate-evaluate", "complete-slice", "replan-slice", "reassess-roadmap",
|
|
107
125
|
"run-uat", "complete-milestone", "validate-milestone", "rewrite-docs",
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { VALID_BRANCH_NAME } from "./git-service.js";
|
|
9
9
|
import { normalizeStringArray } from "../shared/format-utils.js";
|
|
10
|
-
import { KNOWN_PREFERENCE_KEYS,
|
|
10
|
+
import { KNOWN_PREFERENCE_KEYS, KNOWN_UNIT_LABELS, SKILL_ACTIONS, } from "./preferences-types.js";
|
|
11
11
|
const VALID_TOKEN_PROFILES = new Set(["budget", "balanced", "quality", "burn-max"]);
|
|
12
12
|
const VALID_UOK_TURN_ACTIONS = new Set([
|
|
13
13
|
"commit",
|
|
@@ -432,7 +432,7 @@ export function validatePreferences(preferences) {
|
|
|
432
432
|
if (preferences.post_unit_hooks && Array.isArray(preferences.post_unit_hooks)) {
|
|
433
433
|
const validHooks = [];
|
|
434
434
|
const seenNames = new Set();
|
|
435
|
-
const knownUnitTypes = new Set(
|
|
435
|
+
const knownUnitTypes = new Set(KNOWN_UNIT_LABELS);
|
|
436
436
|
for (const hook of preferences.post_unit_hooks) {
|
|
437
437
|
if (!hook || typeof hook !== "object") {
|
|
438
438
|
errors.push("post_unit_hooks entry must be an object");
|
|
@@ -493,7 +493,7 @@ export function validatePreferences(preferences) {
|
|
|
493
493
|
if (preferences.pre_dispatch_hooks && Array.isArray(preferences.pre_dispatch_hooks)) {
|
|
494
494
|
const validPreHooks = [];
|
|
495
495
|
const seenPreNames = new Set();
|
|
496
|
-
const knownUnitTypes = new Set(
|
|
496
|
+
const knownUnitTypes = new Set(KNOWN_UNIT_LABELS);
|
|
497
497
|
const validActions = new Set(["modify", "skip", "replace"]);
|
|
498
498
|
for (const hook of preferences.pre_dispatch_hooks) {
|
|
499
499
|
if (!hook || typeof hook !== "object") {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ensureDbOpen } from "../bootstrap/dynamic-tools.js";
|
|
2
2
|
import { sanitizeCompleteMilestoneParams } from "../bootstrap/sanitize-complete-milestone.js";
|
|
3
3
|
import { loadWriteGateSnapshot, shouldBlockContextArtifactSaveInSnapshot, shouldBlockRootArtifactSaveInSnapshot } from "../bootstrap/write-gate.js";
|
|
4
|
-
import { getActiveRequirements, getMilestone, getSliceStatusSummary, getSliceTaskCounts, readTransaction, saveGateResult, } from "../gsd-db.js";
|
|
4
|
+
import { getActiveRequirements, insertMilestone, getMilestone, getSliceStatusSummary, getSliceTaskCounts, readTransaction, saveGateResult, } from "../gsd-db.js";
|
|
5
5
|
import { GATE_REGISTRY } from "../gate-registry.js";
|
|
6
6
|
import { generateRequirementsMd, saveArtifactToDb } from "../db-writer.js";
|
|
7
7
|
import { resolveMilestoneFile, resolveSliceFile } from "../paths.js";
|
|
@@ -17,6 +17,7 @@ import { handleValidateMilestone } from "./validate-milestone.js";
|
|
|
17
17
|
import { logError, logWarning } from "../workflow-logger.js";
|
|
18
18
|
import { invalidateStateCache } from "../state.js";
|
|
19
19
|
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
20
|
+
import { parseProject } from "../schemas/parsers.js";
|
|
20
21
|
export const SUPPORTED_SUMMARY_ARTIFACT_TYPES = [
|
|
21
22
|
"SUMMARY",
|
|
22
23
|
"RESEARCH",
|
|
@@ -37,6 +38,19 @@ function isRootSummaryArtifactType(artifactType) {
|
|
|
37
38
|
artifactType === "REQUIREMENTS" ||
|
|
38
39
|
artifactType === "REQUIREMENTS-DRAFT";
|
|
39
40
|
}
|
|
41
|
+
function registerProjectMilestoneSequence(content) {
|
|
42
|
+
const parsed = parseProject(content);
|
|
43
|
+
const registered = [];
|
|
44
|
+
for (const milestone of parsed.milestones) {
|
|
45
|
+
insertMilestone({
|
|
46
|
+
id: milestone.id,
|
|
47
|
+
title: milestone.title,
|
|
48
|
+
status: milestone.done ? "complete" : "queued",
|
|
49
|
+
});
|
|
50
|
+
registered.push(milestone.id);
|
|
51
|
+
}
|
|
52
|
+
return registered;
|
|
53
|
+
}
|
|
40
54
|
export async function executeSummarySave(params, basePath = process.cwd()) {
|
|
41
55
|
const dbAvailable = await ensureDbOpen(basePath);
|
|
42
56
|
if (!dbAvailable) {
|
|
@@ -126,6 +140,24 @@ export async function executeSummarySave(params, basePath = process.cwd()) {
|
|
|
126
140
|
slice_id: isRootArtifact ? undefined : params.slice_id,
|
|
127
141
|
task_id: isRootArtifact ? undefined : params.task_id,
|
|
128
142
|
}, basePath);
|
|
143
|
+
let registeredMilestones = [];
|
|
144
|
+
let registrationWarning;
|
|
145
|
+
if (params.artifact_type === "PROJECT") {
|
|
146
|
+
try {
|
|
147
|
+
registeredMilestones = registerProjectMilestoneSequence(contentToSave);
|
|
148
|
+
if (registeredMilestones.length > 0)
|
|
149
|
+
invalidateStateCache();
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
153
|
+
registrationWarning = `PROJECT artifact saved, but milestone registration failed: ${msg}`;
|
|
154
|
+
logWarning("tool", registrationWarning, {
|
|
155
|
+
tool: "gsd_summary_save",
|
|
156
|
+
error: String(err),
|
|
157
|
+
stack: err instanceof Error ? err.stack ?? "" : "",
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
129
161
|
if (params.artifact_type === "CONTEXT" && !params.task_id) {
|
|
130
162
|
try {
|
|
131
163
|
const draftFile = params.slice_id
|
|
@@ -140,7 +172,14 @@ export async function executeSummarySave(params, basePath = process.cwd()) {
|
|
|
140
172
|
}
|
|
141
173
|
return {
|
|
142
174
|
content: [{ type: "text", text: `Saved ${params.artifact_type} artifact to ${relativePath}` }],
|
|
143
|
-
details: {
|
|
175
|
+
details: {
|
|
176
|
+
operation: "save_summary",
|
|
177
|
+
path: relativePath,
|
|
178
|
+
artifact_type: params.artifact_type,
|
|
179
|
+
content_source: contentSource,
|
|
180
|
+
...(registeredMilestones.length > 0 ? { registeredMilestones } : {}),
|
|
181
|
+
...(registrationWarning ? { warning: registrationWarning } : {}),
|
|
182
|
+
},
|
|
144
183
|
};
|
|
145
184
|
}
|
|
146
185
|
catch (err) {
|
|
@@ -71,6 +71,38 @@ export function manifestBudgetChars(unitType) {
|
|
|
71
71
|
const manifest = resolveManifest(unitType);
|
|
72
72
|
return manifest ? manifest.maxSystemPromptChars : null;
|
|
73
73
|
}
|
|
74
|
+
const CONTEXT_MODE_LANE_LABELS = {
|
|
75
|
+
interview: "interview",
|
|
76
|
+
research: "research",
|
|
77
|
+
planning: "planning",
|
|
78
|
+
execution: "execution",
|
|
79
|
+
verification: "verification",
|
|
80
|
+
orchestration: "orchestration",
|
|
81
|
+
docs: "documentation",
|
|
82
|
+
};
|
|
83
|
+
const CONTEXT_MODE_GUIDANCE = "Use `gsd_exec` for noisy scans, builds, and tests so full output stays out of prompt context; call `gsd_exec_search` before repeating prior runs; call `gsd_resume` after compaction or resume to recover stored execution context.";
|
|
84
|
+
/**
|
|
85
|
+
* Render the Context Mode instruction lane for a unit type. Unknown unit
|
|
86
|
+
* types, disabled config, and explicit `contextMode: "none"` all omit the
|
|
87
|
+
* block so callers can prefix this safely without extra branching.
|
|
88
|
+
*/
|
|
89
|
+
export function composeContextModeInstructions(unitType, opts) {
|
|
90
|
+
if (!opts.enabled)
|
|
91
|
+
return "";
|
|
92
|
+
const manifest = resolveManifest(unitType);
|
|
93
|
+
if (!manifest || manifest.contextMode === "none")
|
|
94
|
+
return "";
|
|
95
|
+
const lane = CONTEXT_MODE_LANE_LABELS[manifest.contextMode];
|
|
96
|
+
if (opts.renderMode === "nested") {
|
|
97
|
+
return `Context Mode (${lane} lane): ${CONTEXT_MODE_GUIDANCE}`;
|
|
98
|
+
}
|
|
99
|
+
return [
|
|
100
|
+
"## Context Mode",
|
|
101
|
+
"",
|
|
102
|
+
`Lane: **${lane} lane**.`,
|
|
103
|
+
CONTEXT_MODE_GUIDANCE,
|
|
104
|
+
].join("\n");
|
|
105
|
+
}
|
|
74
106
|
const SECTION_SEPARATOR = "\n\n---\n\n";
|
|
75
107
|
/**
|
|
76
108
|
* Compose all manifest-declared context for a unit type using the v2
|
|
@@ -137,6 +137,7 @@ export const UNIT_MANIFESTS = {
|
|
|
137
137
|
memory: "prompt-relevant",
|
|
138
138
|
codebaseMap: true,
|
|
139
139
|
preferences: "active-only",
|
|
140
|
+
contextMode: "research",
|
|
140
141
|
tools: TOOLS_PLANNING,
|
|
141
142
|
artifacts: {
|
|
142
143
|
// Phase 3 migration (#4782): matches today's actual
|
|
@@ -153,6 +154,7 @@ export const UNIT_MANIFESTS = {
|
|
|
153
154
|
memory: "prompt-relevant",
|
|
154
155
|
codebaseMap: true,
|
|
155
156
|
preferences: "active-only",
|
|
157
|
+
contextMode: "planning",
|
|
156
158
|
tools: TOOLS_PLANNING,
|
|
157
159
|
artifacts: {
|
|
158
160
|
inline: ["project", "requirements", "decisions", "milestone-research", "templates"],
|
|
@@ -167,6 +169,7 @@ export const UNIT_MANIFESTS = {
|
|
|
167
169
|
memory: "prompt-relevant",
|
|
168
170
|
codebaseMap: true,
|
|
169
171
|
preferences: "active-only",
|
|
172
|
+
contextMode: "interview",
|
|
170
173
|
tools: TOOLS_PLANNING,
|
|
171
174
|
artifacts: {
|
|
172
175
|
inline: ["project", "requirements", "decisions", "milestone-context", "templates"],
|
|
@@ -181,6 +184,7 @@ export const UNIT_MANIFESTS = {
|
|
|
181
184
|
memory: "prompt-relevant",
|
|
182
185
|
codebaseMap: false,
|
|
183
186
|
preferences: "active-only",
|
|
187
|
+
contextMode: "verification",
|
|
184
188
|
// planning-dispatch: validation is a verification-fan-out unit. It reads
|
|
185
189
|
// the milestone surface and dispatches reviewer/security/tester subagents
|
|
186
190
|
// to report findings without touching user source. Mirrors
|
|
@@ -199,6 +203,7 @@ export const UNIT_MANIFESTS = {
|
|
|
199
203
|
memory: "prompt-relevant",
|
|
200
204
|
codebaseMap: false,
|
|
201
205
|
preferences: "active-only",
|
|
206
|
+
contextMode: "verification",
|
|
202
207
|
// planning-dispatch: completion is a high-leverage place to fan out to
|
|
203
208
|
// reviewer / security / tester subagents. They read the diff and report
|
|
204
209
|
// findings; they do not write user source. Write isolation to .gsd/ is
|
|
@@ -221,6 +226,7 @@ export const UNIT_MANIFESTS = {
|
|
|
221
226
|
memory: "prompt-relevant",
|
|
222
227
|
codebaseMap: true,
|
|
223
228
|
preferences: "active-only",
|
|
229
|
+
contextMode: "research",
|
|
224
230
|
tools: TOOLS_PLANNING,
|
|
225
231
|
artifacts: {
|
|
226
232
|
inline: ["roadmap", "milestone-research", "dependency-summaries", "templates"],
|
|
@@ -235,6 +241,7 @@ export const UNIT_MANIFESTS = {
|
|
|
235
241
|
memory: "prompt-relevant",
|
|
236
242
|
codebaseMap: true,
|
|
237
243
|
preferences: "active-only",
|
|
244
|
+
contextMode: "planning",
|
|
238
245
|
// planning-dispatch: allows subagent dispatch so the planner can fan out
|
|
239
246
|
// to scout for codebase recon and to planner/decompose-style specialists
|
|
240
247
|
// for sub-decomposition. Write-isolation to .gsd/ is preserved.
|
|
@@ -252,6 +259,7 @@ export const UNIT_MANIFESTS = {
|
|
|
252
259
|
memory: "prompt-relevant",
|
|
253
260
|
codebaseMap: true,
|
|
254
261
|
preferences: "active-only",
|
|
262
|
+
contextMode: "planning",
|
|
255
263
|
// See plan-slice — same rationale: dispatch to scout/planner-style
|
|
256
264
|
// specialists during refinement is materially better than re-doing recon
|
|
257
265
|
// inline.
|
|
@@ -269,6 +277,7 @@ export const UNIT_MANIFESTS = {
|
|
|
269
277
|
memory: "prompt-relevant",
|
|
270
278
|
codebaseMap: true,
|
|
271
279
|
preferences: "active-only",
|
|
280
|
+
contextMode: "planning",
|
|
272
281
|
tools: TOOLS_PLANNING,
|
|
273
282
|
artifacts: {
|
|
274
283
|
inline: ["slice-plan", "slice-research", "dependency-summaries", "prior-task-summaries", "templates"],
|
|
@@ -283,6 +292,7 @@ export const UNIT_MANIFESTS = {
|
|
|
283
292
|
memory: "prompt-relevant",
|
|
284
293
|
codebaseMap: false,
|
|
285
294
|
preferences: "active-only",
|
|
295
|
+
contextMode: "verification",
|
|
286
296
|
// See complete-milestone — same rationale: dispatch to reviewer / security /
|
|
287
297
|
// tester subagents to fan out review work without bloating this unit's
|
|
288
298
|
// context.
|
|
@@ -304,6 +314,7 @@ export const UNIT_MANIFESTS = {
|
|
|
304
314
|
memory: "critical-only",
|
|
305
315
|
codebaseMap: false,
|
|
306
316
|
preferences: "none",
|
|
317
|
+
contextMode: "planning",
|
|
307
318
|
tools: TOOLS_PLANNING,
|
|
308
319
|
artifacts: {
|
|
309
320
|
// Phase 2 pilot (#4782): manifest now matches today's actual
|
|
@@ -322,6 +333,7 @@ export const UNIT_MANIFESTS = {
|
|
|
322
333
|
memory: "prompt-relevant",
|
|
323
334
|
codebaseMap: true,
|
|
324
335
|
preferences: "active-only",
|
|
336
|
+
contextMode: "execution",
|
|
325
337
|
tools: TOOLS_ALL,
|
|
326
338
|
artifacts: {
|
|
327
339
|
inline: ["task-plan", "slice-plan", "prior-task-summaries", "templates"],
|
|
@@ -336,6 +348,7 @@ export const UNIT_MANIFESTS = {
|
|
|
336
348
|
memory: "prompt-relevant",
|
|
337
349
|
codebaseMap: true,
|
|
338
350
|
preferences: "active-only",
|
|
351
|
+
contextMode: "execution",
|
|
339
352
|
tools: TOOLS_ALL,
|
|
340
353
|
artifacts: {
|
|
341
354
|
inline: ["slice-plan", "prior-task-summaries", "templates"],
|
|
@@ -351,6 +364,7 @@ export const UNIT_MANIFESTS = {
|
|
|
351
364
|
memory: "critical-only",
|
|
352
365
|
codebaseMap: false,
|
|
353
366
|
preferences: "active-only",
|
|
367
|
+
contextMode: "verification",
|
|
354
368
|
tools: TOOLS_PLANNING,
|
|
355
369
|
artifacts: {
|
|
356
370
|
// Phase 3 migration (#4782): manifest matches today's actual
|
|
@@ -369,6 +383,7 @@ export const UNIT_MANIFESTS = {
|
|
|
369
383
|
memory: "critical-only",
|
|
370
384
|
codebaseMap: false,
|
|
371
385
|
preferences: "active-only",
|
|
386
|
+
contextMode: "verification",
|
|
372
387
|
tools: TOOLS_PLANNING,
|
|
373
388
|
artifacts: {
|
|
374
389
|
inline: ["slice-plan", "prior-task-summaries"],
|
|
@@ -383,6 +398,7 @@ export const UNIT_MANIFESTS = {
|
|
|
383
398
|
memory: "prompt-relevant",
|
|
384
399
|
codebaseMap: true,
|
|
385
400
|
preferences: "active-only",
|
|
401
|
+
contextMode: "docs",
|
|
386
402
|
tools: TOOLS_DOCS,
|
|
387
403
|
artifacts: {
|
|
388
404
|
inline: ["project", "requirements", "decisions", "templates"],
|
|
@@ -401,6 +417,7 @@ export const UNIT_MANIFESTS = {
|
|
|
401
417
|
memory: "none",
|
|
402
418
|
codebaseMap: false,
|
|
403
419
|
preferences: "none",
|
|
420
|
+
contextMode: "none",
|
|
404
421
|
tools: TOOLS_PLANNING,
|
|
405
422
|
artifacts: {
|
|
406
423
|
inline: [],
|
|
@@ -418,6 +435,7 @@ export const UNIT_MANIFESTS = {
|
|
|
418
435
|
memory: "prompt-relevant",
|
|
419
436
|
codebaseMap: true,
|
|
420
437
|
preferences: "active-only",
|
|
438
|
+
contextMode: "interview",
|
|
421
439
|
tools: TOOLS_PLANNING,
|
|
422
440
|
artifacts: {
|
|
423
441
|
inline: ["templates"],
|
|
@@ -434,6 +452,7 @@ export const UNIT_MANIFESTS = {
|
|
|
434
452
|
memory: "prompt-relevant",
|
|
435
453
|
codebaseMap: true,
|
|
436
454
|
preferences: "active-only",
|
|
455
|
+
contextMode: "interview",
|
|
437
456
|
tools: TOOLS_PLANNING,
|
|
438
457
|
artifacts: {
|
|
439
458
|
inline: ["project", "templates"],
|
|
@@ -450,6 +469,7 @@ export const UNIT_MANIFESTS = {
|
|
|
450
469
|
memory: "none",
|
|
451
470
|
codebaseMap: false,
|
|
452
471
|
preferences: "none",
|
|
472
|
+
contextMode: "none",
|
|
453
473
|
tools: TOOLS_PLANNING,
|
|
454
474
|
artifacts: {
|
|
455
475
|
inline: [],
|
|
@@ -468,6 +488,7 @@ export const UNIT_MANIFESTS = {
|
|
|
468
488
|
memory: "prompt-relevant",
|
|
469
489
|
codebaseMap: true,
|
|
470
490
|
preferences: "active-only",
|
|
491
|
+
contextMode: "research",
|
|
471
492
|
tools: { mode: "planning-dispatch", allowedSubagents: ["scout"] },
|
|
472
493
|
artifacts: {
|
|
473
494
|
inline: ["project", "requirements", "templates"],
|