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
|
@@ -40,9 +40,13 @@ let activeQueuePhase = false;
|
|
|
40
40
|
let pendingGateId = null;
|
|
41
41
|
/**
|
|
42
42
|
* Recognized gate question ID patterns.
|
|
43
|
-
* These appear in discuss.md (depth/requirements/roadmap).
|
|
43
|
+
* These appear in both discuss-prepared.md (4-layer) and discuss.md (depth/requirements/roadmap).
|
|
44
44
|
*/
|
|
45
45
|
const GATE_QUESTION_PATTERNS = [
|
|
46
|
+
"layer1_scope_gate",
|
|
47
|
+
"layer2_architecture_gate",
|
|
48
|
+
"layer3_error_gate",
|
|
49
|
+
"layer4_quality_gate",
|
|
46
50
|
"depth_verification",
|
|
47
51
|
];
|
|
48
52
|
/**
|
|
@@ -36,7 +36,19 @@ import { parkMilestone, discardMilestone } from "./milestone-actions.js";
|
|
|
36
36
|
import { selectAndApplyModel } from "./auto-model-selection.js";
|
|
37
37
|
import { DISCUSS_TOOLS_ALLOWLIST } from "./constants.js";
|
|
38
38
|
import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForGuidedUnit, } from "./workflow-mcp.js";
|
|
39
|
-
import { runPreparation, formatCodebaseBrief, formatPriorContextBrief, } from "./preparation.js";
|
|
39
|
+
import { runPreparation, formatCodebaseBrief, formatPriorContextBrief, formatEcosystemBrief, } from "./preparation.js";
|
|
40
|
+
// ─── Preparation result storage ─────────────────────────────────────────────
|
|
41
|
+
// Stores the most recent preparation result for injection into discuss prompts.
|
|
42
|
+
// S02 will consume this when building the prepared discussion prompt.
|
|
43
|
+
let lastPreparationResult = null;
|
|
44
|
+
/** Get the most recent preparation result (for S02 prompt building). */
|
|
45
|
+
export function getLastPreparationResult() {
|
|
46
|
+
return lastPreparationResult;
|
|
47
|
+
}
|
|
48
|
+
/** Clear the preparation result (called after discussion completes). */
|
|
49
|
+
export function clearPreparationResult() {
|
|
50
|
+
lastPreparationResult = null;
|
|
51
|
+
}
|
|
40
52
|
// ─── Re-exports (preserve public API for existing importers) ────────────────
|
|
41
53
|
export { MILESTONE_ID_RE, generateMilestoneSuffix, nextMilestoneId, extractMilestoneSeq, parseMilestoneId, milestoneIdSort, maxMilestoneNum, findMilestoneIds, reserveMilestoneId, claimReservedId, getReservedMilestoneIds, clearReservedMilestoneIds, } from "./milestone-ids.js";
|
|
42
54
|
export { showQueue, handleQueueReorder, showQueueAdd, buildExistingMilestonesContext, } from "./guided-flow-queue.js";
|
|
@@ -323,7 +335,7 @@ function resolveAvailableModel(modelId, availableModels, currentProvider) {
|
|
|
323
335
|
* Build the discuss-and-plan prompt for a new milestone.
|
|
324
336
|
* Used by all three "new milestone" paths (first ever, no active, all complete).
|
|
325
337
|
*/
|
|
326
|
-
function buildDiscussPrompt(nextId, preamble, _basePath
|
|
338
|
+
function buildDiscussPrompt(nextId, preamble, _basePath) {
|
|
327
339
|
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
328
340
|
const inlinedTemplates = [
|
|
329
341
|
inlineTemplate("project", "Project"),
|
|
@@ -335,7 +347,6 @@ function buildDiscussPrompt(nextId, preamble, _basePath, preparationContext) {
|
|
|
335
347
|
return loadPrompt("discuss", {
|
|
336
348
|
milestoneId: nextId,
|
|
337
349
|
preamble,
|
|
338
|
-
preparationContext: preparationContext ?? "",
|
|
339
350
|
contextPath: `${milestoneRel}/${nextId}-CONTEXT.md`,
|
|
340
351
|
roadmapPath: `${milestoneRel}/${nextId}-ROADMAP.md`,
|
|
341
352
|
inlinedTemplates,
|
|
@@ -366,12 +377,50 @@ function buildHeadlessDiscussPrompt(nextId, seedContext, _basePath) {
|
|
|
366
377
|
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
367
378
|
});
|
|
368
379
|
}
|
|
380
|
+
/**
|
|
381
|
+
* Build the prepared discuss prompt with brief injection.
|
|
382
|
+
* Uses the discuss-prepared template which encodes the 4-layer discussion protocol.
|
|
383
|
+
*
|
|
384
|
+
* @param nextId - The milestone ID being discussed
|
|
385
|
+
* @param preamble - Preamble text for the discuss prompt
|
|
386
|
+
* @param _basePath - Root directory of the project (unused, kept for signature consistency)
|
|
387
|
+
* @param prepResult - Preparation result containing briefs to inject
|
|
388
|
+
* @returns The prepared discuss prompt string
|
|
389
|
+
*/
|
|
390
|
+
function buildPreparedPrompt(nextId, preamble, _basePath, prepResult) {
|
|
391
|
+
const milestoneRel = `.gsd/milestones/${nextId}`;
|
|
392
|
+
// Use context-enhanced instead of context for prepared discussions
|
|
393
|
+
const inlinedTemplates = [
|
|
394
|
+
inlineTemplate("project", "Project"),
|
|
395
|
+
inlineTemplate("requirements", "Requirements"),
|
|
396
|
+
inlineTemplate("context-enhanced", "Context Enhanced"),
|
|
397
|
+
inlineTemplate("roadmap", "Roadmap"),
|
|
398
|
+
inlineTemplate("decisions", "Decisions"),
|
|
399
|
+
].join("\n\n---\n\n");
|
|
400
|
+
// Format the briefs from the preparation result
|
|
401
|
+
const codebaseBrief = prepResult.codebaseBrief || formatCodebaseBrief(prepResult.codebase);
|
|
402
|
+
const priorContextBrief = prepResult.priorContextBrief || formatPriorContextBrief(prepResult.priorContext);
|
|
403
|
+
const ecosystemBrief = prepResult.ecosystemBrief || formatEcosystemBrief(prepResult.ecosystem);
|
|
404
|
+
return loadPrompt("discuss-prepared", {
|
|
405
|
+
milestoneId: nextId,
|
|
406
|
+
preamble,
|
|
407
|
+
codebaseBrief,
|
|
408
|
+
priorContextBrief,
|
|
409
|
+
ecosystemBrief,
|
|
410
|
+
contextPath: `${milestoneRel}/${nextId}-CONTEXT.md`,
|
|
411
|
+
roadmapPath: `${milestoneRel}/${nextId}-ROADMAP.md`,
|
|
412
|
+
inlinedTemplates,
|
|
413
|
+
commitInstruction: buildDocsCommitInstruction(`docs(${nextId}): context, requirements, and roadmap`),
|
|
414
|
+
multiMilestoneCommitInstruction: buildDocsCommitInstruction("docs: project plan — N milestones"),
|
|
415
|
+
});
|
|
416
|
+
}
|
|
369
417
|
/**
|
|
370
418
|
* Run preparation phase if enabled, then build the discuss prompt.
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
419
|
+
* This is the main entry point for new milestone discussions with preparation.
|
|
420
|
+
* Stores the preparation result for S02 to inject into the discuss prompt.
|
|
421
|
+
*
|
|
422
|
+
* When preparation succeeds, uses the discuss-prepared template with brief injection.
|
|
423
|
+
* Falls back to the standard discuss template when preparation is disabled or fails.
|
|
375
424
|
*
|
|
376
425
|
* @param ctx - Extension command context with UI for progress notifications
|
|
377
426
|
* @param nextId - The milestone ID being discussed
|
|
@@ -380,12 +429,12 @@ function buildHeadlessDiscussPrompt(nextId, seedContext, _basePath) {
|
|
|
380
429
|
* @returns The discuss prompt string
|
|
381
430
|
*/
|
|
382
431
|
async function prepareAndBuildDiscussPrompt(ctx, nextId, preamble, basePath) {
|
|
432
|
+
// Clear stale preparation result immediately to prevent cross-session/project
|
|
433
|
+
// state leaks. This ensures data from a prior milestone/project never leaks
|
|
434
|
+
// into subsequent discussions (adversarial review fix #3602).
|
|
435
|
+
lastPreparationResult = null;
|
|
383
436
|
const prefs = loadEffectiveGSDPreferences()?.preferences ?? {};
|
|
384
|
-
// Run preparation if enabled (default: true)
|
|
385
|
-
// supplementary context into the standard discuss prompt, NOT as a
|
|
386
|
-
// replacement template. The discuss prompt always leads with "What's the
|
|
387
|
-
// vision?" so the user defines the scope, not the codebase analysis.
|
|
388
|
-
let preparationContext = "";
|
|
437
|
+
// Run preparation if enabled (default: true)
|
|
389
438
|
if (prefs.discuss_preparation !== false) {
|
|
390
439
|
try {
|
|
391
440
|
const prepResult = await runPreparation(basePath, ctx.ui, {
|
|
@@ -393,24 +442,20 @@ async function prepareAndBuildDiscussPrompt(ctx, nextId, preamble, basePath) {
|
|
|
393
442
|
discuss_web_research: prefs.discuss_web_research,
|
|
394
443
|
discuss_depth: prefs.discuss_depth,
|
|
395
444
|
});
|
|
445
|
+
lastPreparationResult = prepResult;
|
|
446
|
+
// Use prepared prompt if preparation was enabled and produced results
|
|
396
447
|
if (prepResult.enabled) {
|
|
397
|
-
|
|
398
|
-
const priorContextBrief = prepResult.priorContextBrief || formatPriorContextBrief(prepResult.priorContext);
|
|
399
|
-
const parts = [];
|
|
400
|
-
if (codebaseBrief)
|
|
401
|
-
parts.push(`### Codebase Brief\n\n${codebaseBrief}`);
|
|
402
|
-
if (priorContextBrief)
|
|
403
|
-
parts.push(`### Prior Context Brief\n\n${priorContextBrief}`);
|
|
404
|
-
if (parts.length > 0) {
|
|
405
|
-
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")}`;
|
|
406
|
-
}
|
|
448
|
+
return buildPreparedPrompt(nextId, preamble, basePath, prepResult);
|
|
407
449
|
}
|
|
408
450
|
}
|
|
409
|
-
catch
|
|
410
|
-
|
|
451
|
+
catch {
|
|
452
|
+
// If preparation throws, ensure stale data doesn't persist
|
|
453
|
+
lastPreparationResult = null;
|
|
411
454
|
}
|
|
412
455
|
}
|
|
413
|
-
|
|
456
|
+
// Fall back to standard discuss prompt for backward compatibility
|
|
457
|
+
// lastPreparationResult is already null (cleared at entry or on error)
|
|
458
|
+
return buildDiscussPrompt(nextId, preamble, basePath);
|
|
414
459
|
}
|
|
415
460
|
/**
|
|
416
461
|
* Bootstrap a .gsd/ project from scratch for headless use.
|
|
@@ -5,7 +5,7 @@ import { tierOrdinal } from "./complexity-classifier.js";
|
|
|
5
5
|
// ─── Known Model Tiers ───────────────────────────────────────────────────────
|
|
6
6
|
// Maps known model IDs to their capability tier. Used when tier_models is not
|
|
7
7
|
// explicitly configured to pick the best available model for each tier.
|
|
8
|
-
|
|
8
|
+
const MODEL_CAPABILITY_TIER = {
|
|
9
9
|
// Light-tier models (cheapest)
|
|
10
10
|
"claude-haiku-4-5": "light",
|
|
11
11
|
"claude-3-5-haiku-latest": "light",
|
|
@@ -80,45 +80,15 @@ const MODEL_COST_PER_1K_INPUT = {
|
|
|
80
80
|
// Per-model capability profiles (0–100 scale). Used for capability-aware
|
|
81
81
|
// model selection within an eligible tier set.
|
|
82
82
|
export const MODEL_CAPABILITY_PROFILES = {
|
|
83
|
-
// ── Anthropic ──────────────────────────────────────────────────────────────
|
|
84
83
|
"claude-opus-4-6": { coding: 95, debugging: 90, research: 85, reasoning: 95, speed: 30, longContext: 80, instruction: 90 },
|
|
85
84
|
"claude-sonnet-4-6": { coding: 85, debugging: 80, research: 75, reasoning: 80, speed: 60, longContext: 75, instruction: 85 },
|
|
86
|
-
"claude-sonnet-4-5-20250514": { coding: 85, debugging: 80, research: 75, reasoning: 80, speed: 60, longContext: 75, instruction: 85 },
|
|
87
|
-
"claude-3-5-sonnet-latest": { coding: 82, debugging: 78, research: 72, reasoning: 78, speed: 62, longContext: 70, instruction: 82 },
|
|
88
85
|
"claude-haiku-4-5": { coding: 60, debugging: 50, research: 45, reasoning: 50, speed: 95, longContext: 50, instruction: 75 },
|
|
89
|
-
"claude-3-5-haiku-latest": { coding: 60, debugging: 50, research: 45, reasoning: 50, speed: 95, longContext: 50, instruction: 75 },
|
|
90
|
-
"claude-3-haiku-20240307": { coding: 50, debugging: 40, research: 35, reasoning: 40, speed: 95, longContext: 40, instruction: 65 },
|
|
91
|
-
"claude-3-opus-latest": { coding: 90, debugging: 85, research: 82, reasoning: 90, speed: 35, longContext: 75, instruction: 88 },
|
|
92
|
-
// ── OpenAI GPT ─────────────────────────────────────────────────────────────
|
|
93
86
|
"gpt-4o": { coding: 80, debugging: 75, research: 70, reasoning: 75, speed: 65, longContext: 70, instruction: 80 },
|
|
94
87
|
"gpt-4o-mini": { coding: 55, debugging: 45, research: 40, reasoning: 45, speed: 90, longContext: 45, instruction: 70 },
|
|
95
|
-
"gpt-4-turbo": { coding: 78, debugging: 72, research: 68, reasoning: 72, speed: 50, longContext: 65, instruction: 78 },
|
|
96
|
-
"gpt-4.1": { coding: 82, debugging: 78, research: 72, reasoning: 78, speed: 62, longContext: 72, instruction: 82 },
|
|
97
|
-
"gpt-4.1-mini": { coding: 58, debugging: 48, research: 42, reasoning: 48, speed: 88, longContext: 48, instruction: 72 },
|
|
98
|
-
"gpt-4.1-nano": { coding: 40, debugging: 30, research: 25, reasoning: 30, speed: 95, longContext: 30, instruction: 60 },
|
|
99
|
-
"gpt-5": { coding: 92, debugging: 88, research: 85, reasoning: 92, speed: 40, longContext: 85, instruction: 90 },
|
|
100
|
-
"gpt-5-mini": { coding: 62, debugging: 52, research: 48, reasoning: 52, speed: 88, longContext: 52, instruction: 74 },
|
|
101
|
-
"gpt-5-nano": { coding: 42, debugging: 32, research: 28, reasoning: 32, speed: 95, longContext: 32, instruction: 62 },
|
|
102
|
-
"gpt-5-pro": { coding: 94, debugging: 90, research: 88, reasoning: 94, speed: 35, longContext: 88, instruction: 92 },
|
|
103
|
-
"gpt-5.1": { coding: 93, debugging: 89, research: 86, reasoning: 93, speed: 42, longContext: 86, instruction: 91 },
|
|
104
|
-
"gpt-5.1-codex-max": { coding: 90, debugging: 85, research: 70, reasoning: 85, speed: 55, longContext: 75, instruction: 85 },
|
|
105
|
-
"gpt-5.1-codex-mini": { coding: 65, debugging: 55, research: 40, reasoning: 50, speed: 88, longContext: 48, instruction: 72 },
|
|
106
|
-
"gpt-5.2": { coding: 93, debugging: 90, research: 87, reasoning: 93, speed: 42, longContext: 87, instruction: 91 },
|
|
107
|
-
"gpt-5.2-codex": { coding: 93, debugging: 90, research: 72, reasoning: 88, speed: 50, longContext: 78, instruction: 88 },
|
|
108
|
-
"gpt-5.3-codex": { coding: 94, debugging: 91, research: 74, reasoning: 89, speed: 50, longContext: 80, instruction: 89 },
|
|
109
|
-
"gpt-5.3-codex-spark": { coding: 68, debugging: 58, research: 42, reasoning: 52, speed: 90, longContext: 50, instruction: 74 },
|
|
110
|
-
"gpt-5.4": { coding: 95, debugging: 92, research: 88, reasoning: 94, speed: 42, longContext: 88, instruction: 92 },
|
|
111
|
-
// ── OpenAI o-series (reasoning-first) ──────────────────────────────────────
|
|
112
|
-
"o1": { coding: 78, debugging: 82, research: 78, reasoning: 90, speed: 20, longContext: 65, instruction: 82 },
|
|
113
|
-
"o3": { coding: 80, debugging: 85, research: 80, reasoning: 92, speed: 25, longContext: 70, instruction: 85 },
|
|
114
|
-
"o4-mini": { coding: 75, debugging: 80, research: 72, reasoning: 88, speed: 60, longContext: 65, instruction: 80 },
|
|
115
|
-
"o4-mini-deep-research": { coding: 75, debugging: 80, research: 85, reasoning: 88, speed: 30, longContext: 80, instruction: 80 },
|
|
116
|
-
// ── Google ─────────────────────────────────────────────────────────────────
|
|
117
88
|
"gemini-2.5-pro": { coding: 75, debugging: 70, research: 85, reasoning: 75, speed: 55, longContext: 90, instruction: 75 },
|
|
118
89
|
"gemini-2.0-flash": { coding: 50, debugging: 40, research: 50, reasoning: 40, speed: 95, longContext: 60, instruction: 65 },
|
|
119
|
-
"gemini-flash-2.0": { coding: 50, debugging: 40, research: 50, reasoning: 40, speed: 95, longContext: 60, instruction: 65 },
|
|
120
|
-
// ── DeepSeek ───────────────────────────────────────────────────────────────
|
|
121
90
|
"deepseek-chat": { coding: 75, debugging: 65, research: 55, reasoning: 70, speed: 70, longContext: 55, instruction: 65 },
|
|
91
|
+
"o3": { coding: 80, debugging: 85, research: 80, reasoning: 92, speed: 25, longContext: 70, instruction: 85 },
|
|
122
92
|
};
|
|
123
93
|
// ─── Base Task Requirements Data Table ───────────────────────────────────────
|
|
124
94
|
// Per-unit-type base requirement vectors. Weights indicate how important each
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
* Validate that enhanced context content has all required sections.
|
|
9
|
+
*
|
|
10
|
+
* Required sections per R109:
|
|
11
|
+
* - Scope section (## Scope, ## Milestone Scope, or ## Why This Milestone)
|
|
12
|
+
* - Architectural Decisions section (## Architectural Decisions)
|
|
13
|
+
* - Acceptance Criteria section (## Acceptance Criteria or ## Final Integrated Acceptance)
|
|
14
|
+
*
|
|
15
|
+
* Additionally validates that the Architectural Decisions section contains
|
|
16
|
+
* at least one decision entry (### heading or **Decision marker).
|
|
17
|
+
*
|
|
18
|
+
* @param content - The enhanced context markdown content
|
|
19
|
+
* @returns ValidationResult with valid flag and list of missing sections
|
|
20
|
+
*/
|
|
21
|
+
export function validateEnhancedContext(content) {
|
|
22
|
+
const missing = [];
|
|
23
|
+
// Required section 1: Scope (multiple acceptable header variants)
|
|
24
|
+
const hasScopeSection = /^## Scope\b/m.test(content) ||
|
|
25
|
+
/^## Milestone Scope\b/m.test(content) ||
|
|
26
|
+
/^## Why This Milestone\b/m.test(content);
|
|
27
|
+
if (!hasScopeSection) {
|
|
28
|
+
missing.push("Milestone Scope or Why This Milestone");
|
|
29
|
+
}
|
|
30
|
+
// Required section 2: Architectural Decisions
|
|
31
|
+
const hasArchitecturalDecisions = /^## Architectural Decisions\b/m.test(content);
|
|
32
|
+
if (!hasArchitecturalDecisions) {
|
|
33
|
+
missing.push("Architectural Decisions");
|
|
34
|
+
}
|
|
35
|
+
// Required section 3: Acceptance Criteria (multiple acceptable header variants)
|
|
36
|
+
const hasAcceptanceCriteria = /^## Acceptance Criteria\b/m.test(content) ||
|
|
37
|
+
/^## Final Integrated Acceptance\b/m.test(content);
|
|
38
|
+
if (!hasAcceptanceCriteria) {
|
|
39
|
+
missing.push("Acceptance Criteria");
|
|
40
|
+
}
|
|
41
|
+
// Additional validation: Architectural Decisions must have at least one entry
|
|
42
|
+
if (hasArchitecturalDecisions) {
|
|
43
|
+
// Extract the section content between ## Architectural Decisions and the next ## heading.
|
|
44
|
+
// Uses indexOf-based extraction instead of regex with \z (which is invalid in JavaScript
|
|
45
|
+
// regex — it's PCRE/Ruby syntax and JS treats it as literal 'z').
|
|
46
|
+
const sectionStart = content.indexOf("## Architectural Decisions");
|
|
47
|
+
if (sectionStart === -1) {
|
|
48
|
+
missing.push("Architectural Decisions");
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
const afterHeading = content.slice(sectionStart + "## Architectural Decisions".length);
|
|
52
|
+
const nextSection = afterHeading.search(/^## /m);
|
|
53
|
+
const sectionContent = nextSection === -1 ? afterHeading : afterHeading.slice(0, nextSection);
|
|
54
|
+
// Check for actual decision entries:
|
|
55
|
+
// - ### heading (subsection per decision)
|
|
56
|
+
// - **Decision marker (inline decision format)
|
|
57
|
+
const hasDecisionEntry = /^### /m.test(sectionContent) || /^\*\*Decision/m.test(sectionContent);
|
|
58
|
+
if (!hasDecisionEntry) {
|
|
59
|
+
missing.push("At least one architectural decision entry");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
valid: missing.length === 0,
|
|
65
|
+
missing,
|
|
66
|
+
};
|
|
67
|
+
}
|