gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.04f5ccf82
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 +93 -18
- package/dist/cli.js +20 -9
- package/dist/headless-ui.js +13 -6
- package/dist/headless.js +9 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +1 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +122 -40
- package/dist/resources/extensions/gsd/auto/orchestrator.js +15 -4
- package/dist/resources/extensions/gsd/auto/phases.js +146 -49
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
- package/dist/resources/extensions/gsd/auto-budget.js +9 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +72 -5
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +185 -30
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +329 -137
- package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
- package/dist/resources/extensions/gsd/auto-recovery.js +82 -16
- package/dist/resources/extensions/gsd/auto-start.js +99 -16
- package/dist/resources/extensions/gsd/auto-timers.js +11 -3
- package/dist/resources/extensions/gsd/auto-verification.js +146 -34
- package/dist/resources/extensions/gsd/auto-worktree.js +185 -26
- package/dist/resources/extensions/gsd/auto.js +135 -74
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +65 -10
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +13 -10
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +14 -4
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
- package/dist/resources/extensions/gsd/clean-root-preflight.js +267 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +16 -4
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +55 -7
- package/dist/resources/extensions/gsd/db/auto-workers.js +30 -0
- package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
- package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
- package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +74 -3
- package/dist/resources/extensions/gsd/doctor-proactive.js +14 -2
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor.js +2 -28
- package/dist/resources/extensions/gsd/export-html.js +27 -425
- package/dist/resources/extensions/gsd/forensics.js +10 -3
- package/dist/resources/extensions/gsd/git-conflict-state.js +21 -0
- package/dist/resources/extensions/gsd/git-service.js +152 -15
- package/dist/resources/extensions/gsd/gsd-db.js +76 -33
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +110 -117
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/init-wizard.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
- package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +121 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
- package/dist/resources/extensions/gsd/pre-execution-checks.js +54 -19
- package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
- package/dist/resources/extensions/gsd/preferences-models.js +6 -4
- package/dist/resources/extensions/gsd/preferences-types.js +3 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +147 -0
- package/dist/resources/extensions/gsd/preferences.js +35 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/repo-identity.js +39 -22
- package/dist/resources/extensions/gsd/repository-registry.js +44 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
- package/dist/resources/extensions/gsd/session-lock.js +15 -2
- package/dist/resources/extensions/gsd/slice-parallel-conflict.js +2 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +84 -5
- package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
- package/dist/resources/extensions/gsd/state.js +28 -7
- package/dist/resources/extensions/gsd/status-guards.js +14 -2
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/dist/resources/extensions/gsd/templates/plan.md +9 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -9
- package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -10
- package/dist/resources/extensions/gsd/tools/exec-tool.js +87 -5
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +32 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +185 -40
- package/dist/resources/extensions/gsd/tui/render-kit.js +33 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +142 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/watch/header-renderer.js +34 -25
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +86 -19
- package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
- package/dist/resources/extensions/gsd/worktree-safety.js +43 -4
- package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
- package/dist/resources/extensions/gsd/worktree-telemetry.js +32 -0
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/shared/interview-ui.js +6 -4
- package/dist/resources/extensions/shared/next-action-ui.js +13 -5
- 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/ttsr/ttsr-manager.js +3 -1
- 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 +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- package/dist/resources/skills/forensics/SKILL.md +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 +8 -8
- 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 +5 -5
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- 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.js.nft.json +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 +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
- 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 +4 -5
- 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 -5
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -7
- 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 +4 -7
- 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 +4 -5
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
- 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/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
- package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.js +7 -8
- package/package.json +4 -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 +13 -4
- 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.test.ts +23 -1
- 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/native/src/__tests__/stream-process.test.mjs +32 -12
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +16 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +82 -97
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +20 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +91 -102
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/loader.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/loader.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/loader.test.js +24 -0
- package/packages/pi-tui/dist/__tests__/loader.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +72 -4
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/loader.js +3 -0
- package/packages/pi-tui/dist/components/loader.js.map +1 -1
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +1 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +117 -33
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/loader.test.ts +30 -0
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +90 -4
- package/packages/pi-tui/src/components/loader.ts +3 -0
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/src/tui.ts +116 -33
- 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 +10 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +19 -6
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +1 -0
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +123 -40
- package/src/resources/extensions/gsd/auto/orchestrator.ts +15 -4
- package/src/resources/extensions/gsd/auto/phases.ts +172 -60
- package/src/resources/extensions/gsd/auto/session.ts +16 -0
- package/src/resources/extensions/gsd/auto/types.ts +3 -0
- package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
- package/src/resources/extensions/gsd/auto-budget.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +78 -5
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +208 -29
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +369 -148
- package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
- package/src/resources/extensions/gsd/auto-recovery.ts +86 -13
- package/src/resources/extensions/gsd/auto-start.ts +109 -14
- package/src/resources/extensions/gsd/auto-timers.ts +10 -3
- package/src/resources/extensions/gsd/auto-verification.ts +174 -42
- package/src/resources/extensions/gsd/auto-worktree.ts +202 -30
- package/src/resources/extensions/gsd/auto.ts +172 -81
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +66 -10
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -10
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -4
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
- package/src/resources/extensions/gsd/clean-root-preflight.ts +284 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +17 -4
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- package/src/resources/extensions/gsd/crash-recovery.ts +55 -6
- package/src/resources/extensions/gsd/db/auto-workers.ts +37 -0
- package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
- package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
- package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +73 -3
- package/src/resources/extensions/gsd/doctor-proactive.ts +18 -2
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -27
- package/src/resources/extensions/gsd/export-html.ts +27 -427
- package/src/resources/extensions/gsd/forensics.ts +9 -3
- package/src/resources/extensions/gsd/git-conflict-state.ts +23 -0
- package/src/resources/extensions/gsd/git-service.ts +182 -16
- package/src/resources/extensions/gsd/gsd-db.ts +80 -31
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +142 -134
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/init-wizard.ts +17 -2
- package/src/resources/extensions/gsd/journal.ts +8 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
- package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +139 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
- package/src/resources/extensions/gsd/pre-execution-checks.ts +67 -19
- package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
- package/src/resources/extensions/gsd/preferences-models.ts +6 -4
- package/src/resources/extensions/gsd/preferences-types.ts +35 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +154 -0
- package/src/resources/extensions/gsd/preferences.ts +39 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/repo-identity.ts +45 -25
- package/src/resources/extensions/gsd/repository-registry.ts +77 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
- package/src/resources/extensions/gsd/session-lock.ts +15 -2
- package/src/resources/extensions/gsd/slice-parallel-conflict.ts +2 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +75 -3
- package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
- package/src/resources/extensions/gsd/state.ts +33 -7
- package/src/resources/extensions/gsd/status-guards.ts +16 -2
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/src/resources/extensions/gsd/templates/plan.md +9 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +775 -34
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +245 -28
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +136 -13
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-workers.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +170 -3
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +55 -2
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +60 -9
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +139 -1
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +140 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +99 -1
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +15 -1
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +36 -1
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +226 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +5 -21
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
- package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +21 -40
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +59 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/prefs-missing-models-crash.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +28 -1
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +59 -1
- package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +112 -1
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +94 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +188 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +153 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +73 -2
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +18 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +57 -10
- package/src/resources/extensions/gsd/tools/exec-tool.ts +98 -5
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +31 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +166 -17
- package/src/resources/extensions/gsd/tui/render-kit.ts +44 -0
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +170 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/watch/header-renderer.ts +35 -24
- package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +98 -20
- package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
- package/src/resources/extensions/gsd/worktree-safety.ts +57 -10
- package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
- package/src/resources/extensions/gsd/worktree-telemetry.ts +39 -0
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/shared/interview-ui.ts +6 -4
- package/src/resources/extensions/shared/next-action-ui.ts +11 -5
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
- package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +32 -0
- 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/ttsr/ttsr-manager.ts +5 -1
- 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 +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/src/resources/skills/forensics/SKILL.md +1 -1
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → w_ikFkx_-OHxisG9xjz4u}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → w_ikFkx_-OHxisG9xjz4u}/_ssgManifest.js +0 -0
|
@@ -17,6 +17,43 @@
|
|
|
17
17
|
import { existsSync, readFileSync } from "node:fs";
|
|
18
18
|
import { resolve, dirname, extname } from "node:path";
|
|
19
19
|
// ─── Import Resolution Check ─────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Replace the contents of single- and double-quoted string literals on a single
|
|
22
|
+
* source line with spaces so import patterns do not match text inside strings.
|
|
23
|
+
* Template-literal spans are handled separately via the inTemplateLiteral flag.
|
|
24
|
+
*/
|
|
25
|
+
function stripStringLiterals(line) {
|
|
26
|
+
let result = "";
|
|
27
|
+
let i = 0;
|
|
28
|
+
while (i < line.length) {
|
|
29
|
+
const ch = line[i];
|
|
30
|
+
if (ch === '"' || ch === "'") {
|
|
31
|
+
result += ch;
|
|
32
|
+
i++;
|
|
33
|
+
while (i < line.length) {
|
|
34
|
+
const c = line[i];
|
|
35
|
+
if (c === "\\" && i + 1 < line.length) {
|
|
36
|
+
result += " ";
|
|
37
|
+
i += 2;
|
|
38
|
+
}
|
|
39
|
+
else if (c === ch) {
|
|
40
|
+
result += ch;
|
|
41
|
+
i++;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
result += " ";
|
|
46
|
+
i++;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
result += ch;
|
|
52
|
+
i++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
20
57
|
/**
|
|
21
58
|
* Extract relative import paths from TypeScript/JavaScript source code.
|
|
22
59
|
* Returns array of { importPath, lineNum } for relative imports.
|
|
@@ -30,11 +67,19 @@ export function extractRelativeImports(source) {
|
|
|
30
67
|
// import './path'
|
|
31
68
|
// require('./path')
|
|
32
69
|
// require("../path")
|
|
33
|
-
const importPattern = /(
|
|
70
|
+
const importPattern = /(?:^|[;{}]\s*)import\s+(?:.*?\s+from\s+)?(['"])(\.\.?\/[^'"]+)\1/g;
|
|
71
|
+
const requirePattern = /require\s*\(\s*(['"])(\.\.?\/[^'"]+)\1/g;
|
|
34
72
|
// Track if we're inside a block comment
|
|
35
73
|
let inBlockComment = false;
|
|
74
|
+
let inTemplateLiteral = false;
|
|
36
75
|
for (let i = 0; i < lines.length; i++) {
|
|
37
76
|
const line = lines[i];
|
|
77
|
+
if (inTemplateLiteral) {
|
|
78
|
+
if ((line.match(/(?<!\\)`/g) ?? []).length % 2 === 1) {
|
|
79
|
+
inTemplateLiteral = false;
|
|
80
|
+
}
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
38
83
|
// Handle block comment boundaries
|
|
39
84
|
if (inBlockComment) {
|
|
40
85
|
if (line.includes("*/")) {
|
|
@@ -61,9 +106,17 @@ export function extractRelativeImports(source) {
|
|
|
61
106
|
let match;
|
|
62
107
|
// Reset lastIndex for each line
|
|
63
108
|
importPattern.lastIndex = 0;
|
|
109
|
+
requirePattern.lastIndex = 0;
|
|
110
|
+
const strippedLine = stripStringLiterals(line);
|
|
64
111
|
while ((match = importPattern.exec(line)) !== null) {
|
|
112
|
+
const importOffset = match[0].indexOf("import");
|
|
113
|
+
const importStart = match.index + importOffset;
|
|
114
|
+
if (strippedLine.slice(importStart, importStart + "import".length) !==
|
|
115
|
+
"import") {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
65
118
|
// Check if this match is after a // comment marker on the same line
|
|
66
|
-
const beforeMatch =
|
|
119
|
+
const beforeMatch = strippedLine.substring(0, match.index);
|
|
67
120
|
if (beforeMatch.includes("//")) {
|
|
68
121
|
continue;
|
|
69
122
|
}
|
|
@@ -72,6 +125,24 @@ export function extractRelativeImports(source) {
|
|
|
72
125
|
lineNum: i + 1,
|
|
73
126
|
});
|
|
74
127
|
}
|
|
128
|
+
while ((match = requirePattern.exec(line)) !== null) {
|
|
129
|
+
if (strippedLine.slice(match.index, match.index + "require".length) !==
|
|
130
|
+
"require") {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// Check if this match is after a // comment marker on the same line
|
|
134
|
+
const beforeMatch = strippedLine.substring(0, match.index);
|
|
135
|
+
if (beforeMatch.includes("//")) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
imports.push({
|
|
139
|
+
importPath: match[2],
|
|
140
|
+
lineNum: i + 1,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
if ((strippedLine.match(/(?<!\\)`/g) ?? []).length % 2 === 1) {
|
|
144
|
+
inTemplateLiteral = true;
|
|
145
|
+
}
|
|
75
146
|
}
|
|
76
147
|
return imports;
|
|
77
148
|
}
|
|
@@ -109,13 +180,6 @@ export function resolveImportPath(importPath, sourceFile, basePath) {
|
|
|
109
180
|
".woff", ".woff2", ".ttf", ".otf", ".eot",
|
|
110
181
|
]);
|
|
111
182
|
const runtimeFallbackExtensions = new Set([".js", ".jsx", ".mjs", ".cjs"]);
|
|
112
|
-
const dottedStemFallbackExtensions = new Set([".server", ".client", ".webhook"]);
|
|
113
|
-
if (explicitExt !== "" &&
|
|
114
|
-
!runtimeFallbackExtensions.has(explicitExt) &&
|
|
115
|
-
!nonFallbackExtensions.has(explicitExt) &&
|
|
116
|
-
!dottedStemFallbackExtensions.has(explicitExt)) {
|
|
117
|
-
return { exists: false, resolvedPath: null };
|
|
118
|
-
}
|
|
119
183
|
if (nonFallbackExtensions.has(explicitExt) && !runtimeFallbackExtensions.has(explicitExt)) {
|
|
120
184
|
return { exists: false, resolvedPath: null };
|
|
121
185
|
}
|
|
@@ -18,8 +18,34 @@
|
|
|
18
18
|
import { existsSync } from "node:fs";
|
|
19
19
|
import { spawn } from "node:child_process";
|
|
20
20
|
import { homedir } from "node:os";
|
|
21
|
-
import { resolve } from "node:path";
|
|
21
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
22
|
+
import { validateVerificationCommand } from "./verification-gate.js";
|
|
22
23
|
const NPM_COMMAND = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
24
|
+
export function checkVerificationCommands(tasks) {
|
|
25
|
+
const results = [];
|
|
26
|
+
for (const task of tasks) {
|
|
27
|
+
const verify = task.verify.trim();
|
|
28
|
+
if (!verify)
|
|
29
|
+
continue;
|
|
30
|
+
const commands = verify
|
|
31
|
+
.split("&&")
|
|
32
|
+
.map((command) => command.trim())
|
|
33
|
+
.filter(Boolean);
|
|
34
|
+
for (const command of commands) {
|
|
35
|
+
const validation = validateVerificationCommand(command);
|
|
36
|
+
if (!validation.ok) {
|
|
37
|
+
results.push({
|
|
38
|
+
category: "tool",
|
|
39
|
+
target: `${task.id} Verify`,
|
|
40
|
+
passed: false,
|
|
41
|
+
message: `Unsafe or non-runnable Verify command: ${command} (${validation.reason})`,
|
|
42
|
+
blocking: true,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return results;
|
|
48
|
+
}
|
|
23
49
|
// ─── Package Existence Check ─────────────────────────────────────────────────
|
|
24
50
|
/**
|
|
25
51
|
* Extract npm package names from task descriptions.
|
|
@@ -81,7 +107,7 @@ export function extractPackageReferences(description) {
|
|
|
81
107
|
while ((importMatch = importPattern.exec(description)) !== null) {
|
|
82
108
|
// Skip relative imports and node builtins
|
|
83
109
|
const pkg = importMatch[1];
|
|
84
|
-
if (!pkg.startsWith(".") && !pkg.startsWith("node:")) {
|
|
110
|
+
if (!pkg.startsWith(".") && !pkg.startsWith("node:") && !pkg.startsWith("@/")) {
|
|
85
111
|
packages.add(normalizePackageName(pkg));
|
|
86
112
|
}
|
|
87
113
|
}
|
|
@@ -292,7 +318,7 @@ function extractPathFromAnnotation(raw) {
|
|
|
292
318
|
if (quoteMatch) {
|
|
293
319
|
return quoteMatch[2].trim();
|
|
294
320
|
}
|
|
295
|
-
const annotatedMatch = trimmed.match(/^(.+?)
|
|
321
|
+
const annotatedMatch = trimmed.match(/^(.+?)(?:\s+[—–-]\s+.+|\s+\([^()]+\))$/);
|
|
296
322
|
if (annotatedMatch) {
|
|
297
323
|
const prefix = annotatedMatch[1].trim();
|
|
298
324
|
const prefixBacktickMatch = prefix.match(/`([^`]+)`/);
|
|
@@ -357,6 +383,14 @@ function isRuntimeOnlyInput(raw) {
|
|
|
357
383
|
function containsGlobPattern(candidate) {
|
|
358
384
|
return ["*", "?", "[", "]", "{", "}"].some((char) => candidate.includes(char));
|
|
359
385
|
}
|
|
386
|
+
function toComparisonPath(filePath, basePath) {
|
|
387
|
+
const normalized = normalizeFilePath(filePath);
|
|
388
|
+
if (!isAbsolute(normalized))
|
|
389
|
+
return normalized;
|
|
390
|
+
const normalizedBasePath = normalizeFilePath(basePath);
|
|
391
|
+
const rel = normalizeFilePath(relative(normalizedBasePath, normalized));
|
|
392
|
+
return rel && !rel.startsWith("..") && rel !== "." ? rel : normalized;
|
|
393
|
+
}
|
|
360
394
|
/**
|
|
361
395
|
* Build a set of files that will be created by tasks up to (but not including) taskIndex.
|
|
362
396
|
* Also includes outputs of completed tasks at any position — a completed task has already
|
|
@@ -389,21 +423,22 @@ function getExpectedOutputsUpTo(tasks, taskIndex) {
|
|
|
389
423
|
*
|
|
390
424
|
* All paths are normalized before comparison to ensure ./src/a.ts matches src/a.ts.
|
|
391
425
|
*/
|
|
392
|
-
export function checkFilePathConsistency(tasks, basePath) {
|
|
426
|
+
export function checkFilePathConsistency(tasks, basePath, context) {
|
|
393
427
|
const results = [];
|
|
428
|
+
const resolutionRoots = [basePath, ...(context?.additionalRoots ?? [])];
|
|
394
429
|
// Build a set of all files created by any task at any position (normalized).
|
|
395
430
|
// Used to suppress consistency errors for files that will be caught with a
|
|
396
431
|
// more precise message by checkTaskOrdering (sequence violation).
|
|
397
432
|
const allTaskOutputs = new Set();
|
|
398
433
|
for (const t of tasks) {
|
|
399
434
|
for (const f of t.expected_output) {
|
|
400
|
-
allTaskOutputs.add(
|
|
435
|
+
allTaskOutputs.add(toComparisonPath(f, basePath));
|
|
401
436
|
}
|
|
402
437
|
}
|
|
403
438
|
for (let i = 0; i < tasks.length; i++) {
|
|
404
439
|
const task = tasks[i];
|
|
405
|
-
const priorOutputs = getExpectedOutputsUpTo(tasks, i);
|
|
406
|
-
const ownOutputs = new Set(task.expected_output.map(
|
|
440
|
+
const priorOutputs = new Set(Array.from(getExpectedOutputsUpTo(tasks, i), (filePath) => toComparisonPath(filePath, basePath)));
|
|
441
|
+
const ownOutputs = new Set(task.expected_output.map((filePath) => toComparisonPath(filePath, basePath)));
|
|
407
442
|
const filesToCheck = [...task.inputs];
|
|
408
443
|
for (const file of filesToCheck) {
|
|
409
444
|
// Skip empty strings
|
|
@@ -412,12 +447,11 @@ export function checkFilePathConsistency(tasks, basePath) {
|
|
|
412
447
|
if (!shouldValidateInputAsPath(file))
|
|
413
448
|
continue;
|
|
414
449
|
// Normalize path for consistent comparison
|
|
415
|
-
const normalizedFile =
|
|
450
|
+
const normalizedFile = toComparisonPath(file, basePath);
|
|
416
451
|
if (containsGlobPattern(normalizedFile))
|
|
417
452
|
continue;
|
|
418
453
|
// Check if file exists on disk
|
|
419
|
-
const
|
|
420
|
-
const existsOnDisk = existsSync(absolutePath);
|
|
454
|
+
const existsOnDisk = resolutionRoots.some((root) => existsSync(resolve(root, normalizedFile)));
|
|
421
455
|
// Check if file is in prior expected outputs (priorOutputs already normalized)
|
|
422
456
|
const inPriorOutputs = priorOutputs.has(normalizedFile);
|
|
423
457
|
const inOwnOutputs = ownOutputs.has(normalizedFile);
|
|
@@ -455,14 +489,15 @@ export function checkFilePathConsistency(tasks, basePath) {
|
|
|
455
489
|
*
|
|
456
490
|
* All paths are normalized before comparison to ensure ./src/a.ts matches src/a.ts.
|
|
457
491
|
*/
|
|
458
|
-
export function checkTaskOrdering(tasks, basePath) {
|
|
492
|
+
export function checkTaskOrdering(tasks, basePath, context) {
|
|
459
493
|
const results = [];
|
|
494
|
+
const resolutionRoots = [basePath, ...(context?.additionalRoots ?? [])];
|
|
460
495
|
// Build map: normalized file → task index that creates it
|
|
461
496
|
const fileCreators = new Map();
|
|
462
497
|
for (let i = 0; i < tasks.length; i++) {
|
|
463
498
|
const task = tasks[i];
|
|
464
499
|
for (const file of task.expected_output) {
|
|
465
|
-
const normalizedFile =
|
|
500
|
+
const normalizedFile = toComparisonPath(file, basePath);
|
|
466
501
|
const existing = fileCreators.get(normalizedFile);
|
|
467
502
|
if (!existing || (!existing.completed && task.status === "completed")) {
|
|
468
503
|
fileCreators.set(normalizedFile, {
|
|
@@ -485,7 +520,7 @@ export function checkTaskOrdering(tasks, basePath) {
|
|
|
485
520
|
continue;
|
|
486
521
|
if (!shouldValidateInputAsPath(file))
|
|
487
522
|
continue;
|
|
488
|
-
const normalizedFile =
|
|
523
|
+
const normalizedFile = toComparisonPath(file, basePath);
|
|
489
524
|
if (containsGlobPattern(normalizedFile))
|
|
490
525
|
continue;
|
|
491
526
|
// A directory reference like `artifacts/M009-S03/` is never a concrete
|
|
@@ -494,8 +529,7 @@ export function checkTaskOrdering(tasks, basePath) {
|
|
|
494
529
|
if (isDirectoryReference(file))
|
|
495
530
|
continue;
|
|
496
531
|
const creator = fileCreators.get(normalizedFile);
|
|
497
|
-
const
|
|
498
|
-
const existsOnDisk = existsSync(absolutePath);
|
|
532
|
+
const existsOnDisk = resolutionRoots.some((root) => existsSync(resolve(root, normalizedFile)));
|
|
499
533
|
// Skip if the creating task has already completed — its output is available
|
|
500
534
|
// regardless of disk state (e.g. file was a temp artifact cleaned up after
|
|
501
535
|
// the task ran, or a replan introduced a new earlier-sequence task that
|
|
@@ -640,14 +674,15 @@ export function checkInterfaceContracts(tasks, _basePath) {
|
|
|
640
674
|
* @param basePath - Base path for resolving file references
|
|
641
675
|
* @returns PreExecutionResult with status, checks, and duration
|
|
642
676
|
*/
|
|
643
|
-
export async function runPreExecutionChecks(tasks, basePath) {
|
|
677
|
+
export async function runPreExecutionChecks(tasks, basePath, context) {
|
|
644
678
|
const startTime = Date.now();
|
|
645
679
|
const allChecks = [];
|
|
646
680
|
// Run sync checks first
|
|
647
|
-
const fileChecks = checkFilePathConsistency(tasks, basePath);
|
|
648
|
-
const orderingChecks = checkTaskOrdering(tasks, basePath);
|
|
681
|
+
const fileChecks = checkFilePathConsistency(tasks, basePath, context);
|
|
682
|
+
const orderingChecks = checkTaskOrdering(tasks, basePath, context);
|
|
649
683
|
const contractChecks = checkInterfaceContracts(tasks, basePath);
|
|
650
|
-
|
|
684
|
+
const verificationChecks = checkVerificationCommands(tasks);
|
|
685
|
+
allChecks.push(...fileChecks, ...orderingChecks, ...contractChecks, ...verificationChecks);
|
|
651
686
|
// Run async package checks
|
|
652
687
|
const packageChecks = await checkPackageExistence(tasks, basePath);
|
|
653
688
|
allChecks.push(...packageChecks);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve MCP server config for a given model ID using longest-prefix-wins matching.
|
|
3
|
+
*
|
|
4
|
+
* Keys in config.per_model are model-ID prefixes. When modelId.startsWith(key),
|
|
5
|
+
* the key is a candidate; the longest matching key wins. Returns undefined when
|
|
6
|
+
* no key matches or per_model is empty.
|
|
7
|
+
*/
|
|
8
|
+
export function resolveModelMcpConfig(modelId, config) {
|
|
9
|
+
let bestKey;
|
|
10
|
+
const perModel = config.per_model ?? {};
|
|
11
|
+
for (const key of Object.keys(perModel)) {
|
|
12
|
+
if (modelId.startsWith(key)) {
|
|
13
|
+
if (bestKey === undefined || key.length > bestKey.length) {
|
|
14
|
+
bestKey = key;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return bestKey !== undefined ? perModel[bestKey] : undefined;
|
|
19
|
+
}
|
|
@@ -29,9 +29,10 @@ export function resolveModelForUnit(unitType) {
|
|
|
29
29
|
*/
|
|
30
30
|
export function resolveModelWithFallbacksForUnit(unitType) {
|
|
31
31
|
const prefs = loadEffectiveGSDPreferences(undefined, { availableModelIds: [] });
|
|
32
|
-
|
|
32
|
+
const models = prefs?.preferences?.models;
|
|
33
|
+
if (!models)
|
|
33
34
|
return undefined;
|
|
34
|
-
const m =
|
|
35
|
+
const m = models;
|
|
35
36
|
let phaseConfig;
|
|
36
37
|
switch (unitType) {
|
|
37
38
|
case "research-milestone":
|
|
@@ -128,9 +129,10 @@ export function resolveModelWithFallbacksForUnit(unitType) {
|
|
|
128
129
|
*/
|
|
129
130
|
export function resolveDefaultSessionModel(sessionProvider) {
|
|
130
131
|
const prefs = loadEffectiveGSDPreferences(undefined, { availableModelIds: [] });
|
|
131
|
-
|
|
132
|
+
const models = prefs?.preferences?.models;
|
|
133
|
+
if (!models)
|
|
132
134
|
return undefined;
|
|
133
|
-
const m =
|
|
135
|
+
const m = models;
|
|
134
136
|
// Priority: execution → planning → first configured value
|
|
135
137
|
const candidates = [
|
|
136
138
|
m.execution,
|
|
@@ -71,6 +71,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
|
|
|
71
71
|
"verification_commands",
|
|
72
72
|
"verification_auto_fix",
|
|
73
73
|
"verification_max_retries",
|
|
74
|
+
"per_unit_cost_cap_usd",
|
|
74
75
|
"search_provider",
|
|
75
76
|
"context_selection",
|
|
76
77
|
"widget_mode",
|
|
@@ -99,6 +100,8 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
|
|
|
99
100
|
"context_window_override",
|
|
100
101
|
"context_mode",
|
|
101
102
|
"planning_depth",
|
|
103
|
+
"claude_code_mcp",
|
|
104
|
+
"workspace",
|
|
102
105
|
]);
|
|
103
106
|
/**
|
|
104
107
|
* Broad union of every recognized unit-type *label* used across the codebase.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Accepts a raw GSDPreferences object and returns a sanitized copy
|
|
6
6
|
* together with any errors and warnings.
|
|
7
7
|
*/
|
|
8
|
+
import { isAbsolute } from "node:path";
|
|
8
9
|
import { VALID_BRANCH_NAME } from "./git-service.js";
|
|
9
10
|
import { normalizeStringArray } from "../shared/format-utils.js";
|
|
10
11
|
import { KNOWN_PREFERENCE_KEYS, KNOWN_UNIT_LABELS, SKILL_ACTIONS, } from "./preferences-types.js";
|
|
@@ -949,6 +950,15 @@ export function validatePreferences(preferences) {
|
|
|
949
950
|
errors.push("verification_max_retries must be a non-negative number");
|
|
950
951
|
}
|
|
951
952
|
}
|
|
953
|
+
if (preferences.per_unit_cost_cap_usd !== undefined) {
|
|
954
|
+
const raw = preferences.per_unit_cost_cap_usd;
|
|
955
|
+
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) {
|
|
956
|
+
validated.per_unit_cost_cap_usd = raw;
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
errors.push("per_unit_cost_cap_usd must be a positive number");
|
|
960
|
+
}
|
|
961
|
+
}
|
|
952
962
|
// ─── Git Preferences ───────────────────────────────────────────────────
|
|
953
963
|
if (preferences.git && typeof preferences.git === "object") {
|
|
954
964
|
const git = {};
|
|
@@ -1264,6 +1274,143 @@ export function validatePreferences(preferences) {
|
|
|
1264
1274
|
errors.push("codebase must be an object");
|
|
1265
1275
|
}
|
|
1266
1276
|
}
|
|
1277
|
+
// ─── Claude Code MCP Per-Model Config ───────────────────────────────────────
|
|
1278
|
+
if (preferences.claude_code_mcp !== undefined) {
|
|
1279
|
+
if (typeof preferences.claude_code_mcp === "object" && preferences.claude_code_mcp !== null) {
|
|
1280
|
+
const raw = preferences.claude_code_mcp;
|
|
1281
|
+
if (typeof raw.per_model !== "object" || raw.per_model === null || Array.isArray(raw.per_model)) {
|
|
1282
|
+
warnings.push("claude_code_mcp.per_model must be an object — ignoring claude_code_mcp");
|
|
1283
|
+
}
|
|
1284
|
+
else {
|
|
1285
|
+
const perModel = raw.per_model;
|
|
1286
|
+
const validPerModel = {};
|
|
1287
|
+
for (const [prefix, entry] of Object.entries(perModel)) {
|
|
1288
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
1289
|
+
warnings.push(`claude_code_mcp.per_model["${prefix}"] must be an object — ignoring entry`);
|
|
1290
|
+
continue;
|
|
1291
|
+
}
|
|
1292
|
+
const e = entry;
|
|
1293
|
+
const validEntry = {};
|
|
1294
|
+
for (const field of ["allowed_servers", "blocked_servers"]) {
|
|
1295
|
+
if (e[field] !== undefined) {
|
|
1296
|
+
if (Array.isArray(e[field]) && e[field].every((s) => typeof s === "string")) {
|
|
1297
|
+
validEntry[field] = e[field];
|
|
1298
|
+
}
|
|
1299
|
+
else {
|
|
1300
|
+
warnings.push(`claude_code_mcp.per_model["${prefix}"].${field} must be an array of strings — ignoring field`);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
validPerModel[prefix] = validEntry;
|
|
1305
|
+
}
|
|
1306
|
+
validated.claude_code_mcp = { per_model: validPerModel };
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
else {
|
|
1310
|
+
warnings.push("claude_code_mcp must be an object — ignoring");
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
// ─── Workspace Repository Registry ─────────────────────────────────
|
|
1314
|
+
if (preferences.workspace !== undefined) {
|
|
1315
|
+
if (typeof preferences.workspace === "object" && preferences.workspace !== null && !Array.isArray(preferences.workspace)) {
|
|
1316
|
+
const workspace = preferences.workspace;
|
|
1317
|
+
const validWorkspace = {};
|
|
1318
|
+
if (workspace.mode !== undefined) {
|
|
1319
|
+
if (workspace.mode === "project" || workspace.mode === "parent") {
|
|
1320
|
+
validWorkspace.mode = workspace.mode;
|
|
1321
|
+
}
|
|
1322
|
+
else {
|
|
1323
|
+
errors.push('workspace.mode must be one of: project, parent');
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
if (workspace.repositories !== undefined) {
|
|
1327
|
+
if (typeof workspace.repositories === "object" &&
|
|
1328
|
+
workspace.repositories !== null &&
|
|
1329
|
+
!Array.isArray(workspace.repositories)) {
|
|
1330
|
+
const repos = workspace.repositories;
|
|
1331
|
+
const validRepos = {};
|
|
1332
|
+
const normalizedPaths = new Set();
|
|
1333
|
+
for (const [repoId, repoValue] of Object.entries(repos)) {
|
|
1334
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(repoId)) {
|
|
1335
|
+
errors.push(`workspace.repositories key "${repoId}" must match /^[A-Za-z0-9][A-Za-z0-9._-]*$/`);
|
|
1336
|
+
continue;
|
|
1337
|
+
}
|
|
1338
|
+
if (typeof repoValue !== "object" || repoValue === null || Array.isArray(repoValue)) {
|
|
1339
|
+
errors.push(`workspace.repositories.${repoId} must be an object`);
|
|
1340
|
+
continue;
|
|
1341
|
+
}
|
|
1342
|
+
const repo = repoValue;
|
|
1343
|
+
const validRepo = { path: "" };
|
|
1344
|
+
if (typeof repo.path === "string" && repo.path.trim().length > 0) {
|
|
1345
|
+
validRepo.path = repo.path.trim();
|
|
1346
|
+
if (isAbsolute(validRepo.path)) {
|
|
1347
|
+
errors.push(`workspace.repositories.${repoId}.path must be a relative path`);
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
const normalizedPathKey = validRepo.path.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
1351
|
+
if (normalizedPaths.has(normalizedPathKey)) {
|
|
1352
|
+
errors.push(`workspace.repositories contains duplicate path: ${validRepo.path}`);
|
|
1353
|
+
continue;
|
|
1354
|
+
}
|
|
1355
|
+
normalizedPaths.add(normalizedPathKey);
|
|
1356
|
+
}
|
|
1357
|
+
else {
|
|
1358
|
+
errors.push(`workspace.repositories.${repoId}.path must be a non-empty string`);
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
if (repo.role !== undefined) {
|
|
1362
|
+
if (typeof repo.role === "string" && repo.role.trim().length > 0)
|
|
1363
|
+
validRepo.role = repo.role.trim();
|
|
1364
|
+
else
|
|
1365
|
+
errors.push(`workspace.repositories.${repoId}.role must be a non-empty string`);
|
|
1366
|
+
}
|
|
1367
|
+
if (repo.verification !== undefined) {
|
|
1368
|
+
if (Array.isArray(repo.verification) &&
|
|
1369
|
+
repo.verification.every((v) => typeof v === "string" && v.trim().length > 0)) {
|
|
1370
|
+
validRepo.verification = repo.verification.map((v) => v.trim());
|
|
1371
|
+
}
|
|
1372
|
+
else {
|
|
1373
|
+
errors.push(`workspace.repositories.${repoId}.verification must be an array of non-empty strings`);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
if (repo.commit_policy !== undefined) {
|
|
1377
|
+
if (repo.commit_policy === "auto" || repo.commit_policy === "skip") {
|
|
1378
|
+
validRepo.commit_policy = repo.commit_policy;
|
|
1379
|
+
}
|
|
1380
|
+
else {
|
|
1381
|
+
errors.push(`workspace.repositories.${repoId}.commit_policy must be one of: auto, skip`);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
const knownRepoKeys = new Set(["path", "role", "verification", "commit_policy"]);
|
|
1385
|
+
for (const key of Object.keys(repo)) {
|
|
1386
|
+
if (!knownRepoKeys.has(key)) {
|
|
1387
|
+
warnings.push(`unknown workspace.repositories.${repoId} key "${key}" — ignored`);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
validRepos[repoId] = validRepo;
|
|
1391
|
+
}
|
|
1392
|
+
if (Object.keys(validRepos).length > 0) {
|
|
1393
|
+
validWorkspace.repositories = validRepos;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
else {
|
|
1397
|
+
errors.push("workspace.repositories must be an object mapping repo ids to config");
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
const knownWorkspaceKeys = new Set(["mode", "repositories"]);
|
|
1401
|
+
for (const key of Object.keys(workspace)) {
|
|
1402
|
+
if (!knownWorkspaceKeys.has(key)) {
|
|
1403
|
+
warnings.push(`unknown workspace key "${key}" — ignored`);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
if (Object.keys(validWorkspace).length > 0) {
|
|
1407
|
+
validated.workspace = validWorkspace;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
else {
|
|
1411
|
+
errors.push("workspace must be an object");
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1267
1414
|
// ─── Enhanced Verification ──────────────────────────────────────────────────
|
|
1268
1415
|
if (preferences.enhanced_verification !== undefined) {
|
|
1269
1416
|
if (typeof preferences.enhanced_verification === "boolean") {
|
|
@@ -38,6 +38,8 @@ export function resolveSkillStalenessDays(basePath) {
|
|
|
38
38
|
}
|
|
39
39
|
// ─── Re-exports: models ─────────────────────────────────────────────────────
|
|
40
40
|
export { resolveModelForUnit, resolveModelWithFallbacksForUnit, getNextFallbackModel, isTransientNetworkError, validateModelId, updatePreferencesModels, resolveDynamicRoutingConfig, resolveAutoSupervisorConfig, resolveProfileDefaults, getProfileTierMap, resolveEffectiveProfile, resolveInlineLevel, resolveContextSelection, resolveSearchProviderFromPreferences, resolveDisabledModelProvidersFromPreferences, } from "./preferences-models.js";
|
|
41
|
+
// ─── Re-exports: MCP ────────────────────────────────────────────────────────
|
|
42
|
+
export { resolveModelMcpConfig } from "./preferences-mcp.js";
|
|
41
43
|
// ─── Path Constants & Getters ───────────────────────────────────────────────
|
|
42
44
|
function globalPreferencesPath() {
|
|
43
45
|
return join(gsdHome(), "PREFERENCES.md");
|
|
@@ -65,6 +67,35 @@ export function getLegacyGlobalGSDPreferencesPath() {
|
|
|
65
67
|
export function getProjectGSDPreferencesPath(basePath) {
|
|
66
68
|
return projectPreferencesPath(basePath);
|
|
67
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Normalize a value loaded from disk (or passed from another component) into
|
|
72
|
+
* a plain, mutable bare preferences object.
|
|
73
|
+
*
|
|
74
|
+
* Accepts:
|
|
75
|
+
* - a `LoadedGSDPreferences` wrapper (`{ path, scope, preferences, ... }`)
|
|
76
|
+
* - a bare `GSDPreferences` object
|
|
77
|
+
* - `null` / `undefined` / any malformed value
|
|
78
|
+
*
|
|
79
|
+
* Returns a fresh `Record<string, unknown>` so callers may spread additional
|
|
80
|
+
* values without mutating the input. This is the single boundary the
|
|
81
|
+
* preferences wizard funnels existing-on-disk data through, so missing or
|
|
82
|
+
* partially-formed preference shapes can no longer reach code that assumes
|
|
83
|
+
* a fully-populated wrapper.
|
|
84
|
+
*/
|
|
85
|
+
export function normalizePreferencesShape(loaded) {
|
|
86
|
+
if (!loaded || typeof loaded !== "object")
|
|
87
|
+
return {};
|
|
88
|
+
const obj = loaded;
|
|
89
|
+
// Wrapper shape (`LoadedGSDPreferences`) carries the nested preferences
|
|
90
|
+
// under a `.preferences` key. Bare `GSDPreferences` never declares one
|
|
91
|
+
// (see preferences-types.ts), so the presence of that key is a reliable
|
|
92
|
+
// discriminator. Tolerate `preferences: undefined` by falling through to
|
|
93
|
+
// the empty-object return below.
|
|
94
|
+
const candidate = "preferences" in obj ? obj.preferences : obj;
|
|
95
|
+
if (!candidate || typeof candidate !== "object")
|
|
96
|
+
return {};
|
|
97
|
+
return { ...candidate };
|
|
98
|
+
}
|
|
68
99
|
// ─── Loading ────────────────────────────────────────────────────────────────
|
|
69
100
|
export function loadGlobalGSDPreferences() {
|
|
70
101
|
return loadPreferencesFile(globalPreferencesPath(), "global")
|
|
@@ -272,6 +303,10 @@ export function applyModeDefaults(mode, prefs) {
|
|
|
272
303
|
}
|
|
273
304
|
function mergePreferences(base, override) {
|
|
274
305
|
return {
|
|
306
|
+
// Preserve validated preference keys that do not need custom merge logic.
|
|
307
|
+
// The explicit fields below still own defaults, arrays, and deep merges.
|
|
308
|
+
...base,
|
|
309
|
+
...override,
|
|
275
310
|
version: override.version ?? base.version,
|
|
276
311
|
mode: override.mode ?? base.mode,
|
|
277
312
|
always_use_skills: mergeStringLists(base.always_use_skills, override.always_use_skills),
|
|
@@ -181,7 +181,7 @@ export function loadPrompt(name, vars = {}) {
|
|
|
181
181
|
.map(m => m.slice(2, -2))
|
|
182
182
|
.filter(key => !(key in effectiveVars));
|
|
183
183
|
if (missing.length > 0) {
|
|
184
|
-
throw new GSDError(GSD_PARSE_ERROR, `loadPrompt("${name}"): template declares {{${missing.join("}}, {{")}}}
|
|
184
|
+
throw new GSDError(GSD_PARSE_ERROR, `loadPrompt("${name}"): template declares {{${missing.join("}}, {{")}}} but no value was provided. ` +
|
|
185
185
|
`This usually means the extension code in memory is older than the template on disk. ` +
|
|
186
186
|
`Restart pi to reload the extension.`);
|
|
187
187
|
}
|
|
@@ -57,7 +57,7 @@ Subagents report only; they do not write user source. Fold any findings into Dec
|
|
|
57
57
|
**Success path** (all verifications passed):
|
|
58
58
|
|
|
59
59
|
10. For each requirement whose status changed in step 9, call `gsd_requirement_update` with the requirement ID and updated `status` and `validation` fields — the tool regenerates `.gsd/REQUIREMENTS.md` automatically. Do this BEFORE completing the milestone so requirement updates are persisted.
|
|
60
|
-
11.
|
|
60
|
+
11. Refresh the project state through `gsd_summary_save` with `artifact_type: "PROJECT"` and the full updated project markdown as `content`; omit `milestone_id`. The tool persists the DB-backed PROJECT artifact and renders `.gsd/PROJECT.md`. Do not write or edit `.gsd/PROJECT.md` directly.
|
|
61
61
|
12. Extract structured learnings from this milestone and persist them to the GSD memory store. Follow the procedure block immediately below — it writes `{{milestoneId}}-LEARNINGS.md` as the audit trail and persists Patterns, Lessons, and Decisions via `capture_thought` (categories: pattern, gotcha/convention, architecture). The memory store is the single source of truth for cross-session durable knowledge (ADR-013).
|
|
62
62
|
|
|
63
63
|
{{extractLearningsSteps}}
|
|
@@ -34,7 +34,7 @@ Use `subagent` only for fresh-context review when useful: reviewer for cross-cut
|
|
|
34
34
|
12. Review the inlined task-summary excerpts for DECISIONS.md and KNOWLEDGE.md-worthy decisions, patterns, and gotchas. Read full `*-SUMMARY.md` files only when an excerpt is absent, truncated, or lacks the specific evidence needed for the slice narrative. Capture significant items with `capture_thought`; do not append knowledge files directly.
|
|
35
35
|
13. When verification passes, call `gsd_slice_complete`. The DB-backed tool is the canonical write path. Do **not** manually write `{{sliceSummaryPath}}`. Do **not** manually write `{{sliceUatPath}}`. Do not edit roadmap checkboxes; the tool renders files and updates projections.
|
|
36
36
|
14. Do not run git commands.
|
|
37
|
-
15.
|
|
37
|
+
15. If the current project state needs refresh, call `gsd_summary_save` with `artifact_type: "PROJECT"` and the full updated project markdown as `content`; omit `milestone_id`. Do not write or edit `.gsd/PROJECT.md` directly.
|
|
38
38
|
|
|
39
39
|
**Autonomous execution:** no human is available. Do not call `ask_user_questions` or `secure_env_collect`; make reasonable assumptions and document them.
|
|
40
40
|
|
|
@@ -106,8 +106,8 @@ Directories use bare IDs. Files use ID-SUFFIX format. Titles live inside content
|
|
|
106
106
|
|
|
107
107
|
In a single pass:
|
|
108
108
|
1. `mkdir -p .gsd/milestones/{{milestoneId}}/slices`
|
|
109
|
-
2.
|
|
110
|
-
3.
|
|
109
|
+
2. Call `gsd_summary_save` with `artifact_type: "PROJECT"` and full Project template content. The tool persists the DB-backed PROJECT artifact and renders `.gsd/PROJECT.md`. Describe what the project is, its current state, and list the milestone sequence.
|
|
110
|
+
3. Persist requirements with `gsd_requirement_save` or `gsd_requirement_update`, then call `gsd_summary_save` with `artifact_type: "REQUIREMENTS"` so the tool renders `.gsd/REQUIREMENTS.md` from DB rows. Confirm states, ownership, and traceability before roadmap creation.
|
|
111
111
|
|
|
112
112
|
**Depth-Preservation Guidance for context.md:** Preserve the specification's exact terminology, emphasis, and framing. Do not flatten domain-specific language into generics. CONTEXT.md is downstream agents' only window into this spec.
|
|
113
113
|
|
|
@@ -120,8 +120,8 @@ In a single pass:
|
|
|
120
120
|
|
|
121
121
|
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
122
122
|
|
|
123
|
-
- [ ]
|
|
124
|
-
- [ ]
|
|
123
|
+
- [ ] Called `gsd_summary_save` for the PROJECT artifact (step 2)
|
|
124
|
+
- [ ] Persisted requirements and called `gsd_summary_save` for the REQUIREMENTS artifact (step 3)
|
|
125
125
|
- [ ] Written `{{contextPath}}` (step 4)
|
|
126
126
|
- [ ] Called `gsd_plan_milestone` (step 5)
|
|
127
127
|
|
|
@@ -145,8 +145,8 @@ Next steps:
|
|
|
145
145
|
#### Phase 1: Shared artifacts
|
|
146
146
|
|
|
147
147
|
1. For each milestone, call `gsd_milestone_generate_id`; never invent IDs. Then `mkdir -p .gsd/milestones/<ID>/slices`.
|
|
148
|
-
2.
|
|
149
|
-
3.
|
|
148
|
+
2. Call `gsd_summary_save` with `artifact_type: "PROJECT"` and full Project template content so the tool persists the DB-backed PROJECT artifact and renders `.gsd/PROJECT.md`.
|
|
149
|
+
3. Persist requirements with `gsd_requirement_save` or `gsd_requirement_update`, then call `gsd_summary_save` with `artifact_type: "REQUIREMENTS"` so the tool renders `.gsd/REQUIREMENTS.md` from DB rows. Capture Active, Deferred, Out of Scope, and any already Validated requirements. Later milestones may have provisional ownership where slice plans do not exist yet.
|
|
150
150
|
4. For any architectural or pattern decisions, call `gsd_decision_save` — the tool auto-assigns IDs and regenerates `.gsd/DECISIONS.md` automatically.
|
|
151
151
|
|
|
152
152
|
#### Phase 2: Primary milestone
|
|
@@ -214,8 +214,8 @@ For single-milestone projects, do NOT write this file.
|
|
|
214
214
|
|
|
215
215
|
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
216
216
|
|
|
217
|
-
- [ ]
|
|
218
|
-
- [ ]
|
|
217
|
+
- [ ] Called `gsd_summary_save` for the PROJECT artifact
|
|
218
|
+
- [ ] Persisted requirements and called `gsd_summary_save` for the REQUIREMENTS artifact
|
|
219
219
|
- [ ] Written the primary milestone `CONTEXT.md`
|
|
220
220
|
- [ ] Called `gsd_plan_milestone` for the primary milestone
|
|
221
221
|
- [ ] Written `.gsd/DISCUSSION-MANIFEST.json` with `gates_completed === total`
|