gsd-pi 2.68.1-dev.c1497ab → 2.68.1
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/bootstrap/write-gate.js +5 -1
- package/dist/resources/extensions/gsd/guided-flow.js +70 -25
- package/dist/resources/extensions/gsd/model-router.js +2 -32
- package/dist/resources/extensions/gsd/prompt-validation.js +67 -0
- package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +0 -2
- package/dist/resources/extensions/gsd/templates/context-enhanced.md +138 -0
- package/dist/resources/extensions/gsd/templates/context.md +2 -34
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +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/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +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/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +3 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +5 -1
- package/src/resources/extensions/gsd/guided-flow.ts +84 -22
- package/src/resources/extensions/gsd/model-router.ts +10 -44
- package/src/resources/extensions/gsd/preferences-types.ts +1 -3
- package/src/resources/extensions/gsd/prompt-validation.ts +88 -0
- package/src/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +0 -2
- package/src/resources/extensions/gsd/templates/context-enhanced.md +138 -0
- package/src/resources/extensions/gsd/templates/context.md +2 -34
- package/src/resources/extensions/gsd/tests/adversarial-review-fixes.test.ts +223 -0
- package/src/resources/extensions/gsd/tests/capability-router.test.ts +7 -31
- package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
- package/src/resources/extensions/gsd/tests/integration-prepared-discussion.test.ts +525 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/preparation.test.ts +1211 -0
- package/src/resources/extensions/gsd/tests/prompt-builder.test.ts +669 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +16 -13
- package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- /package/dist/web/standalone/.next/static/{5D80IWYltFwlAJiCZ84MC → u9mQsApZYm8sVYSAaft8g}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{5D80IWYltFwlAJiCZ84MC → u9mQsApZYm8sVYSAaft8g}/_ssgManifest.js +0 -0
|
@@ -53,8 +53,25 @@ import {
|
|
|
53
53
|
runPreparation,
|
|
54
54
|
formatCodebaseBrief,
|
|
55
55
|
formatPriorContextBrief,
|
|
56
|
+
formatEcosystemBrief,
|
|
57
|
+
type PreparationResult,
|
|
56
58
|
} from "./preparation.js";
|
|
57
59
|
|
|
60
|
+
// ─── Preparation result storage ─────────────────────────────────────────────
|
|
61
|
+
// Stores the most recent preparation result for injection into discuss prompts.
|
|
62
|
+
// S02 will consume this when building the prepared discussion prompt.
|
|
63
|
+
let lastPreparationResult: PreparationResult | null = null;
|
|
64
|
+
|
|
65
|
+
/** Get the most recent preparation result (for S02 prompt building). */
|
|
66
|
+
export function getLastPreparationResult(): PreparationResult | null {
|
|
67
|
+
return lastPreparationResult;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Clear the preparation result (called after discussion completes). */
|
|
71
|
+
export function clearPreparationResult(): void {
|
|
72
|
+
lastPreparationResult = null;
|
|
73
|
+
}
|
|
74
|
+
|
|
58
75
|
// ─── Re-exports (preserve public API for existing importers) ────────────────
|
|
59
76
|
export {
|
|
60
77
|
MILESTONE_ID_RE, generateMilestoneSuffix, nextMilestoneId,
|
|
@@ -410,7 +427,7 @@ function resolveAvailableModel<T extends { id: string; provider: string }>(
|
|
|
410
427
|
* Build the discuss-and-plan prompt for a new milestone.
|
|
411
428
|
* Used by all three "new milestone" paths (first ever, no active, all complete).
|
|
412
429
|
*/
|
|
413
|
-
function buildDiscussPrompt(nextId: string, preamble: string, _basePath: string
|
|
430
|
+
function buildDiscussPrompt(nextId: string, preamble: string, _basePath: string): string {
|
|
414
431
|
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
415
432
|
const inlinedTemplates = [
|
|
416
433
|
inlineTemplate("project", "Project"),
|
|
@@ -422,7 +439,6 @@ function buildDiscussPrompt(nextId: string, preamble: string, _basePath: string,
|
|
|
422
439
|
return loadPrompt("discuss", {
|
|
423
440
|
milestoneId: nextId,
|
|
424
441
|
preamble,
|
|
425
|
-
preparationContext: preparationContext ?? "",
|
|
426
442
|
contextPath: `${milestoneRel}/${nextId}-CONTEXT.md`,
|
|
427
443
|
roadmapPath: `${milestoneRel}/${nextId}-ROADMAP.md`,
|
|
428
444
|
inlinedTemplates,
|
|
@@ -455,12 +471,59 @@ function buildHeadlessDiscussPrompt(nextId: string, seedContext: string, _basePa
|
|
|
455
471
|
});
|
|
456
472
|
}
|
|
457
473
|
|
|
474
|
+
/**
|
|
475
|
+
* Build the prepared discuss prompt with brief injection.
|
|
476
|
+
* Uses the discuss-prepared template which encodes the 4-layer discussion protocol.
|
|
477
|
+
*
|
|
478
|
+
* @param nextId - The milestone ID being discussed
|
|
479
|
+
* @param preamble - Preamble text for the discuss prompt
|
|
480
|
+
* @param _basePath - Root directory of the project (unused, kept for signature consistency)
|
|
481
|
+
* @param prepResult - Preparation result containing briefs to inject
|
|
482
|
+
* @returns The prepared discuss prompt string
|
|
483
|
+
*/
|
|
484
|
+
function buildPreparedPrompt(
|
|
485
|
+
nextId: string,
|
|
486
|
+
preamble: string,
|
|
487
|
+
_basePath: string,
|
|
488
|
+
prepResult: PreparationResult,
|
|
489
|
+
): string {
|
|
490
|
+
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
491
|
+
|
|
492
|
+
// Use context-enhanced instead of context for prepared discussions
|
|
493
|
+
const inlinedTemplates = [
|
|
494
|
+
inlineTemplate("project", "Project"),
|
|
495
|
+
inlineTemplate("requirements", "Requirements"),
|
|
496
|
+
inlineTemplate("context-enhanced", "Context Enhanced"),
|
|
497
|
+
inlineTemplate("roadmap", "Roadmap"),
|
|
498
|
+
inlineTemplate("decisions", "Decisions"),
|
|
499
|
+
].join("\n\n---\n\n");
|
|
500
|
+
|
|
501
|
+
// Format the briefs from the preparation result
|
|
502
|
+
const codebaseBrief = prepResult.codebaseBrief || formatCodebaseBrief(prepResult.codebase);
|
|
503
|
+
const priorContextBrief = prepResult.priorContextBrief || formatPriorContextBrief(prepResult.priorContext);
|
|
504
|
+
const ecosystemBrief = prepResult.ecosystemBrief || formatEcosystemBrief(prepResult.ecosystem);
|
|
505
|
+
|
|
506
|
+
return loadPrompt("discuss-prepared", {
|
|
507
|
+
milestoneId: nextId,
|
|
508
|
+
preamble,
|
|
509
|
+
codebaseBrief,
|
|
510
|
+
priorContextBrief,
|
|
511
|
+
ecosystemBrief,
|
|
512
|
+
contextPath: `${milestoneRel}/${nextId}-CONTEXT.md`,
|
|
513
|
+
roadmapPath: `${milestoneRel}/${nextId}-ROADMAP.md`,
|
|
514
|
+
inlinedTemplates,
|
|
515
|
+
commitInstruction: buildDocsCommitInstruction(`docs(${nextId}): context, requirements, and roadmap`),
|
|
516
|
+
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
|
|
458
520
|
/**
|
|
459
521
|
* Run preparation phase if enabled, then build the discuss prompt.
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
522
|
+
* This is the main entry point for new milestone discussions with preparation.
|
|
523
|
+
* Stores the preparation result for S02 to inject into the discuss prompt.
|
|
524
|
+
*
|
|
525
|
+
* When preparation succeeds, uses the discuss-prepared template with brief injection.
|
|
526
|
+
* Falls back to the standard discuss template when preparation is disabled or fails.
|
|
464
527
|
*
|
|
465
528
|
* @param ctx - Extension command context with UI for progress notifications
|
|
466
529
|
* @param nextId - The milestone ID being discussed
|
|
@@ -474,13 +537,14 @@ async function prepareAndBuildDiscussPrompt(
|
|
|
474
537
|
preamble: string,
|
|
475
538
|
basePath: string,
|
|
476
539
|
): Promise<string> {
|
|
540
|
+
// Clear stale preparation result immediately to prevent cross-session/project
|
|
541
|
+
// state leaks. This ensures data from a prior milestone/project never leaks
|
|
542
|
+
// into subsequent discussions (adversarial review fix #3602).
|
|
543
|
+
lastPreparationResult = null;
|
|
544
|
+
|
|
477
545
|
const prefs = loadEffectiveGSDPreferences()?.preferences ?? {};
|
|
478
546
|
|
|
479
|
-
// Run preparation if enabled (default: true)
|
|
480
|
-
// supplementary context into the standard discuss prompt, NOT as a
|
|
481
|
-
// replacement template. The discuss prompt always leads with "What's the
|
|
482
|
-
// vision?" so the user defines the scope, not the codebase analysis.
|
|
483
|
-
let preparationContext = "";
|
|
547
|
+
// Run preparation if enabled (default: true)
|
|
484
548
|
if (prefs.discuss_preparation !== false) {
|
|
485
549
|
try {
|
|
486
550
|
const prepResult = await runPreparation(basePath, ctx.ui, {
|
|
@@ -488,23 +552,21 @@ async function prepareAndBuildDiscussPrompt(
|
|
|
488
552
|
discuss_web_research: prefs.discuss_web_research,
|
|
489
553
|
discuss_depth: prefs.discuss_depth,
|
|
490
554
|
});
|
|
555
|
+
lastPreparationResult = prepResult;
|
|
491
556
|
|
|
557
|
+
// Use prepared prompt if preparation was enabled and produced results
|
|
492
558
|
if (prepResult.enabled) {
|
|
493
|
-
|
|
494
|
-
const priorContextBrief = prepResult.priorContextBrief || formatPriorContextBrief(prepResult.priorContext);
|
|
495
|
-
const parts: string[] = [];
|
|
496
|
-
if (codebaseBrief) parts.push(`### Codebase Brief\n\n${codebaseBrief}`);
|
|
497
|
-
if (priorContextBrief) parts.push(`### Prior Context Brief\n\n${priorContextBrief}`);
|
|
498
|
-
if (parts.length > 0) {
|
|
499
|
-
preparationContext = `\n\n## Preparation Context\n\nThe system analyzed the codebase before this discussion. Use these findings as background context — they describe what already exists, NOT what the user wants to build. Always ask the user what they want to build first.\n\n${parts.join("\n\n")}`;
|
|
500
|
-
}
|
|
559
|
+
return buildPreparedPrompt(nextId, preamble, basePath, prepResult);
|
|
501
560
|
}
|
|
502
|
-
} catch
|
|
503
|
-
|
|
561
|
+
} catch {
|
|
562
|
+
// If preparation throws, ensure stale data doesn't persist
|
|
563
|
+
lastPreparationResult = null;
|
|
504
564
|
}
|
|
505
565
|
}
|
|
506
566
|
|
|
507
|
-
|
|
567
|
+
// Fall back to standard discuss prompt for backward compatibility
|
|
568
|
+
// lastPreparationResult is already null (cleared at entry or on error)
|
|
569
|
+
return buildDiscussPrompt(nextId, preamble, basePath);
|
|
508
570
|
}
|
|
509
571
|
|
|
510
572
|
/**
|
|
@@ -58,7 +58,7 @@ export interface ModelCapabilities {
|
|
|
58
58
|
// Maps known model IDs to their capability tier. Used when tier_models is not
|
|
59
59
|
// explicitly configured to pick the best available model for each tier.
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
const MODEL_CAPABILITY_TIER: Record<string, ComplexityTier> = {
|
|
62
62
|
// Light-tier models (cheapest)
|
|
63
63
|
"claude-haiku-4-5": "light",
|
|
64
64
|
"claude-3-5-haiku-latest": "light",
|
|
@@ -139,49 +139,15 @@ const MODEL_COST_PER_1K_INPUT: Record<string, number> = {
|
|
|
139
139
|
// model selection within an eligible tier set.
|
|
140
140
|
|
|
141
141
|
export const MODEL_CAPABILITY_PROFILES: Record<string, ModelCapabilities> = {
|
|
142
|
-
|
|
143
|
-
"claude-
|
|
144
|
-
"claude-
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"
|
|
150
|
-
"
|
|
151
|
-
|
|
152
|
-
// ── OpenAI GPT ─────────────────────────────────────────────────────────────
|
|
153
|
-
"gpt-4o": { coding: 80, debugging: 75, research: 70, reasoning: 75, speed: 65, longContext: 70, instruction: 80 },
|
|
154
|
-
"gpt-4o-mini": { coding: 55, debugging: 45, research: 40, reasoning: 45, speed: 90, longContext: 45, instruction: 70 },
|
|
155
|
-
"gpt-4-turbo": { coding: 78, debugging: 72, research: 68, reasoning: 72, speed: 50, longContext: 65, instruction: 78 },
|
|
156
|
-
"gpt-4.1": { coding: 82, debugging: 78, research: 72, reasoning: 78, speed: 62, longContext: 72, instruction: 82 },
|
|
157
|
-
"gpt-4.1-mini": { coding: 58, debugging: 48, research: 42, reasoning: 48, speed: 88, longContext: 48, instruction: 72 },
|
|
158
|
-
"gpt-4.1-nano": { coding: 40, debugging: 30, research: 25, reasoning: 30, speed: 95, longContext: 30, instruction: 60 },
|
|
159
|
-
"gpt-5": { coding: 92, debugging: 88, research: 85, reasoning: 92, speed: 40, longContext: 85, instruction: 90 },
|
|
160
|
-
"gpt-5-mini": { coding: 62, debugging: 52, research: 48, reasoning: 52, speed: 88, longContext: 52, instruction: 74 },
|
|
161
|
-
"gpt-5-nano": { coding: 42, debugging: 32, research: 28, reasoning: 32, speed: 95, longContext: 32, instruction: 62 },
|
|
162
|
-
"gpt-5-pro": { coding: 94, debugging: 90, research: 88, reasoning: 94, speed: 35, longContext: 88, instruction: 92 },
|
|
163
|
-
"gpt-5.1": { coding: 93, debugging: 89, research: 86, reasoning: 93, speed: 42, longContext: 86, instruction: 91 },
|
|
164
|
-
"gpt-5.1-codex-max": { coding: 90, debugging: 85, research: 70, reasoning: 85, speed: 55, longContext: 75, instruction: 85 },
|
|
165
|
-
"gpt-5.1-codex-mini": { coding: 65, debugging: 55, research: 40, reasoning: 50, speed: 88, longContext: 48, instruction: 72 },
|
|
166
|
-
"gpt-5.2": { coding: 93, debugging: 90, research: 87, reasoning: 93, speed: 42, longContext: 87, instruction: 91 },
|
|
167
|
-
"gpt-5.2-codex": { coding: 93, debugging: 90, research: 72, reasoning: 88, speed: 50, longContext: 78, instruction: 88 },
|
|
168
|
-
"gpt-5.3-codex": { coding: 94, debugging: 91, research: 74, reasoning: 89, speed: 50, longContext: 80, instruction: 89 },
|
|
169
|
-
"gpt-5.3-codex-spark": { coding: 68, debugging: 58, research: 42, reasoning: 52, speed: 90, longContext: 50, instruction: 74 },
|
|
170
|
-
"gpt-5.4": { coding: 95, debugging: 92, research: 88, reasoning: 94, speed: 42, longContext: 88, instruction: 92 },
|
|
171
|
-
|
|
172
|
-
// ── OpenAI o-series (reasoning-first) ──────────────────────────────────────
|
|
173
|
-
"o1": { coding: 78, debugging: 82, research: 78, reasoning: 90, speed: 20, longContext: 65, instruction: 82 },
|
|
174
|
-
"o3": { coding: 80, debugging: 85, research: 80, reasoning: 92, speed: 25, longContext: 70, instruction: 85 },
|
|
175
|
-
"o4-mini": { coding: 75, debugging: 80, research: 72, reasoning: 88, speed: 60, longContext: 65, instruction: 80 },
|
|
176
|
-
"o4-mini-deep-research": { coding: 75, debugging: 80, research: 85, reasoning: 88, speed: 30, longContext: 80, instruction: 80 },
|
|
177
|
-
|
|
178
|
-
// ── Google ─────────────────────────────────────────────────────────────────
|
|
179
|
-
"gemini-2.5-pro": { coding: 75, debugging: 70, research: 85, reasoning: 75, speed: 55, longContext: 90, instruction: 75 },
|
|
180
|
-
"gemini-2.0-flash": { coding: 50, debugging: 40, research: 50, reasoning: 40, speed: 95, longContext: 60, instruction: 65 },
|
|
181
|
-
"gemini-flash-2.0": { coding: 50, debugging: 40, research: 50, reasoning: 40, speed: 95, longContext: 60, instruction: 65 },
|
|
182
|
-
|
|
183
|
-
// ── DeepSeek ───────────────────────────────────────────────────────────────
|
|
184
|
-
"deepseek-chat": { coding: 75, debugging: 65, research: 55, reasoning: 70, speed: 70, longContext: 55, instruction: 65 },
|
|
142
|
+
"claude-opus-4-6": { coding: 95, debugging: 90, research: 85, reasoning: 95, speed: 30, longContext: 80, instruction: 90 },
|
|
143
|
+
"claude-sonnet-4-6": { coding: 85, debugging: 80, research: 75, reasoning: 80, speed: 60, longContext: 75, instruction: 85 },
|
|
144
|
+
"claude-haiku-4-5": { coding: 60, debugging: 50, research: 45, reasoning: 50, speed: 95, longContext: 50, instruction: 75 },
|
|
145
|
+
"gpt-4o": { coding: 80, debugging: 75, research: 70, reasoning: 75, speed: 65, longContext: 70, instruction: 80 },
|
|
146
|
+
"gpt-4o-mini": { coding: 55, debugging: 45, research: 40, reasoning: 45, speed: 90, longContext: 45, instruction: 70 },
|
|
147
|
+
"gemini-2.5-pro": { coding: 75, debugging: 70, research: 85, reasoning: 75, speed: 55, longContext: 90, instruction: 75 },
|
|
148
|
+
"gemini-2.0-flash": { coding: 50, debugging: 40, research: 50, reasoning: 40, speed: 95, longContext: 60, instruction: 65 },
|
|
149
|
+
"deepseek-chat": { coding: 75, debugging: 65, research: 55, reasoning: 70, speed: 70, longContext: 55, instruction: 65 },
|
|
150
|
+
"o3": { coding: 80, debugging: 85, research: 80, reasoning: 92, speed: 25, longContext: 70, instruction: 85 },
|
|
185
151
|
};
|
|
186
152
|
|
|
187
153
|
// ─── Base Task Requirements Data Table ───────────────────────────────────────
|
|
@@ -20,7 +20,7 @@ import type {
|
|
|
20
20
|
ReactiveExecutionConfig,
|
|
21
21
|
GateEvaluationConfig,
|
|
22
22
|
} from "./types.js";
|
|
23
|
-
import type { DynamicRoutingConfig
|
|
23
|
+
import type { DynamicRoutingConfig } from "./model-router.js";
|
|
24
24
|
|
|
25
25
|
export interface ContextManagementConfig {
|
|
26
26
|
observation_masking?: boolean; // default: true
|
|
@@ -255,8 +255,6 @@ export interface GSDPreferences {
|
|
|
255
255
|
post_unit_hooks?: PostUnitHookConfig[];
|
|
256
256
|
pre_dispatch_hooks?: PreDispatchHookConfig[];
|
|
257
257
|
dynamic_routing?: DynamicRoutingConfig;
|
|
258
|
-
/** Per-model capability overrides. Deep-merged with built-in profiles for capability-aware routing (ADR-004). */
|
|
259
|
-
modelOverrides?: Record<string, { capabilities?: Partial<ModelCapabilities> }>;
|
|
260
258
|
context_management?: ContextManagementConfig;
|
|
261
259
|
token_profile?: TokenProfile;
|
|
262
260
|
phases?: PhaseSkipPreferences;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD Prompt Validation — Validates enhanced context output before writing.
|
|
3
|
+
*
|
|
4
|
+
* Implements R109 validation requirement: CONTEXT.md must have required sections
|
|
5
|
+
* before being written to disk.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Result of validating enhanced context output.
|
|
10
|
+
*/
|
|
11
|
+
export interface ValidationResult {
|
|
12
|
+
/** Whether all required sections are present. */
|
|
13
|
+
valid: boolean;
|
|
14
|
+
/** List of missing required sections. */
|
|
15
|
+
missing: string[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Validate that enhanced context content has all required sections.
|
|
20
|
+
*
|
|
21
|
+
* Required sections per R109:
|
|
22
|
+
* - Scope section (## Scope, ## Milestone Scope, or ## Why This Milestone)
|
|
23
|
+
* - Architectural Decisions section (## Architectural Decisions)
|
|
24
|
+
* - Acceptance Criteria section (## Acceptance Criteria or ## Final Integrated Acceptance)
|
|
25
|
+
*
|
|
26
|
+
* Additionally validates that the Architectural Decisions section contains
|
|
27
|
+
* at least one decision entry (### heading or **Decision marker).
|
|
28
|
+
*
|
|
29
|
+
* @param content - The enhanced context markdown content
|
|
30
|
+
* @returns ValidationResult with valid flag and list of missing sections
|
|
31
|
+
*/
|
|
32
|
+
export function validateEnhancedContext(content: string): ValidationResult {
|
|
33
|
+
const missing: string[] = [];
|
|
34
|
+
|
|
35
|
+
// Required section 1: Scope (multiple acceptable header variants)
|
|
36
|
+
const hasScopeSection =
|
|
37
|
+
/^## Scope\b/m.test(content) ||
|
|
38
|
+
/^## Milestone Scope\b/m.test(content) ||
|
|
39
|
+
/^## Why This Milestone\b/m.test(content);
|
|
40
|
+
|
|
41
|
+
if (!hasScopeSection) {
|
|
42
|
+
missing.push("Milestone Scope or Why This Milestone");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Required section 2: Architectural Decisions
|
|
46
|
+
const hasArchitecturalDecisions = /^## Architectural Decisions\b/m.test(content);
|
|
47
|
+
if (!hasArchitecturalDecisions) {
|
|
48
|
+
missing.push("Architectural Decisions");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Required section 3: Acceptance Criteria (multiple acceptable header variants)
|
|
52
|
+
const hasAcceptanceCriteria =
|
|
53
|
+
/^## Acceptance Criteria\b/m.test(content) ||
|
|
54
|
+
/^## Final Integrated Acceptance\b/m.test(content);
|
|
55
|
+
|
|
56
|
+
if (!hasAcceptanceCriteria) {
|
|
57
|
+
missing.push("Acceptance Criteria");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Additional validation: Architectural Decisions must have at least one entry
|
|
61
|
+
if (hasArchitecturalDecisions) {
|
|
62
|
+
// Extract the section content between ## Architectural Decisions and the next ## heading.
|
|
63
|
+
// Uses indexOf-based extraction instead of regex with \z (which is invalid in JavaScript
|
|
64
|
+
// regex — it's PCRE/Ruby syntax and JS treats it as literal 'z').
|
|
65
|
+
const sectionStart = content.indexOf("## Architectural Decisions");
|
|
66
|
+
if (sectionStart === -1) {
|
|
67
|
+
missing.push("Architectural Decisions");
|
|
68
|
+
} else {
|
|
69
|
+
const afterHeading = content.slice(sectionStart + "## Architectural Decisions".length);
|
|
70
|
+
const nextSection = afterHeading.search(/^## /m);
|
|
71
|
+
const sectionContent = nextSection === -1 ? afterHeading : afterHeading.slice(0, nextSection);
|
|
72
|
+
|
|
73
|
+
// Check for actual decision entries:
|
|
74
|
+
// - ### heading (subsection per decision)
|
|
75
|
+
// - **Decision marker (inline decision format)
|
|
76
|
+
const hasDecisionEntry = /^### /m.test(sectionContent) || /^\*\*Decision/m.test(sectionContent);
|
|
77
|
+
|
|
78
|
+
if (!hasDecisionEntry) {
|
|
79
|
+
missing.push("At least one architectural decision entry");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
valid: missing.length === 0,
|
|
86
|
+
missing,
|
|
87
|
+
};
|
|
88
|
+
}
|