@opengsd/gsd-pi 1.9.0 → 1.10.0-dev.a5e42e99
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 +10 -9
- package/dist/headless.js +2 -1
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
- package/dist/resources/extensions/gsd/auto/loop.js +24 -4
- package/dist/resources/extensions/gsd/auto/run-unit.js +19 -1
- package/dist/resources/extensions/gsd/auto/unit-phase.js +37 -5
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -8
- package/dist/resources/extensions/gsd/auto-dispatch.js +2 -0
- package/dist/resources/extensions/gsd/auto-model-selection.js +1 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +102 -21
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -5
- package/dist/resources/extensions/gsd/auto-start.js +30 -10
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +40 -0
- package/dist/resources/extensions/gsd/auto-verification.js +25 -12
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +7 -3
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +15 -5
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -7
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +7 -26
- package/dist/resources/extensions/gsd/commands-verdict.js +10 -9
- package/dist/resources/extensions/gsd/compat/compat-marker.js +80 -5
- package/dist/resources/extensions/gsd/constants.js +12 -13
- package/dist/resources/extensions/gsd/context-masker.js +97 -21
- package/dist/resources/extensions/gsd/db/engine.js +5 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +33 -2
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +40 -12
- package/dist/resources/extensions/gsd/error-classifier.js +12 -2
- package/dist/resources/extensions/gsd/exec-sandbox.js +1 -0
- package/dist/resources/extensions/gsd/flat-phase-migration.js +12 -0
- package/dist/resources/extensions/gsd/git-service.js +19 -7
- package/dist/resources/extensions/gsd/gsd-db.js +75 -31
- package/dist/resources/extensions/gsd/guided-flow.js +11 -5
- package/dist/resources/extensions/gsd/markdown-renderer.js +5 -21
- package/dist/resources/extensions/gsd/md-importer.js +5 -6
- package/dist/resources/extensions/gsd/model-cost-table.js +6 -1
- package/dist/resources/extensions/gsd/model-router.js +16 -0
- package/dist/resources/extensions/gsd/paths.js +66 -15
- package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
- package/dist/resources/extensions/gsd/planning-subagent-registry.js +33 -0
- package/dist/resources/extensions/gsd/preferences-models.js +50 -10
- package/dist/resources/extensions/gsd/preferences-types.js +6 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +86 -4
- package/dist/resources/extensions/gsd/preferences.js +24 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
- package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
- package/dist/resources/extensions/gsd/skill-activation.js +17 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +98 -2
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +4 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +5 -2
- package/dist/resources/extensions/gsd/stop-notice.js +9 -0
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +8 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +12 -5
- package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -1
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
- package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
- package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
- package/dist/resources/extensions/gsd/verification-evidence.js +5 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
- package/dist/resources/extensions/gsd/workspace.js +2 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +20 -18
- package/dist/resources/extensions/ollama/ollama-chat-provider.js +2 -2
- package/dist/resources/extensions/shared/interview-ui.js +43 -6
- package/dist/resources/extensions/subagent/index.js +1 -1
- package/dist/startup-model-validation.d.ts +1 -1
- 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 +9 -9
- 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/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/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 +4 -4
- 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 +9 -9
- package/dist/web/standalone/.next/server/chunks/1991.js +2 -2
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- 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-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- 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/server.js +1 -1
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +8 -6
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -1
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/rpc.test.js +1 -1
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +1 -0
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/cli/args.js +2 -2
- package/packages/gsd-agent-modes/dist/cli/args.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/README.md +21 -5
- package/packages/gsd-cloud/dist/background-cli.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/background-cli.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/background-cli.test.js +325 -0
- package/packages/gsd-cloud/dist/background-cli.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cli.d.ts.map +1 -1
- package/packages/gsd-cloud/dist/cli.js +146 -16
- package/packages/gsd-cloud/dist/cli.js.map +1 -1
- package/packages/gsd-cloud/dist/cloud-config.d.ts +1 -1
- package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -1
- package/packages/gsd-cloud/dist/cloud-config.js +7 -1
- package/packages/gsd-cloud/dist/cloud-config.js.map +1 -1
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts +7 -4
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -1
- package/packages/gsd-cloud/dist/cloud-runtime.js +115 -31
- package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -1
- package/packages/gsd-cloud/dist/cloud-runtime.test.js +224 -59
- package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -1
- package/packages/gsd-cloud/dist/runtime-artifacts.d.ts +3 -0
- package/packages/gsd-cloud/dist/runtime-artifacts.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-artifacts.js +36 -0
- package/packages/gsd-cloud/dist/runtime-artifacts.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.d.ts +32 -0
- package/packages/gsd-cloud/dist/runtime-process.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.js +640 -0
- package/packages/gsd-cloud/dist/runtime-process.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/runtime-process.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.test.js +543 -0
- package/packages/gsd-cloud/dist/runtime-process.test.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.d.ts +117 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.js +291 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.test.js +434 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.test.js.map +1 -0
- package/packages/gsd-cloud/package.json +2 -2
- package/packages/mcp-server/README.md +7 -2
- package/packages/mcp-server/dist/cli-runner.d.ts +3 -0
- package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
- package/packages/mcp-server/dist/cli-runner.js +119 -33
- package/packages/mcp-server/dist/cli-runner.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +5 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +2 -2
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +187 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +145 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.js +18 -6
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +3 -2
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +6 -1
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-vertex.js.map +1 -1
- package/packages/pi-ai/dist/providers/google.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +103 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +9 -1
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +14 -4
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +54 -0
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +1 -0
- package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme.d.ts +1 -1
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +1 -0
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +2 -2
- package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
- package/src/resources/extensions/gsd/auto/loop.ts +48 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +20 -1
- package/src/resources/extensions/gsd/auto/unit-phase.ts +41 -5
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-model-selection.ts +1 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -19
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-runtime-state.ts +12 -7
- package/src/resources/extensions/gsd/auto-start.ts +32 -9
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +56 -0
- package/src/resources/extensions/gsd/auto-verification.ts +46 -12
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +10 -3
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +20 -7
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +1 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -12
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +10 -31
- package/src/resources/extensions/gsd/commands-verdict.ts +16 -9
- package/src/resources/extensions/gsd/compat/compat-marker.ts +99 -5
- package/src/resources/extensions/gsd/constants.ts +14 -13
- package/src/resources/extensions/gsd/context-masker.ts +98 -2
- package/src/resources/extensions/gsd/db/engine.ts +5 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +33 -2
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +45 -11
- package/src/resources/extensions/gsd/error-classifier.ts +13 -2
- package/src/resources/extensions/gsd/exec-sandbox.ts +1 -0
- package/src/resources/extensions/gsd/flat-phase-migration.ts +14 -0
- package/src/resources/extensions/gsd/git-service.ts +19 -6
- package/src/resources/extensions/gsd/gsd-db.ts +85 -33
- package/src/resources/extensions/gsd/guided-flow.ts +11 -4
- package/src/resources/extensions/gsd/markdown-renderer.ts +5 -23
- package/src/resources/extensions/gsd/md-importer.ts +5 -5
- package/src/resources/extensions/gsd/model-cost-table.ts +14 -1
- package/src/resources/extensions/gsd/model-router.ts +17 -0
- package/src/resources/extensions/gsd/paths.ts +73 -15
- package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
- package/src/resources/extensions/gsd/planning-subagent-registry.ts +45 -0
- package/src/resources/extensions/gsd/preferences-models.ts +54 -10
- package/src/resources/extensions/gsd/preferences-types.ts +26 -2
- package/src/resources/extensions/gsd/preferences-validation.ts +108 -3
- package/src/resources/extensions/gsd/preferences.ts +38 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
- package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
- package/src/resources/extensions/gsd/skill-activation.ts +17 -3
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +132 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +4 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +4 -2
- package/src/resources/extensions/gsd/stop-notice.ts +11 -0
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +8 -0
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +74 -1
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +76 -1
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
- package/src/resources/extensions/gsd/tests/db-engine-cjs-compat.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/external-markdown-edit.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +8 -9
- package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
- package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +151 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/workflow-authority-faults.test.ts +238 -0
- package/src/resources/extensions/gsd/tests/workflow-authority-fixture.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-authority-fixture.ts +141 -0
- package/src/resources/extensions/gsd/tests/workflow-authority-projection-conflict.test.ts +177 -0
- package/src/resources/extensions/gsd/tests/workflow-fault-harness.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/workflow-fault-harness.ts +72 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +74 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +20 -5
- package/src/resources/extensions/gsd/tools/plan-slice.ts +5 -1
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
- package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
- package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
- package/src/resources/extensions/gsd/verification-evidence.ts +5 -2
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
- package/src/resources/extensions/gsd/workspace.ts +2 -1
- package/src/resources/extensions/gsd/worktree-state-projection.ts +21 -24
- package/src/resources/extensions/ollama/ollama-chat-provider.ts +2 -2
- package/src/resources/extensions/ollama/tests/ollama-chat-provider-think.test.ts +4 -0
- package/src/resources/extensions/shared/interview-ui.ts +47 -8
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +29 -0
- package/src/resources/extensions/subagent/index.ts +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- /package/dist/web/standalone/.next/static/{BE5XoklToI6lZjRzpXih8 → xwUaOqui04jIIFVsIBLiL}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{BE5XoklToI6lZjRzpXih8 → xwUaOqui04jIIFVsIBLiL}/_ssgManifest.js +0 -0
|
@@ -67,6 +67,13 @@ export type { SliceRow, TaskRow } from "./db-task-slice-rows.js";
|
|
|
67
67
|
|
|
68
68
|
import { TERMINAL_STATUS_SQL } from "./db/sql-constants.js";
|
|
69
69
|
import { applyStatusTransition } from "./db/writers/status.js";
|
|
70
|
+
import {
|
|
71
|
+
LAYOUT_SEGMENTS,
|
|
72
|
+
derivePhaseSlug,
|
|
73
|
+
milestoneIdToPhaseNum,
|
|
74
|
+
milestoneIdUniqueSuffix,
|
|
75
|
+
phaseDirName,
|
|
76
|
+
} from "./layout-policy.js";
|
|
70
77
|
|
|
71
78
|
export function insertDecision(d: Omit<Decision, "seq">): void {
|
|
72
79
|
if (!getDbOrNull()!) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
@@ -206,6 +213,47 @@ export function insertArtifact(a: {
|
|
|
206
213
|
});
|
|
207
214
|
}
|
|
208
215
|
|
|
216
|
+
function canonicalPhaseDirNameForDb(milestoneId: string, title: string): string {
|
|
217
|
+
const phaseNum = milestoneIdToPhaseNum(milestoneId);
|
|
218
|
+
const slug = derivePhaseSlug(title || milestoneId);
|
|
219
|
+
const suffix = milestoneIdUniqueSuffix(milestoneId);
|
|
220
|
+
return phaseDirName(phaseNum, suffix ? `${suffix}-${slug}` : slug);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function reconcileMilestonePhaseArtifactPaths(milestoneId: string, title: string): void {
|
|
224
|
+
const db = getDbOrNull()!;
|
|
225
|
+
const phaseNumPrefix = String(milestoneIdToPhaseNum(milestoneId)).padStart(2, "0");
|
|
226
|
+
const canonicalDir = canonicalPhaseDirNameForDb(milestoneId, title);
|
|
227
|
+
const staleRows = db.prepare(
|
|
228
|
+
`SELECT path
|
|
229
|
+
FROM artifacts
|
|
230
|
+
WHERE milestone_id = :milestone_id
|
|
231
|
+
AND path LIKE :phase_prefix`,
|
|
232
|
+
).all({
|
|
233
|
+
":milestone_id": milestoneId,
|
|
234
|
+
":phase_prefix": `${LAYOUT_SEGMENTS.level1}/${phaseNumPrefix}-%/%`,
|
|
235
|
+
}) as Array<{ path: string }>;
|
|
236
|
+
|
|
237
|
+
const updatePath = db.prepare("UPDATE artifacts SET path = :new_path WHERE path = :old_path");
|
|
238
|
+
const deletePath = db.prepare("DELETE FROM artifacts WHERE path = :path");
|
|
239
|
+
const existingPath = db.prepare("SELECT 1 AS present FROM artifacts WHERE path = :path");
|
|
240
|
+
|
|
241
|
+
for (const row of staleRows) {
|
|
242
|
+
const parts = row.path.split("/");
|
|
243
|
+
if (parts.length < 3) continue;
|
|
244
|
+
if (parts[0] !== LAYOUT_SEGMENTS.level1) continue;
|
|
245
|
+
if (parts[1] === canonicalDir) continue;
|
|
246
|
+
if (!parts[1]?.startsWith(`${phaseNumPrefix}-`)) continue;
|
|
247
|
+
|
|
248
|
+
const newPath = [LAYOUT_SEGMENTS.level1, canonicalDir, ...parts.slice(2)].join("/");
|
|
249
|
+
if (existingPath.get({ ":path": newPath })) {
|
|
250
|
+
deletePath.run({ ":path": row.path });
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
updatePath.run({ ":new_path": newPath, ":old_path": row.path });
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
209
257
|
export interface MilestonePlanningRecord {
|
|
210
258
|
vision: string;
|
|
211
259
|
successCriteria: string[];
|
|
@@ -287,39 +335,43 @@ export function insertMilestone(m: {
|
|
|
287
335
|
|
|
288
336
|
export function upsertMilestonePlanning(milestoneId: string, planning: Partial<MilestonePlanningRecord> & { title?: string; status?: string; depends_on?: string[] }): void {
|
|
289
337
|
if (!getDbOrNull()!) throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
338
|
+
transaction(() => {
|
|
339
|
+
getDbOrNull()!.prepare(
|
|
340
|
+
`UPDATE milestones SET
|
|
341
|
+
title = COALESCE(NULLIF(:title, ''), title),
|
|
342
|
+
status = COALESCE(NULLIF(:status, ''), status),
|
|
343
|
+
depends_on = COALESCE(:depends_on, depends_on),
|
|
344
|
+
vision = COALESCE(:vision, vision),
|
|
345
|
+
success_criteria = COALESCE(:success_criteria, success_criteria),
|
|
346
|
+
key_risks = COALESCE(:key_risks, key_risks),
|
|
347
|
+
proof_strategy = COALESCE(:proof_strategy, proof_strategy),
|
|
348
|
+
verification_contract = COALESCE(:verification_contract, verification_contract),
|
|
349
|
+
verification_integration = COALESCE(:verification_integration, verification_integration),
|
|
350
|
+
verification_operational = COALESCE(:verification_operational, verification_operational),
|
|
351
|
+
verification_uat = COALESCE(:verification_uat, verification_uat),
|
|
352
|
+
definition_of_done = COALESCE(:definition_of_done, definition_of_done),
|
|
353
|
+
requirement_coverage = COALESCE(:requirement_coverage, requirement_coverage),
|
|
354
|
+
boundary_map_markdown = COALESCE(:boundary_map_markdown, boundary_map_markdown)
|
|
355
|
+
WHERE id = :id`,
|
|
356
|
+
).run({
|
|
357
|
+
":id": milestoneId,
|
|
358
|
+
":title": planning.title ?? "",
|
|
359
|
+
":status": planning.status ?? "",
|
|
360
|
+
":depends_on": planning.depends_on ? JSON.stringify(planning.depends_on) : null,
|
|
361
|
+
":vision": planning.vision ?? null,
|
|
362
|
+
":success_criteria": planning.successCriteria ? JSON.stringify(planning.successCriteria) : null,
|
|
363
|
+
":key_risks": planning.keyRisks ? JSON.stringify(planning.keyRisks) : null,
|
|
364
|
+
":proof_strategy": planning.proofStrategy ? JSON.stringify(planning.proofStrategy) : null,
|
|
365
|
+
":verification_contract": planning.verificationContract ?? null,
|
|
366
|
+
":verification_integration": planning.verificationIntegration ?? null,
|
|
367
|
+
":verification_operational": planning.verificationOperational ?? null,
|
|
368
|
+
":verification_uat": planning.verificationUat ?? null,
|
|
369
|
+
":definition_of_done": planning.definitionOfDone ? JSON.stringify(planning.definitionOfDone) : null,
|
|
370
|
+
":requirement_coverage": planning.requirementCoverage ?? null,
|
|
371
|
+
":boundary_map_markdown": planning.boundaryMapMarkdown ?? null,
|
|
372
|
+
});
|
|
373
|
+
const finalTitle = planning.title?.trim();
|
|
374
|
+
if (finalTitle) reconcileMilestonePhaseArtifactPaths(milestoneId, finalTitle);
|
|
323
375
|
});
|
|
324
376
|
}
|
|
325
377
|
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
buildPlanMilestonePrompt,
|
|
27
27
|
buildPlanSlicePrompt,
|
|
28
28
|
buildSkillActivationBlock,
|
|
29
|
+
capPreamble,
|
|
29
30
|
} from "./auto-prompts.js";
|
|
30
31
|
import { deriveState, isGhostMilestone } from "./state.js";
|
|
31
32
|
import { invalidateAllCaches } from "./cache.js";
|
|
@@ -1199,7 +1200,9 @@ function resolveDiscussSliceBasePath(basePath: string, milestoneId: string): str
|
|
|
1199
1200
|
* slice summaries so the agent can ask grounded UX/behaviour questions
|
|
1200
1201
|
* without wasting a turn reading files.
|
|
1201
1202
|
*/
|
|
1202
|
-
|
|
1203
|
+
// Exported for tests (`prompt-budget-enforcement.test.ts`) — verifies the
|
|
1204
|
+
// inlined-context cap. Not part of the public flow surface otherwise.
|
|
1205
|
+
export async function buildDiscussSlicePrompt(
|
|
1203
1206
|
mid: string,
|
|
1204
1207
|
sid: string,
|
|
1205
1208
|
sTitle: string,
|
|
@@ -1262,8 +1265,12 @@ async function buildDiscussSlicePrompt(
|
|
|
1262
1265
|
}
|
|
1263
1266
|
}
|
|
1264
1267
|
|
|
1268
|
+
// Cap the inlined block: it grows unbounded with each completed slice's full
|
|
1269
|
+
// SUMMARY. `capPreamble` truncates at `### ` section boundaries — roadmap and
|
|
1270
|
+
// milestone context come first (survive), completed-slice summaries come last
|
|
1271
|
+
// (dropped first) when the executor's window can't hold everything.
|
|
1265
1272
|
const inlinedContext = inlined.length > 0
|
|
1266
|
-
? `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`
|
|
1273
|
+
? capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`)
|
|
1267
1274
|
: `## Inlined Context\n\n_(no context files found yet — go in blind and ask broad questions)_`;
|
|
1268
1275
|
|
|
1269
1276
|
const sliceDirPath = `.gsd/milestones/${mid}/slices/${sid}`;
|
|
@@ -1275,7 +1282,7 @@ async function buildDiscussSlicePrompt(
|
|
|
1275
1282
|
: "";
|
|
1276
1283
|
|
|
1277
1284
|
const inlinedTemplates = inlineTemplate("slice-context", "Slice Context");
|
|
1278
|
-
return loadPrompt("guided-discuss-slice", {
|
|
1285
|
+
return prependLanguageDirective(base, loadPrompt("guided-discuss-slice", {
|
|
1279
1286
|
milestoneId: mid,
|
|
1280
1287
|
sliceId: sid,
|
|
1281
1288
|
sliceTitle: sTitle,
|
|
@@ -1286,7 +1293,7 @@ async function buildDiscussSlicePrompt(
|
|
|
1286
1293
|
inlinedTemplates,
|
|
1287
1294
|
structuredQuestionsAvailable: options?.structuredQuestionsAvailable ?? "false",
|
|
1288
1295
|
commitInstruction: buildDocsCommitInstruction(`docs(${mid}/${sid}): slice context from discuss`),
|
|
1289
|
-
});
|
|
1296
|
+
}));
|
|
1290
1297
|
}
|
|
1291
1298
|
|
|
1292
1299
|
/**
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { readFileSync, existsSync, mkdirSync, statSync, unlinkSync } from "node:fs";
|
|
13
13
|
import { logWarning } from "./workflow-logger.js";
|
|
14
14
|
import { isClosedStatus } from "./status-guards.js";
|
|
15
|
-
import { dirname, join
|
|
15
|
+
import { dirname, join } from "node:path";
|
|
16
16
|
import {
|
|
17
17
|
getAllMilestones,
|
|
18
18
|
getMilestone,
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
resolveTasksDir,
|
|
41
41
|
targetMilestoneFile,
|
|
42
42
|
targetSliceFile,
|
|
43
|
+
targetTaskFile,
|
|
43
44
|
gsdProjectionRoot,
|
|
44
45
|
gsdRoot,
|
|
45
46
|
buildTaskFileName,
|
|
@@ -49,7 +50,7 @@ import { saveFile, clearParseCache, registerCacheClearCallback } from "./files.j
|
|
|
49
50
|
import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
|
|
50
51
|
import { invalidateStateCache } from "./state.js";
|
|
51
52
|
import { clearPathCache, milestonesDir, legacyMilestonesDir, isLegacyMilestonesLayout, resolveMilestonePath, relSliceFile, canonicalPhaseDirName } from "./paths.js";
|
|
52
|
-
import { readCompatMarker, writeCompatMarker, computeProjectionSha } from "./compat/compat-marker.js";
|
|
53
|
+
import { readCompatMarker, writeCompatMarker, computeProjectionSha, deriveCompatProjectionKey } from "./compat/compat-marker.js";
|
|
53
54
|
import type { RiskLevel } from "./types.js";
|
|
54
55
|
import {
|
|
55
56
|
phaseDirName,
|
|
@@ -108,13 +109,7 @@ function flushProjectionWritesToMarker(): void {
|
|
|
108
109
|
*/
|
|
109
110
|
function toArtifactPath(absPath: string, basePath: string): string {
|
|
110
111
|
const projectionRoot = gsdProjectionRoot(basePath);
|
|
111
|
-
|
|
112
|
-
const root = projectionRel && !projectionRel.startsWith("..") && !projectionRel.startsWith("/")
|
|
113
|
-
? projectionRoot
|
|
114
|
-
: gsdRoot(basePath);
|
|
115
|
-
const rel = relative(root, absPath);
|
|
116
|
-
// Normalize to forward slashes for consistent DB keys
|
|
117
|
-
return rel.replace(/\\/g, "/");
|
|
112
|
+
return deriveCompatProjectionKey(absPath, [projectionRoot, gsdRoot(basePath)]);
|
|
118
113
|
}
|
|
119
114
|
|
|
120
115
|
/**
|
|
@@ -756,20 +751,7 @@ export async function renderTaskSummary(
|
|
|
756
751
|
return false; // No summary to render — skip silently
|
|
757
752
|
}
|
|
758
753
|
|
|
759
|
-
|
|
760
|
-
const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
|
|
761
|
-
if (!slicePath) {
|
|
762
|
-
process.stderr.write(
|
|
763
|
-
`markdown-renderer: cannot resolve slice path for ${milestoneId}/${sliceId}\n`,
|
|
764
|
-
);
|
|
765
|
-
return false;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
// Use the tasks/ subdir when it exists (legacy layout), otherwise use the
|
|
769
|
-
// slice path directly (flat-phase: task summaries live alongside plan files).
|
|
770
|
-
const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId) ?? slicePath;
|
|
771
|
-
const fileName = buildTaskFileName(taskId, "SUMMARY");
|
|
772
|
-
const absPath = join(tasksDir, fileName);
|
|
754
|
+
const absPath = targetTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY", getMilestone(milestoneId)?.title);
|
|
773
755
|
const artifactPath = toArtifactPath(absPath, basePath);
|
|
774
756
|
|
|
775
757
|
await writeAndStore(absPath, artifactPath, task.full_summary_md, {
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
legacyMilestonesDir,
|
|
32
32
|
gsdRoot,
|
|
33
33
|
resolveTaskFiles,
|
|
34
|
+
resolveTaskFile,
|
|
34
35
|
resolveMilestonePath,
|
|
35
36
|
} from './paths.js';
|
|
36
37
|
import { findMilestoneIds } from './guided-flow.js';
|
|
@@ -925,8 +926,7 @@ export function migrateHierarchyToDb(
|
|
|
925
926
|
legacyTasksDir = isLegacySlice
|
|
926
927
|
? resolveTasksDir(basePath, milestoneId, sliceEntry.id)
|
|
927
928
|
: null;
|
|
928
|
-
|
|
929
|
-
taskSummaryFile = join(summaryDir, `${taskEntry.id}-SUMMARY.md`);
|
|
929
|
+
taskSummaryFile = resolveTaskFile(basePath, milestoneId, sliceEntry.id, taskEntry.id, 'SUMMARY');
|
|
930
930
|
}
|
|
931
931
|
const hasTaskSummary = taskSummaryFile !== null && existsSync(taskSummaryFile);
|
|
932
932
|
|
|
@@ -950,9 +950,9 @@ export function migrateHierarchyToDb(
|
|
|
950
950
|
// first execute-task. The surviving SUMMARY wins over a stale checkbox.
|
|
951
951
|
// reopen-task removes the SUMMARY, so this never re-completes an
|
|
952
952
|
// intentionally reopened task.
|
|
953
|
-
// Flat-phase summaries are phase-scoped
|
|
954
|
-
//
|
|
955
|
-
//
|
|
953
|
+
// Flat-phase summaries are phase-scoped; when a milestone has multiple
|
|
954
|
+
// slices, require the summary parent frontmatter to match so one slice's
|
|
955
|
+
// completion does not attest a sibling's same-named task.
|
|
956
956
|
let summaryAttestsCompletion = hasTaskSummary;
|
|
957
957
|
if (summaryAttestsCompletion && !isLegacySlice && roadmap.slices.length > 1 && taskSummaryFile) {
|
|
958
958
|
try {
|
|
@@ -12,6 +12,12 @@ export interface ModelCostEntry {
|
|
|
12
12
|
inputPer1k: number;
|
|
13
13
|
/** Approximate cost per 1K output tokens in USD */
|
|
14
14
|
outputPer1k: number;
|
|
15
|
+
/** Input-token-based long-context pricing tiers, when published */
|
|
16
|
+
tiers?: Array<{
|
|
17
|
+
inputTokensAbove: number;
|
|
18
|
+
inputPer1k: number;
|
|
19
|
+
outputPer1k: number;
|
|
20
|
+
}>;
|
|
15
21
|
/** Last updated date */
|
|
16
22
|
updatedAt: string;
|
|
17
23
|
}
|
|
@@ -62,6 +68,9 @@ export const BUNDLED_COST_TABLE: ModelCostEntry[] = [
|
|
|
62
68
|
// GPT-5.5 API list price, also used for live Codex OAuth routing.
|
|
63
69
|
// Source: https://openai.com/api/pricing/
|
|
64
70
|
{ id: "gpt-5.5", inputPer1k: 0.005, outputPer1k: 0.03, updatedAt: "2026-04-23" },
|
|
71
|
+
{ id: "gpt-5.6-sol", inputPer1k: 0.005, outputPer1k: 0.03, tiers: [{ inputTokensAbove: 272000, inputPer1k: 0.01, outputPer1k: 0.045 }], updatedAt: "2026-07-11" },
|
|
72
|
+
{ id: "gpt-5.6-terra", inputPer1k: 0.0025, outputPer1k: 0.015, tiers: [{ inputTokensAbove: 272000, inputPer1k: 0.005, outputPer1k: 0.0225 }], updatedAt: "2026-07-11" },
|
|
73
|
+
{ id: "gpt-5.6-luna", inputPer1k: 0.001, outputPer1k: 0.006, tiers: [{ inputTokensAbove: 272000, inputPer1k: 0.002, outputPer1k: 0.009 }], updatedAt: "2026-07-11" },
|
|
65
74
|
|
|
66
75
|
// Google
|
|
67
76
|
{ id: "gemini-2.0-flash", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2025-03-15" },
|
|
@@ -78,7 +87,11 @@ export const BUNDLED_COST_TABLE: ModelCostEntry[] = [
|
|
|
78
87
|
export function lookupModelCost(modelId: string): ModelCostEntry | undefined {
|
|
79
88
|
const bareId = modelId.includes("/") ? modelId.split("/").pop()! : modelId;
|
|
80
89
|
return BUNDLED_COST_TABLE.find(e => e.id === bareId)
|
|
81
|
-
?? BUNDLED_COST_TABLE.find(e =>
|
|
90
|
+
?? BUNDLED_COST_TABLE.find(e =>
|
|
91
|
+
bareId.startsWith(`${e.id}-`) ||
|
|
92
|
+
bareId.startsWith(`${e.id}:`) ||
|
|
93
|
+
bareId.startsWith(`${e.id}@`)
|
|
94
|
+
);
|
|
82
95
|
}
|
|
83
96
|
|
|
84
97
|
/**
|
|
@@ -111,10 +111,14 @@ export const MODEL_CAPABILITY_TIER: Record<string, ComplexityTier> = {
|
|
|
111
111
|
"gpt-5.3-codex": "heavy",
|
|
112
112
|
"gpt-5.4": "heavy",
|
|
113
113
|
"gpt-5.5": "heavy",
|
|
114
|
+
"gpt-5.6-sol": "heavy",
|
|
115
|
+
"gpt-5.6-terra": "heavy",
|
|
116
|
+
"gpt-5.6-luna": "heavy",
|
|
114
117
|
"o1": "heavy",
|
|
115
118
|
"o3": "heavy",
|
|
116
119
|
"o4-mini": "heavy",
|
|
117
120
|
"o4-mini-deep-research": "heavy",
|
|
121
|
+
"grok-4.5": "heavy",
|
|
118
122
|
};
|
|
119
123
|
|
|
120
124
|
// ─── Cost Table (per 1K input tokens, approximate USD) ───────────────────────
|
|
@@ -149,11 +153,15 @@ const MODEL_COST_PER_1K_INPUT: Record<string, number> = {
|
|
|
149
153
|
"gpt-5.3-codex-spark": 0.0003,
|
|
150
154
|
"gpt-5.4": 0.005,
|
|
151
155
|
"gpt-5.5": 0.005,
|
|
156
|
+
"gpt-5.6-sol": 0.005,
|
|
157
|
+
"gpt-5.6-terra": 0.0025,
|
|
158
|
+
"gpt-5.6-luna": 0.001,
|
|
152
159
|
"o4-mini": 0.005,
|
|
153
160
|
"o4-mini-deep-research": 0.005,
|
|
154
161
|
"gemini-2.0-flash": 0.0001,
|
|
155
162
|
"gemini-2.5-pro": 0.00125,
|
|
156
163
|
"deepseek-chat": 0.00014,
|
|
164
|
+
"grok-4.5": 0.002,
|
|
157
165
|
};
|
|
158
166
|
|
|
159
167
|
// ─── Capability Profiles Data Table ──────────────────────────────────────────
|
|
@@ -198,6 +206,10 @@ export const MODEL_CAPABILITY_PROFILES: Record<string, ModelCapabilities> = {
|
|
|
198
206
|
// OpenAI's 2026-04-23 published eval deltas across coding, tool use, and long context.
|
|
199
207
|
// Source: https://openai.com/index/introducing-gpt-5-5/
|
|
200
208
|
"gpt-5.5": { coding: 96, debugging: 93, research: 89, reasoning: 95, speed: 42, longContext: 90, instruction: 93 },
|
|
209
|
+
// GPT-5.6 profiles are provisional until official eval results are available.
|
|
210
|
+
"gpt-5.6-sol": { coding: 97, debugging: 94, research: 90, reasoning: 96, speed: 42, longContext: 91, instruction: 94 },
|
|
211
|
+
"gpt-5.6-terra": { coding: 96, debugging: 93, research: 89, reasoning: 95, speed: 48, longContext: 91, instruction: 93 },
|
|
212
|
+
"gpt-5.6-luna": { coding: 92, debugging: 88, research: 84, reasoning: 91, speed: 72, longContext: 91, instruction: 90 },
|
|
201
213
|
|
|
202
214
|
// ── OpenAI o-series (reasoning-first) ──────────────────────────────────────
|
|
203
215
|
"o1": { coding: 78, debugging: 82, research: 78, reasoning: 90, speed: 20, longContext: 65, instruction: 82 },
|
|
@@ -212,6 +224,11 @@ export const MODEL_CAPABILITY_PROFILES: Record<string, ModelCapabilities> = {
|
|
|
212
224
|
|
|
213
225
|
// ── DeepSeek ───────────────────────────────────────────────────────────────
|
|
214
226
|
"deepseek-chat": { coding: 75, debugging: 65, research: 55, reasoning: 70, speed: 70, longContext: 55, instruction: 65 },
|
|
227
|
+
|
|
228
|
+
// ── xAI ────────────────────────────────────────────────────────────────────
|
|
229
|
+
// Grok 4.5 (2026-07): Opus-class frontier model tuned for coding and agentic
|
|
230
|
+
// work; notably faster and more token-efficient than peer heavy models.
|
|
231
|
+
"grok-4.5": { coding: 95, debugging: 90, research: 82, reasoning: 93, speed: 55, longContext: 80, instruction: 90 },
|
|
215
232
|
};
|
|
216
233
|
|
|
217
234
|
// ─── Base Task Requirements Data Table ───────────────────────────────────────
|
|
@@ -136,6 +136,14 @@ function cachedReaddir(dirPath: string): string[] {
|
|
|
136
136
|
return entries;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
function isExistingFile(path: string): boolean {
|
|
140
|
+
try {
|
|
141
|
+
return statSync(path).isFile();
|
|
142
|
+
} catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
139
147
|
/**
|
|
140
148
|
* Clear the volatile directory listing caches.
|
|
141
149
|
* Call after milestone transitions, file creation in planning directories,
|
|
@@ -223,6 +231,26 @@ export function buildTaskFileName(taskId: string, suffix: string): string {
|
|
|
223
231
|
return `${taskId}-${suffix}.md`;
|
|
224
232
|
}
|
|
225
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Build a flat-phase task artifact file name.
|
|
236
|
+
* ("S06", "T03", "SUMMARY") → "S06-T03-SUMMARY.md"
|
|
237
|
+
*/
|
|
238
|
+
export function buildFlatTaskFileName(sliceId: string, taskId: string, suffix: string): string {
|
|
239
|
+
return `${sliceId}-${taskId}-${suffix}.md`;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Extract the task ID from a task artifact filename.
|
|
244
|
+
* Supports flat-phase S##-T##-SUFFIX.md plus legacy T##-SUFFIX.md and
|
|
245
|
+
* T##-DESCRIPTOR-SUFFIX.md names.
|
|
246
|
+
*/
|
|
247
|
+
export function taskIdFromTaskFileName(fileName: string, suffix: string): string | null {
|
|
248
|
+
const flat = new RegExp(`^S\\d+-(T\\d+)-${suffix}\\.md$`, "i").exec(fileName);
|
|
249
|
+
if (flat?.[1]) return flat[1].toUpperCase();
|
|
250
|
+
const legacy = new RegExp(`^(T\\d+)(?:-.*)?-${suffix}\\.md$`, "i").exec(fileName);
|
|
251
|
+
return legacy?.[1]?.toUpperCase() ?? null;
|
|
252
|
+
}
|
|
253
|
+
|
|
226
254
|
// ─── Resolvers ─────────────────────────────────────────────────────────────
|
|
227
255
|
|
|
228
256
|
/**
|
|
@@ -264,7 +292,7 @@ export function resolveFile(dir: string, idPrefix: string, suffix: string): stri
|
|
|
264
292
|
if (!existsSync(dir)) return null;
|
|
265
293
|
const target = `${idPrefix}-${suffix}.md`.toUpperCase();
|
|
266
294
|
try {
|
|
267
|
-
const entries =
|
|
295
|
+
const entries = cachedReaddirWithTypes(dir).filter(e => e.isFile()).map(e => e.name);
|
|
268
296
|
// Direct match: ID-SUFFIX.md
|
|
269
297
|
const direct = entries.find(e => e.toUpperCase() === target);
|
|
270
298
|
if (direct) return direct;
|
|
@@ -284,18 +312,17 @@ export function resolveFile(dir: string, idPrefix: string, suffix: string): stri
|
|
|
284
312
|
}
|
|
285
313
|
|
|
286
314
|
/**
|
|
287
|
-
* Find all task files matching a pattern in a tasks directory.
|
|
288
|
-
* Returns sorted file names matching T##-SUFFIX.md
|
|
315
|
+
* Find all task files matching a pattern in a tasks directory or flat phase dir.
|
|
316
|
+
* Returns sorted file names matching S##-T##-SUFFIX.md, T##-SUFFIX.md,
|
|
317
|
+
* or legacy T##-*-SUFFIX.md.
|
|
289
318
|
*/
|
|
290
319
|
export function resolveTaskFiles(tasksDir: string, suffix: string): string[] {
|
|
291
320
|
if (!existsSync(tasksDir)) return [];
|
|
292
321
|
try {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return cachedReaddir(tasksDir)
|
|
298
|
-
.filter(f => currentPattern.test(f) || legacyPattern.test(f))
|
|
322
|
+
return cachedReaddirWithTypes(tasksDir)
|
|
323
|
+
.filter(e => e.isFile())
|
|
324
|
+
.map(e => e.name)
|
|
325
|
+
.filter(f => taskIdFromTaskFileName(f, suffix) !== null)
|
|
299
326
|
.sort();
|
|
300
327
|
} catch {
|
|
301
328
|
return [];
|
|
@@ -843,7 +870,7 @@ export function resolveMilestoneFile(
|
|
|
843
870
|
const prefix = `${String(phaseNum).padStart(2, "0")}`;
|
|
844
871
|
const flatName = `${prefix}-${suffix}.md`;
|
|
845
872
|
const flatPath = join(mDir, flatName);
|
|
846
|
-
if (
|
|
873
|
+
if (isExistingFile(flatPath)) return flatPath;
|
|
847
874
|
// Legacy fallback: M001-SUFFIX.md
|
|
848
875
|
const file = resolveFile(mDir, milestoneId, suffix);
|
|
849
876
|
return file ? join(mDir, file) : null;
|
|
@@ -878,11 +905,11 @@ export function resolveSliceFile(
|
|
|
878
905
|
const planNum = sliceIdToPlanNum(sliceId);
|
|
879
906
|
const flatName = planFileName(phaseNum, planNum, suffix);
|
|
880
907
|
const flatPath = join(phaseDir, flatName);
|
|
881
|
-
if (
|
|
908
|
+
if (isExistingFile(flatPath)) return flatPath;
|
|
882
909
|
// Also check plan-number-only format MM-SUFFIX.md (written by buildSliceFileName)
|
|
883
910
|
const planOnlyName = `${String(planNum).padStart(2, "0")}-${suffix}.md`;
|
|
884
911
|
const planOnlyPath = join(phaseDir, planOnlyName);
|
|
885
|
-
if (
|
|
912
|
+
if (isExistingFile(planOnlyPath)) return planOnlyPath;
|
|
886
913
|
// Try prefix match for the phase+plan number (handles suffix variations)
|
|
887
914
|
const planPrefix = `${String(phaseNum).padStart(2, "0")}-${String(planNum).padStart(2, "0")}-`;
|
|
888
915
|
try {
|
|
@@ -931,8 +958,10 @@ export function resolveTaskFile(
|
|
|
931
958
|
const isLegacy = phaseDir.startsWith(legacyBase + "/") || phaseDir.startsWith(legacyBase + "\\");
|
|
932
959
|
|
|
933
960
|
if (suffix !== "PLAN" && !isLegacy) {
|
|
934
|
-
const flatPath = join(phaseDir,
|
|
935
|
-
|
|
961
|
+
const flatPath = join(phaseDir, buildFlatTaskFileName(sliceId, taskId, suffix));
|
|
962
|
+
if (isExistingFile(flatPath)) return flatPath;
|
|
963
|
+
const legacyFlatPath = join(phaseDir, buildTaskFileName(taskId, suffix));
|
|
964
|
+
return isExistingFile(legacyFlatPath) ? legacyFlatPath : null;
|
|
936
965
|
}
|
|
937
966
|
|
|
938
967
|
const tDir = resolveTasksDir(basePath, milestoneId, sliceId);
|
|
@@ -1066,6 +1095,35 @@ export function targetSliceFile(
|
|
|
1066
1095
|
return join(dir, fileName);
|
|
1067
1096
|
}
|
|
1068
1097
|
|
|
1098
|
+
/**
|
|
1099
|
+
* Build the canonical absolute write target for a task file.
|
|
1100
|
+
* Readers that need legacy flat-phase fallback should call resolveTaskFile.
|
|
1101
|
+
*/
|
|
1102
|
+
export function targetTaskFile(
|
|
1103
|
+
basePath: string, milestoneId: string, sliceId: string,
|
|
1104
|
+
taskId: string, suffix: string, milestoneTitle?: string
|
|
1105
|
+
): string {
|
|
1106
|
+
if (suffix === "PLAN") {
|
|
1107
|
+
return targetSliceFile(basePath, milestoneId, sliceId, "PLAN", milestoneTitle);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
const mDir = resolveMilestonePath(basePath, milestoneId);
|
|
1111
|
+
const legacyBase = legacyMilestonesDir(basePath);
|
|
1112
|
+
const isLegacy = mDir
|
|
1113
|
+
? mDir.startsWith(legacyBase + "/") || mDir.startsWith(legacyBase + "\\")
|
|
1114
|
+
: isLegacyMilestonesLayout(basePath);
|
|
1115
|
+
const milestoneDir = mDir
|
|
1116
|
+
?? dirname(targetMilestoneFile(basePath, milestoneId, "ROADMAP", milestoneTitle));
|
|
1117
|
+
|
|
1118
|
+
if (isLegacy) {
|
|
1119
|
+
const slicesDir = join(milestoneDir, "slices");
|
|
1120
|
+
const sliceDir = join(slicesDir, resolveDir(slicesDir, sliceId) ?? sliceId);
|
|
1121
|
+
return join(sliceDir, "tasks", buildTaskFileName(taskId, suffix));
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
return join(milestoneDir, buildFlatTaskFileName(sliceId, taskId, suffix));
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1069
1127
|
/**
|
|
1070
1128
|
* Build relative .gsd/ path to a slice file.
|
|
1071
1129
|
* Preserves an existing compatibility filename when present; otherwise falls
|
|
@@ -1105,5 +1163,5 @@ export function relTaskFile(
|
|
|
1105
1163
|
return relSliceFile(basePath, milestoneId, sliceId, "PLAN");
|
|
1106
1164
|
}
|
|
1107
1165
|
const relS = relSlicePath(basePath, milestoneId, sliceId, milestoneTitle);
|
|
1108
|
-
return `${relS}/${
|
|
1166
|
+
return `${relS}/${buildFlatTaskFileName(sliceId, taskId, suffix)}`;
|
|
1109
1167
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { CONFIGURABLE_PLANNING_SUBAGENT_UNITS, type GSDPreferences } from "./preferences-types.js";
|
|
2
|
+
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
3
|
+
import type { ToolsPolicy } from "./unit-context-manifest.js";
|
|
4
|
+
|
|
5
|
+
const CONFIGURABLE_UNITS = new Set<string>(CONFIGURABLE_PLANNING_SUBAGENT_UNITS);
|
|
6
|
+
|
|
7
|
+
function configuredAllowedSubagents(
|
|
8
|
+
unitType: string,
|
|
9
|
+
preferences: GSDPreferences | null | undefined,
|
|
10
|
+
): readonly string[] {
|
|
11
|
+
if (!CONFIGURABLE_UNITS.has(unitType)) return [];
|
|
12
|
+
return preferences?.planning_subagents?.[
|
|
13
|
+
unitType as keyof NonNullable<GSDPreferences["planning_subagents"]>
|
|
14
|
+
]?.allowed ?? [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function mergeAllowedSubagents(
|
|
18
|
+
current: readonly string[],
|
|
19
|
+
configured: readonly string[],
|
|
20
|
+
): readonly string[] {
|
|
21
|
+
return Array.from(new Set([...current, ...configured]));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function applyPlanningSubagentPreferences(
|
|
25
|
+
unitType: string,
|
|
26
|
+
policy: ToolsPolicy | null | undefined,
|
|
27
|
+
preferences: GSDPreferences | null | undefined,
|
|
28
|
+
): ToolsPolicy | null | undefined {
|
|
29
|
+
if (!policy) return policy;
|
|
30
|
+
const configured = configuredAllowedSubagents(unitType, preferences);
|
|
31
|
+
if (configured.length === 0) return policy;
|
|
32
|
+
|
|
33
|
+
if (policy.mode === "planning") {
|
|
34
|
+
return {
|
|
35
|
+
mode: "planning-dispatch",
|
|
36
|
+
allowedSubagents: mergeAllowedSubagents([], configured),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (policy.mode === "planning-dispatch") {
|
|
41
|
+
return {
|
|
42
|
+
...policy,
|
|
43
|
+
allowedSubagents: mergeAllowedSubagents(policy.allowedSubagents, configured),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return policy;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function resolveEffectivePlanningToolsPolicy(
|
|
51
|
+
unitType: string,
|
|
52
|
+
policy: ToolsPolicy | null | undefined,
|
|
53
|
+
basePath?: string,
|
|
54
|
+
): ToolsPolicy | null | undefined {
|
|
55
|
+
if (!basePath) return policy;
|
|
56
|
+
const preferences = loadEffectiveGSDPreferences(basePath)?.preferences;
|
|
57
|
+
return applyPlanningSubagentPreferences(unitType, policy, preferences);
|
|
58
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only planning specialists that controlled planning dispatch may use.
|
|
3
|
+
*
|
|
4
|
+
* Unit manifests and project preferences still declare per-unit subsets. This
|
|
5
|
+
* registry is the global safety classification checked by the write gate and
|
|
6
|
+
* preference validation before any configured planning allowlist takes effect.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { PlanningSubagentRegistryConfig } from "./preferences-types.js";
|
|
10
|
+
|
|
11
|
+
const PLANNING_DISPATCH_AGENT_REGISTRY = {
|
|
12
|
+
mnemo: { readOnlySpecialist: true },
|
|
13
|
+
scout: { readOnlySpecialist: true },
|
|
14
|
+
planner: { readOnlySpecialist: true },
|
|
15
|
+
reviewer: { readOnlySpecialist: true },
|
|
16
|
+
security: { readOnlySpecialist: true },
|
|
17
|
+
tester: { readOnlySpecialist: true },
|
|
18
|
+
} as const satisfies Record<string, { readonly readOnlySpecialist: boolean }>;
|
|
19
|
+
|
|
20
|
+
export const ALLOWED_PLANNING_DISPATCH_AGENTS = new Set<string>(
|
|
21
|
+
Object.entries(PLANNING_DISPATCH_AGENT_REGISTRY)
|
|
22
|
+
.filter(([, metadata]) => metadata.readOnlySpecialist)
|
|
23
|
+
.map(([agentId]) => agentId),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
function configuredPlanningDispatchAgents(registry?: PlanningSubagentRegistryConfig): string[] {
|
|
27
|
+
return Object.entries(registry ?? {})
|
|
28
|
+
.filter(([, metadata]) => metadata.read_only_specialist === true)
|
|
29
|
+
.map(([agentId]) => agentId);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isReadOnlyPlanningDispatchAgent(
|
|
33
|
+
agentId: string,
|
|
34
|
+
registry?: PlanningSubagentRegistryConfig,
|
|
35
|
+
): boolean {
|
|
36
|
+
const metadata = PLANNING_DISPATCH_AGENT_REGISTRY[agentId as keyof typeof PLANNING_DISPATCH_AGENT_REGISTRY];
|
|
37
|
+
return metadata?.readOnlySpecialist === true || registry?.[agentId]?.read_only_specialist === true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function allowedPlanningDispatchAgentsList(registry?: PlanningSubagentRegistryConfig): string {
|
|
41
|
+
return Array.from(new Set([
|
|
42
|
+
...ALLOWED_PLANNING_DISPATCH_AGENTS,
|
|
43
|
+
...configuredPlanningDispatchAgents(registry),
|
|
44
|
+
])).join(", ");
|
|
45
|
+
}
|