gsd-pi 2.81.0-dev.72a81bdf3 → 2.82.0-dev.2841a1e44
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 +49 -30
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +3 -1
- package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
- package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +113 -6
- package/dist/resources/extensions/gsd/auto/phases.js +9 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +169 -124
- package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
- package/dist/resources/extensions/gsd/auto-verification.js +28 -22
- package/dist/resources/extensions/gsd/auto.js +128 -52
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +5 -0
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +16 -7
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +3 -1
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +4 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -1
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
- package/dist/resources/extensions/gsd/context-store.js +112 -0
- package/dist/resources/extensions/gsd/db-writer.js +150 -84
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
- package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
- package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
- package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
- package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +6 -1
- package/dist/resources/extensions/gsd/md-importer.js +1 -1
- package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
- package/dist/resources/extensions/gsd/migrate/command.js +5 -0
- package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
- package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
- package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
- package/dist/resources/extensions/gsd/prompts/system.md +2 -2
- package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
- package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +25 -2
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +21 -2
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +122 -0
- package/dist/resources/extensions/visual-brief/prompts.js +111 -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 +15 -15
- 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/react-loadable-manifest.json +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_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 +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +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 +15 -15
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-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/.next/static/chunks/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/{8359.e059d86b255fce1c.js → 8359.7eb3bb8f8ecf4c01.js} +2 -2
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-6a95bc41e0f7ec89.js} +1 -1
- package/dist/web/standalone/.next/static/css/0262768ec1b89d34.css +1 -0
- package/package.json +5 -4
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +14 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -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-parity.test.ts +244 -0
- package/packages/mcp-server/src/workflow-tools.test.ts +22 -0
- package/packages/mcp-server/src/workflow-tools.ts +168 -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-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -2
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -1
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/index.ts +7 -2
- package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
- package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +5 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/tui.ts +6 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +3 -1
- package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
- package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +46 -11
- package/src/resources/extensions/gsd/auto/orchestrator.ts +118 -6
- package/src/resources/extensions/gsd/auto/phases.ts +14 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +194 -137
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
- package/src/resources/extensions/gsd/auto-verification.ts +36 -34
- package/src/resources/extensions/gsd/auto.ts +136 -51
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +6 -0
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +16 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +3 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +4 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +25 -1
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/context-store.ts +120 -1
- package/src/resources/extensions/gsd/db-writer.ts +167 -84
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
- package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
- package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
- package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +6 -1
- package/src/resources/extensions/gsd/md-importer.ts +1 -1
- package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
- package/src/resources/extensions/gsd/migrate/command.ts +5 -0
- package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
- package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
- package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
- package/src/resources/extensions/gsd/prompts/system.md +2 -2
- package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
- package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +408 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
- package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
- package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +16 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +35 -2
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +20 -2
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +134 -0
- package/src/resources/extensions/visual-brief/prompts.ts +147 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +172 -0
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → Qgr2B_MRhPxC0z8fwv4vT}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → Qgr2B_MRhPxC0z8fwv4vT}/_ssgManifest.js +0 -0
|
@@ -240,12 +240,14 @@ import { runAutoLoopWithUok } from "./uok/kernel.js";
|
|
|
240
240
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
241
241
|
import { validateDirectory } from "./validate-directory.js";
|
|
242
242
|
import { createAutoOrchestrator } from "./auto/orchestrator.js";
|
|
243
|
-
import type { AutoOrchestrationModule, AutoOrchestratorDeps } from "./auto/contracts.js";
|
|
243
|
+
import type { AutoOrchestrationModule, AutoOrchestratorDeps, DispatchAdapter } from "./auto/contracts.js";
|
|
244
244
|
import { reconcileBeforeDispatch } from "./state-reconciliation.js";
|
|
245
245
|
import { compileUnitToolContract } from "./tool-contract.js";
|
|
246
246
|
import { createWorktreeSafetyModule } from "./worktree-safety.js";
|
|
247
247
|
import { resolveManifest } from "./unit-context-manifest.js";
|
|
248
248
|
import { classifyFailure } from "./recovery-classification.js";
|
|
249
|
+
import { supportsStructuredQuestions } from "./workflow-mcp.js";
|
|
250
|
+
import type { MinimalModelRegistry } from "./context-budget.js";
|
|
249
251
|
// Slice-level parallelism (#2340)
|
|
250
252
|
import { getEligibleSlices } from "./slice-parallel-eligibility.js";
|
|
251
253
|
import { startSliceParallel } from "./slice-parallel-orchestrator.js";
|
|
@@ -1048,13 +1050,11 @@ export async function cleanupAfterLoopExit(ctx: ExtensionContext): Promise<void>
|
|
|
1048
1050
|
initHealthWidget(ctx);
|
|
1049
1051
|
}
|
|
1050
1052
|
|
|
1051
|
-
// ADR-016 phase 3 (#5693): the stop-path basePath restore routes
|
|
1052
|
-
// `Lifecycle.restoreToProjectRoot()`, the sole owner of
|
|
1053
|
-
//
|
|
1054
|
-
//
|
|
1055
|
-
//
|
|
1056
|
-
// The chdir stays here because `restoreToProjectRoot` is a pure
|
|
1057
|
-
// session-state mutation.
|
|
1053
|
+
// ADR-016 phase 3 (#5693): the stop-path basePath restore + chdir routes
|
|
1054
|
+
// through `Lifecycle.restoreToProjectRoot()`, the sole owner of both
|
|
1055
|
+
// `s.basePath` mutation and the paired `process.chdir` for auto-loop
|
|
1056
|
+
// transitions. The verb assigns `s.basePath` before any throwable work, so
|
|
1057
|
+
// a thrown error still leaves basePath restored.
|
|
1058
1058
|
if (s.originalBasePath) {
|
|
1059
1059
|
try {
|
|
1060
1060
|
buildLifecycle().restoreToProjectRoot();
|
|
@@ -1065,11 +1065,6 @@ export async function cleanupAfterLoopExit(ctx: ExtensionContext): Promise<void>
|
|
|
1065
1065
|
{ file: "auto.ts" },
|
|
1066
1066
|
);
|
|
1067
1067
|
}
|
|
1068
|
-
try {
|
|
1069
|
-
process.chdir(s.originalBasePath);
|
|
1070
|
-
} catch (err) {
|
|
1071
|
-
logWarning("engine", `basePath restore/chdir failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1072
|
-
}
|
|
1073
1068
|
}
|
|
1074
1069
|
|
|
1075
1070
|
if (s.originalBasePath && s.cmdCtx) {
|
|
@@ -1384,20 +1379,14 @@ export async function stopAuto(
|
|
|
1384
1379
|
}
|
|
1385
1380
|
|
|
1386
1381
|
// ── Step 7: Restore basePath and chdir (ADR-016 phase 3, #5693) ──
|
|
1387
|
-
// `restoreToProjectRoot`
|
|
1388
|
-
// no
|
|
1382
|
+
// `restoreToProjectRoot` owns both s.basePath restore and process.chdir;
|
|
1383
|
+
// no paired chdir is needed at the call site.
|
|
1389
1384
|
if (s.originalBasePath) {
|
|
1390
1385
|
try {
|
|
1391
1386
|
buildLifecycle().restoreToProjectRoot();
|
|
1392
1387
|
} catch (e) {
|
|
1393
1388
|
debugLog("stop-cleanup-basepath", { error: e instanceof Error ? e.message : String(e) });
|
|
1394
1389
|
}
|
|
1395
|
-
try {
|
|
1396
|
-
process.chdir(s.basePath);
|
|
1397
|
-
} catch (err) {
|
|
1398
|
-
/* best-effort */
|
|
1399
|
-
logWarning("engine", `chdir failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1400
|
-
}
|
|
1401
1390
|
}
|
|
1402
1391
|
|
|
1403
1392
|
// Re-root the active command session/tool runtime after worktree teardown.
|
|
@@ -1792,6 +1781,75 @@ function buildLifecycle(): WorktreeLifecycle {
|
|
|
1792
1781
|
return new WorktreeLifecycle(s, buildWorktreeLifecycleDeps());
|
|
1793
1782
|
}
|
|
1794
1783
|
|
|
1784
|
+
/**
|
|
1785
|
+
* Build the production `DispatchAdapter` used by `createWiredAutoOrchestrationModule`.
|
|
1786
|
+
*
|
|
1787
|
+
* Exported so tests can verify parity with `runDispatch`'s `resolveDispatch` call —
|
|
1788
|
+
* the wired adapter must derive `structuredQuestionsAvailable`, `sessionContextWindow`,
|
|
1789
|
+
* `sessionProvider`, and `modelRegistry` the same way phases.ts:runDispatch does.
|
|
1790
|
+
*/
|
|
1791
|
+
export function createWiredDispatchAdapter(
|
|
1792
|
+
ctx: ExtensionContext,
|
|
1793
|
+
pi: ExtensionAPI,
|
|
1794
|
+
dispatchBasePath: string,
|
|
1795
|
+
): DispatchAdapter {
|
|
1796
|
+
return {
|
|
1797
|
+
async decideNextUnit(input) {
|
|
1798
|
+
const state = input.stateSnapshot;
|
|
1799
|
+
const active = state.activeMilestone;
|
|
1800
|
+
if (!active) return null;
|
|
1801
|
+
|
|
1802
|
+
const prefs = loadEffectiveGSDPreferences(dispatchBasePath)?.preferences;
|
|
1803
|
+
|
|
1804
|
+
// Derive session-derived dispatch inputs the same way phases.ts:runDispatch does
|
|
1805
|
+
// (#5789). Prefer caller-supplied values when present so test harnesses and
|
|
1806
|
+
// alternative wirings can inject deterministic snapshots; otherwise pull from
|
|
1807
|
+
// the captured pi/ctx references.
|
|
1808
|
+
const sessionProvider = input.sessionProvider ?? ctx.model?.provider;
|
|
1809
|
+
const sessionContextWindow = input.sessionContextWindow ?? ctx.model?.contextWindow;
|
|
1810
|
+
const modelRegistry = input.modelRegistry ?? (ctx.modelRegistry as MinimalModelRegistry | undefined);
|
|
1811
|
+
const authMode =
|
|
1812
|
+
sessionProvider && typeof ctx.modelRegistry?.getProviderAuthMode === "function"
|
|
1813
|
+
? ctx.modelRegistry.getProviderAuthMode(sessionProvider)
|
|
1814
|
+
: undefined;
|
|
1815
|
+
const activeTools = typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [];
|
|
1816
|
+
// Mirrors runDispatch: deep-planning keeps approval gates in plain chat
|
|
1817
|
+
// because structured questions can be cancelled outside the chat turn on
|
|
1818
|
+
// some transports.
|
|
1819
|
+
const structuredQuestionsAvailable =
|
|
1820
|
+
input.structuredQuestionsAvailable ??
|
|
1821
|
+
(prefs?.planning_depth === "deep"
|
|
1822
|
+
? "false"
|
|
1823
|
+
: supportsStructuredQuestions(activeTools, {
|
|
1824
|
+
authMode,
|
|
1825
|
+
baseUrl: ctx.model?.baseUrl,
|
|
1826
|
+
})
|
|
1827
|
+
? "true"
|
|
1828
|
+
: "false");
|
|
1829
|
+
|
|
1830
|
+
const action = await resolveDispatch({
|
|
1831
|
+
basePath: dispatchBasePath,
|
|
1832
|
+
mid: active.id,
|
|
1833
|
+
midTitle: active.title,
|
|
1834
|
+
state,
|
|
1835
|
+
prefs,
|
|
1836
|
+
structuredQuestionsAvailable,
|
|
1837
|
+
sessionContextWindow,
|
|
1838
|
+
sessionProvider,
|
|
1839
|
+
modelRegistry,
|
|
1840
|
+
});
|
|
1841
|
+
|
|
1842
|
+
if (action.action !== "dispatch") return null;
|
|
1843
|
+
return {
|
|
1844
|
+
unitType: action.unitType,
|
|
1845
|
+
unitId: action.unitId,
|
|
1846
|
+
reason: action.matchedRule ?? "dispatch",
|
|
1847
|
+
preconditions: [],
|
|
1848
|
+
};
|
|
1849
|
+
},
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1795
1853
|
/**
|
|
1796
1854
|
* Thin entry glue for the new Auto Orchestration module.
|
|
1797
1855
|
*
|
|
@@ -1801,7 +1859,7 @@ function buildLifecycle(): WorktreeLifecycle {
|
|
|
1801
1859
|
*/
|
|
1802
1860
|
export function createWiredAutoOrchestrationModule(
|
|
1803
1861
|
ctx: ExtensionContext,
|
|
1804
|
-
|
|
1862
|
+
pi: ExtensionAPI,
|
|
1805
1863
|
dispatchBasePath: string,
|
|
1806
1864
|
runtimeBasePath = resolveProjectRoot(dispatchBasePath),
|
|
1807
1865
|
): AutoOrchestrationModule {
|
|
@@ -1830,30 +1888,7 @@ export function createWiredAutoOrchestrationModule(
|
|
|
1830
1888
|
};
|
|
1831
1889
|
},
|
|
1832
1890
|
},
|
|
1833
|
-
dispatch:
|
|
1834
|
-
async decideNextUnit(input) {
|
|
1835
|
-
const state = input.stateSnapshot;
|
|
1836
|
-
const active = state.activeMilestone;
|
|
1837
|
-
if (!active) return null;
|
|
1838
|
-
|
|
1839
|
-
const prefs = loadEffectiveGSDPreferences(dispatchBasePath)?.preferences;
|
|
1840
|
-
const action = await resolveDispatch({
|
|
1841
|
-
basePath: dispatchBasePath,
|
|
1842
|
-
mid: active.id,
|
|
1843
|
-
midTitle: active.title,
|
|
1844
|
-
state,
|
|
1845
|
-
prefs,
|
|
1846
|
-
});
|
|
1847
|
-
|
|
1848
|
-
if (action.action !== "dispatch") return null;
|
|
1849
|
-
return {
|
|
1850
|
-
unitType: action.unitType,
|
|
1851
|
-
unitId: action.unitId,
|
|
1852
|
-
reason: action.matchedRule ?? "dispatch",
|
|
1853
|
-
preconditions: [],
|
|
1854
|
-
};
|
|
1855
|
-
},
|
|
1856
|
-
},
|
|
1891
|
+
dispatch: createWiredDispatchAdapter(ctx, pi, dispatchBasePath),
|
|
1857
1892
|
recovery: {
|
|
1858
1893
|
async classifyAndRecover(input) {
|
|
1859
1894
|
const recovery = classifyFailure(input);
|
|
@@ -1902,12 +1937,25 @@ export function createWiredAutoOrchestrationModule(
|
|
|
1902
1937
|
async cleanupOnStop() {},
|
|
1903
1938
|
},
|
|
1904
1939
|
health: {
|
|
1940
|
+
checkResourcesStale() {
|
|
1941
|
+
return checkResourcesStale(s.resourceVersionOnStart);
|
|
1942
|
+
},
|
|
1905
1943
|
async preAdvanceGate() {
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1944
|
+
try {
|
|
1945
|
+
const gate = await preDispatchHealthGate(dispatchBasePath);
|
|
1946
|
+
if (gate.proceed) {
|
|
1947
|
+
return {
|
|
1948
|
+
kind: "pass",
|
|
1949
|
+
fixesApplied: gate.fixesApplied,
|
|
1950
|
+
};
|
|
1951
|
+
}
|
|
1952
|
+
return {
|
|
1953
|
+
kind: "fail",
|
|
1954
|
+
reason: gate.reason ?? "Pre-dispatch health check failed — run /gsd doctor for details.",
|
|
1955
|
+
};
|
|
1956
|
+
} catch (error) {
|
|
1957
|
+
return { kind: "threw", error };
|
|
1958
|
+
}
|
|
1911
1959
|
},
|
|
1912
1960
|
async postAdvanceRecord(result) {
|
|
1913
1961
|
if (result.kind === "error") {
|
|
@@ -1975,6 +2023,43 @@ export function createWiredAutoOrchestrationModule(
|
|
|
1975
2023
|
}
|
|
1976
2024
|
},
|
|
1977
2025
|
},
|
|
2026
|
+
uokGate: {
|
|
2027
|
+
async emit(input) {
|
|
2028
|
+
const prefs = loadEffectiveGSDPreferences(dispatchBasePath)?.preferences;
|
|
2029
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
2030
|
+
if (!uokFlags.gates) return;
|
|
2031
|
+
const milestoneId = input.milestoneId ?? s.currentMilestoneId ?? undefined;
|
|
2032
|
+
try {
|
|
2033
|
+
const { UokGateRunner } = await import("./uok/gate-runner.js");
|
|
2034
|
+
const runner = new UokGateRunner();
|
|
2035
|
+
runner.register({
|
|
2036
|
+
id: input.gateId,
|
|
2037
|
+
type: input.gateType,
|
|
2038
|
+
execute: async () => ({
|
|
2039
|
+
outcome: input.outcome,
|
|
2040
|
+
failureClass: input.failureClass,
|
|
2041
|
+
rationale: input.rationale,
|
|
2042
|
+
findings: input.findings ?? "",
|
|
2043
|
+
}),
|
|
2044
|
+
});
|
|
2045
|
+
await runner.run(input.gateId, {
|
|
2046
|
+
basePath: dispatchBasePath,
|
|
2047
|
+
traceId: `pre-dispatch:${flowId}`,
|
|
2048
|
+
turnId: `orch-${seq}`,
|
|
2049
|
+
milestoneId,
|
|
2050
|
+
unitType: "pre-dispatch",
|
|
2051
|
+
unitId: `orch-${seq}`,
|
|
2052
|
+
});
|
|
2053
|
+
} catch (err) {
|
|
2054
|
+
logWarning("engine", `uok gate emit failed: ${getErrorMessage(err)}`, {
|
|
2055
|
+
file: "auto.ts",
|
|
2056
|
+
gateId: input.gateId,
|
|
2057
|
+
gateType: input.gateType,
|
|
2058
|
+
...(milestoneId ? { milestoneId } : {}),
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
},
|
|
2062
|
+
},
|
|
1978
2063
|
};
|
|
1979
2064
|
|
|
1980
2065
|
return createAutoOrchestrator(deps);
|
|
@@ -423,6 +423,10 @@ export function registerHooks(
|
|
|
423
423
|
pi: ExtensionAPI,
|
|
424
424
|
ecosystemHandlers: GSDEcosystemBeforeAgentStartHandler[],
|
|
425
425
|
): void {
|
|
426
|
+
// ADR-005 Phase 3b: surface pi-ai ProviderSwitchReport via audit, notification, and counter.
|
|
427
|
+
// Idempotent — only the first registerHooks call installs.
|
|
428
|
+
void import("../provider-switch-observer.js").then((m) => m.installProviderSwitchObserver());
|
|
429
|
+
|
|
426
430
|
pi.on("session_start", async (_event, ctx) => {
|
|
427
431
|
const basePath = contextBasePath(ctx);
|
|
428
432
|
initSessionNotifications(ctx);
|
|
@@ -480,6 +484,8 @@ export function registerHooks(
|
|
|
480
484
|
}
|
|
481
485
|
await loadToolApiKeysForSession();
|
|
482
486
|
if (!isAutoActive()) {
|
|
487
|
+
ctx.ui.setWidget("gsd-progress", undefined);
|
|
488
|
+
ctx.ui.setWidget("gsd-outcome", undefined);
|
|
483
489
|
const { initHealthWidget } = await import("../health-widget.js");
|
|
484
490
|
initHealthWidget(ctx);
|
|
485
491
|
} else {
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
export function extractSubagentAgentClasses(input: unknown): string[] {
|
|
2
2
|
if (!input || typeof input !== "object") return [];
|
|
3
3
|
|
|
4
|
-
const record = input as Record<string, unknown>;
|
|
5
4
|
const agentClasses: string[] = [];
|
|
5
|
+
const visited = new WeakSet<object>();
|
|
6
6
|
const addAgentClass = (value: unknown): void => {
|
|
7
7
|
if (typeof value === "string" && value.trim().length > 0) agentClasses.push(value.trim());
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
const visitItems = (value: unknown): void => {
|
|
10
11
|
if (!Array.isArray(value)) return;
|
|
11
12
|
for (const item of value) {
|
|
12
|
-
|
|
13
|
+
visit(item);
|
|
13
14
|
}
|
|
14
15
|
};
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const visit = (value: unknown): void => {
|
|
18
|
+
if (!value || typeof value !== "object") return;
|
|
19
|
+
if (visited.has(value)) return;
|
|
20
|
+
visited.add(value);
|
|
21
|
+
const record = value as Record<string, unknown>;
|
|
22
|
+
addAgentClass(record.agent);
|
|
23
|
+
visitItems(record.tasks);
|
|
24
|
+
visitItems(record.chain);
|
|
25
|
+
visitItems(record.parallel);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
visit(input);
|
|
19
29
|
return agentClasses;
|
|
20
30
|
}
|
|
@@ -13,6 +13,7 @@ import { resolveAllSkillReferences, renderPreferencesForSystemPrompt, loadEffect
|
|
|
13
13
|
import { resolveModelWithFallbacksForUnit } from "../preferences-models.js";
|
|
14
14
|
import { resolveSkillReference } from "../preferences-skills.js";
|
|
15
15
|
import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
|
|
16
|
+
import { extractIntroAndRules } from "../knowledge-parser.js";
|
|
16
17
|
import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
|
|
17
18
|
import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
|
|
18
19
|
import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
|
|
@@ -131,9 +132,14 @@ export async function buildBeforeAgentStartResult(
|
|
|
131
132
|
logWarning("bootstrap", `cmux prompt setup skipped: ${(e as Error).message}`);
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
const ctxProjectRoot = (ctx as { projectRoot?: unknown }).projectRoot;
|
|
136
|
+
const basePath = typeof ctxProjectRoot === "string" && ctxProjectRoot.length > 0
|
|
137
|
+
? ctxProjectRoot
|
|
138
|
+
: process.cwd();
|
|
139
|
+
|
|
134
140
|
let preferenceBlock = "";
|
|
135
141
|
if (loadedPreferences) {
|
|
136
|
-
const cwd =
|
|
142
|
+
const cwd = basePath;
|
|
137
143
|
const report = resolveAllSkillReferences(loadedPreferences.preferences, cwd);
|
|
138
144
|
preferenceBlock = `\n\n${renderPreferencesForSystemPrompt(loadedPreferences.preferences, report.resolutions)}`;
|
|
139
145
|
if (report.warnings.length > 0) {
|
|
@@ -144,14 +150,6 @@ export async function buildBeforeAgentStartResult(
|
|
|
144
150
|
}
|
|
145
151
|
}
|
|
146
152
|
|
|
147
|
-
const { block: knowledgeBlock, globalSizeKb } = loadKnowledgeBlock(gsdHome(), process.cwd());
|
|
148
|
-
if (globalSizeKb > 4) {
|
|
149
|
-
ctx.ui.notify(
|
|
150
|
-
`GSD: ~/.gsd/agent/KNOWLEDGE.md is ${globalSizeKb.toFixed(1)}KB — consider trimming to keep system prompt lean.`,
|
|
151
|
-
"warning",
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
153
|
// ADR-013 step 5: opportunistic decisions->memories backfill. Idempotent
|
|
156
154
|
// and best-effort — first run absorbs the existing decisions table into
|
|
157
155
|
// the memory store; subsequent runs are a single sentinel SELECT.
|
|
@@ -159,12 +157,50 @@ export async function buildBeforeAgentStartResult(
|
|
|
159
157
|
const { backfillDecisionsToMemories } = await import("../memory-backfill.js");
|
|
160
158
|
const written = backfillDecisionsToMemories();
|
|
161
159
|
if (written > 0) {
|
|
162
|
-
ctx.ui.notify(`GSD: backfilled ${written} decision${written === 1 ? "" : "s"} into the memory store
|
|
160
|
+
ctx.ui.notify(`GSD: backfilled ${written} decision${written === 1 ? "" : "s"} into the memory store.`, "info");
|
|
163
161
|
}
|
|
164
162
|
} catch (e) {
|
|
165
163
|
logWarning("bootstrap", `decisions backfill failed: ${(e as Error).message}`);
|
|
166
164
|
}
|
|
167
165
|
|
|
166
|
+
// ADR-013 Stage 2b: KNOWLEDGE.md Patterns + Lessons backfill, then
|
|
167
|
+
// re-render the hybrid projection (manual Rules + projected Patterns +
|
|
168
|
+
// projected Lessons). Both are idempotent and best-effort — failures here
|
|
169
|
+
// can't block agent startup.
|
|
170
|
+
try {
|
|
171
|
+
const { backfillKnowledgeToMemories } = await import("../knowledge-backfill.js");
|
|
172
|
+
const writtenK = backfillKnowledgeToMemories(basePath);
|
|
173
|
+
if (writtenK > 0) {
|
|
174
|
+
ctx.ui.notify(`GSD: backfilled ${writtenK} KNOWLEDGE.md row${writtenK === 1 ? "" : "s"} into the memory store.`, "info");
|
|
175
|
+
}
|
|
176
|
+
} catch (e) {
|
|
177
|
+
logWarning("bootstrap", `KNOWLEDGE.md backfill failed: ${(e as Error).message}`);
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const { renderKnowledgeProjection } = await import("../knowledge-projection.js");
|
|
181
|
+
renderKnowledgeProjection(basePath);
|
|
182
|
+
} catch (e) {
|
|
183
|
+
logWarning("bootstrap", `KNOWLEDGE.md projection render failed: ${(e as Error).message}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ADR-013 step 6 preflight: warn when decisions / KNOWLEDGE.md rows are not
|
|
187
|
+
// yet in the memories table. Read-only; never throws. Runs after the two
|
|
188
|
+
// backfills above so the gap report reflects post-backfill state.
|
|
189
|
+
try {
|
|
190
|
+
const { reportConsolidationGaps } = await import("../memory-consolidation-scanner.js");
|
|
191
|
+
reportConsolidationGaps(basePath);
|
|
192
|
+
} catch (e) {
|
|
193
|
+
logWarning("bootstrap", `memory consolidation scan failed: ${(e as Error).message}`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const { block: knowledgeBlock, globalSizeKb } = loadKnowledgeBlock(gsdHome(), basePath);
|
|
197
|
+
if (globalSizeKb > 4) {
|
|
198
|
+
ctx.ui.notify(
|
|
199
|
+
`GSD: ~/.gsd/agent/KNOWLEDGE.md is ${globalSizeKb.toFixed(1)}KB — consider trimming to keep system prompt lean.`,
|
|
200
|
+
"warning",
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
168
204
|
let newSkillsBlock = "";
|
|
169
205
|
if (hasSkillSnapshot()) {
|
|
170
206
|
const newSkills = detectNewSkills();
|
|
@@ -370,7 +406,9 @@ export async function loadMemoryBlock(
|
|
|
370
406
|
}
|
|
371
407
|
|
|
372
408
|
export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: string; globalSizeKb: number } {
|
|
373
|
-
// 1. Global knowledge (~/.gsd/agent/KNOWLEDGE.md) — cross-project,
|
|
409
|
+
// 1. Global knowledge (~/.gsd/agent/KNOWLEDGE.md) — cross-project,
|
|
410
|
+
// user-maintained. NOT migrated to memories (which are project-scoped),
|
|
411
|
+
// so the full file is injected unchanged.
|
|
374
412
|
let globalKnowledge = "";
|
|
375
413
|
let globalSizeKb = 0;
|
|
376
414
|
const globalKnowledgePath = join(gsdHomeDir, "agent", "KNOWLEDGE.md");
|
|
@@ -386,13 +424,18 @@ export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: st
|
|
|
386
424
|
}
|
|
387
425
|
}
|
|
388
426
|
|
|
389
|
-
// 2. Project knowledge (.gsd/KNOWLEDGE.md) — project-specific
|
|
427
|
+
// 2. Project knowledge (.gsd/KNOWLEDGE.md) — project-specific.
|
|
428
|
+
// ADR-013 Stage 2b: Patterns and Lessons are projected from the
|
|
429
|
+
// memories table and already reach the LLM via loadMemoryBlock. Inject
|
|
430
|
+
// only the intro prose + `## Rules` section here to avoid duplicating
|
|
431
|
+
// Patterns/Lessons content in the prompt. Rules stay manual per
|
|
432
|
+
// ADR-013 line 39 and have no memory equivalent.
|
|
390
433
|
let projectKnowledge = "";
|
|
391
434
|
const knowledgePath = resolveGsdRootFile(cwd, "KNOWLEDGE");
|
|
392
435
|
if (existsSync(knowledgePath)) {
|
|
393
436
|
try {
|
|
394
|
-
const
|
|
395
|
-
if (
|
|
437
|
+
const raw = readFileSync(knowledgePath, "utf-8").trim();
|
|
438
|
+
if (raw) projectKnowledge = extractIntroAndRules(raw).trim();
|
|
396
439
|
} catch (e) {
|
|
397
440
|
logWarning("bootstrap", `project knowledge file read failed: ${(e as Error).message}`);
|
|
398
441
|
}
|
|
@@ -411,7 +454,7 @@ export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: st
|
|
|
411
454
|
}
|
|
412
455
|
const body = limitKnowledgeBlock(parts.join("\n\n"), getKnowledgeCharLimit());
|
|
413
456
|
return {
|
|
414
|
-
block: `\n\n[KNOWLEDGE — Rules
|
|
457
|
+
block: `\n\n[KNOWLEDGE — Rules from KNOWLEDGE.md (Patterns and Lessons reach the LLM via the memory block)]\n\n${body}`,
|
|
415
458
|
globalSizeKb,
|
|
416
459
|
};
|
|
417
460
|
}
|
|
@@ -5,7 +5,7 @@ import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
|
5
5
|
import { minimatch } from "minimatch";
|
|
6
6
|
|
|
7
7
|
import { getIsolationMode } from "../preferences.js";
|
|
8
|
-
import type
|
|
8
|
+
import { compileSubagentPermissionContract, type ToolsPolicy } from "../unit-context-manifest.js";
|
|
9
9
|
import { logWarning } from "../workflow-logger.js";
|
|
10
10
|
import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
11
11
|
|
|
@@ -811,7 +811,8 @@ export function shouldBlockPlanningUnit(
|
|
|
811
811
|
if (PLANNING_SUBAGENT_TOOLS.has(tool)) {
|
|
812
812
|
if (policy.mode === "planning-dispatch") {
|
|
813
813
|
const requested = (agentClasses ?? []).map(a => a.trim()).filter(Boolean);
|
|
814
|
-
const
|
|
814
|
+
const dispatchContract = compileSubagentPermissionContract(policy);
|
|
815
|
+
const allowedSubagents = dispatchContract.allowedSubagents;
|
|
815
816
|
const allowed = new Set(allowedSubagents);
|
|
816
817
|
// When agentClasses is undefined, the caller has not been updated to extract
|
|
817
818
|
// agent identities yet. Block and warn so stale callers surface in telemetry
|