gsd-pi 2.73.1-dev.d987996 → 2.74.0-dev.0306a2e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-web-branch.d.ts +4 -3
- package/dist/cli-web-branch.js +10 -7
- package/dist/cli.js +184 -206
- package/dist/headless-query.js +4 -1
- package/dist/help-text.js +23 -0
- package/dist/logo.d.ts +1 -1
- package/dist/logo.js +1 -1
- package/dist/onboarding.js +59 -53
- package/dist/resource-loader.js +2 -2
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +68 -4
- package/dist/resources/extensions/gsd/activity-log.js +16 -0
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
- package/dist/resources/extensions/gsd/auto/loop.js +147 -10
- package/dist/resources/extensions/gsd/auto/phases.js +173 -13
- package/dist/resources/extensions/gsd/auto/session.js +10 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +22 -4
- package/dist/resources/extensions/gsd/auto-model-selection.js +105 -16
- package/dist/resources/extensions/gsd/auto-post-unit.js +254 -15
- package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
- package/dist/resources/extensions/gsd/auto-start.js +23 -6
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +13 -0
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
- package/dist/resources/extensions/gsd/auto-verification.js +186 -3
- package/dist/resources/extensions/gsd/auto.js +65 -12
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +30 -8
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +41 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +26 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +25 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
- package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
- package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
- package/dist/resources/extensions/gsd/commands-do.js +79 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +8 -2
- package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
- package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
- package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
- package/dist/resources/extensions/gsd/commands-ship.js +187 -0
- package/dist/resources/extensions/gsd/db-writer.js +3 -5
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +15 -2
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
- package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
- package/dist/resources/extensions/gsd/git-service.js +49 -1
- package/dist/resources/extensions/gsd/graph-context.js +157 -0
- package/dist/resources/extensions/gsd/gsd-db.js +581 -2
- package/dist/resources/extensions/gsd/guided-flow.js +23 -0
- package/dist/resources/extensions/gsd/index.js +15 -2
- package/dist/resources/extensions/gsd/init-wizard.js +1 -0
- package/dist/resources/extensions/gsd/journal.js +27 -0
- package/dist/resources/extensions/gsd/md-importer.js +3 -4
- package/dist/resources/extensions/gsd/memory-store.js +19 -51
- package/dist/resources/extensions/gsd/metrics.js +19 -0
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
- package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
- package/dist/resources/extensions/gsd/notification-widget.js +2 -2
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
- package/dist/resources/extensions/gsd/preferences-models.js +63 -3
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +130 -2
- package/dist/resources/extensions/gsd/preferences.js +26 -0
- package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
- package/dist/resources/extensions/gsd/state.js +66 -15
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
- package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
- package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
- package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
- package/dist/resources/extensions/gsd/uok/audit.js +40 -0
- package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
- package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
- package/dist/resources/extensions/gsd/uok/flags.js +29 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
- package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
- package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
- package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
- package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
- package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
- package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
- package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -0
- package/dist/update-check.d.ts +1 -0
- package/dist/update-check.js +13 -5
- package/dist/update-cmd.js +4 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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/onboarding/route.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/resize/route.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/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- 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/package.json +3 -3
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/index.d.ts +3 -0
- package/packages/mcp-server/dist/index.d.ts.map +1 -1
- package/packages/mcp-server/dist/index.js +3 -0
- package/packages/mcp-server/dist/index.js.map +1 -1
- package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
- package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/graph.js +655 -0
- package/packages/mcp-server/dist/readers/graph.js.map +1 -0
- package/packages/mcp-server/dist/readers/index.d.ts +2 -0
- package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
- package/packages/mcp-server/dist/readers/index.js +1 -0
- package/packages/mcp-server/dist/readers/index.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +65 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/index.ts +15 -0
- package/packages/mcp-server/src/readers/graph.test.ts +604 -0
- package/packages/mcp-server/src/readers/graph.ts +855 -0
- package/packages/mcp-server/src/readers/index.ts +12 -0
- package/packages/mcp-server/src/server.ts +83 -0
- package/packages/mcp-server/tsconfig.json +1 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
- package/packages/native/package.json +2 -2
- package/packages/native/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.json +1 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-ai/dist/index.d.ts +2 -9
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +2 -9
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/capability-patches.js +36 -0
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
- package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
- package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
- package/packages/pi-ai/dist/models/custom.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
- package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
- package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
- package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
- package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
- package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google.js +464 -0
- package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
- package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/groq.js +311 -0
- package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
- package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
- package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
- package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
- package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
- package/packages/pi-ai/dist/models/generated/index.js +51 -0
- package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
- package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
- package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
- package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai.js +702 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
- package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
- package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
- package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
- package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
- package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/xai.js +413 -0
- package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
- package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/zai.js +239 -0
- package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
- package/packages/pi-ai/dist/models/index.d.ts +27 -0
- package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/index.js +80 -0
- package/packages/pi-ai/dist/models/index.js.map +1 -0
- package/packages/pi-ai/dist/models.d.ts +1 -36
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +1 -2
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.js +3 -112
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +6 -5
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/overflow.js +12 -0
- package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.js +50 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +74 -40
- package/packages/pi-ai/src/index.ts +5 -9
- package/packages/pi-ai/src/models/capability-patches.ts +40 -0
- package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
- package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
- package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
- package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
- package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
- package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
- package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
- package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
- package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
- package/packages/pi-ai/src/models/generated/google.ts +466 -0
- package/packages/pi-ai/src/models/generated/groq.ts +313 -0
- package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
- package/packages/pi-ai/src/models/generated/index.ts +52 -0
- package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
- package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
- package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
- package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
- package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
- package/packages/pi-ai/src/models/generated/openai.ts +704 -0
- package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
- package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
- package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
- package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
- package/packages/pi-ai/src/models/generated/xai.ts +415 -0
- package/packages/pi-ai/src/models/generated/zai.ts +241 -0
- package/packages/pi-ai/src/models/index.ts +106 -0
- package/packages/pi-ai/src/models.generated.test.ts +1 -2
- package/packages/pi-ai/src/models.test.ts +6 -5
- package/packages/pi-ai/src/models.ts +3 -153
- package/packages/pi-ai/src/utils/overflow.ts +14 -1
- package/packages/pi-ai/src/utils/tests/overflow.test.ts +58 -0
- package/packages/pi-ai/tsconfig.json +1 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +721 -8
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +5 -5
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +45 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
- package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +12 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +65 -28
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts +2 -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 +9 -3
- 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.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +52 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -0
- 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 +305 -20
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +13 -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 +59 -6
- 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/chat-controller-ordering.test.ts +884 -8
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +5 -5
- package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +50 -0
- package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +78 -32
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +73 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +9 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +381 -39
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +79 -6
- package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
- package/packages/pi-coding-agent/tsconfig.json +3 -2
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +60 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +8 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +32 -3
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/tui.test.ts +76 -1
- package/packages/pi-tui/src/tui.ts +31 -3
- package/packages/pi-tui/tsconfig.json +1 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.json +1 -0
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +107 -5
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +111 -2
- package/src/resources/extensions/gsd/activity-log.ts +21 -0
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
- package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -0
- package/src/resources/extensions/gsd/auto/loop.ts +159 -10
- package/src/resources/extensions/gsd/auto/phases.ts +213 -13
- package/src/resources/extensions/gsd/auto/session.ts +10 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +26 -10
- package/src/resources/extensions/gsd/auto-model-selection.ts +151 -16
- package/src/resources/extensions/gsd/auto-post-unit.ts +278 -16
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
- package/src/resources/extensions/gsd/auto-start.ts +30 -6
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +17 -0
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
- package/src/resources/extensions/gsd/auto-verification.ts +225 -3
- package/src/resources/extensions/gsd/auto.ts +72 -16
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +38 -8
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +52 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +26 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +25 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
- package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
- package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
- package/src/resources/extensions/gsd/commands-do.ts +109 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +8 -2
- package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
- package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
- package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
- package/src/resources/extensions/gsd/commands-ship.ts +219 -0
- package/src/resources/extensions/gsd/db-writer.ts +3 -5
- package/src/resources/extensions/gsd/docs/preferences-reference.md +15 -2
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
- package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
- package/src/resources/extensions/gsd/git-service.ts +68 -0
- package/src/resources/extensions/gsd/graph-context.ts +212 -0
- package/src/resources/extensions/gsd/gsd-db.ts +788 -3
- package/src/resources/extensions/gsd/guided-flow.ts +32 -0
- package/src/resources/extensions/gsd/index.ts +18 -2
- package/src/resources/extensions/gsd/init-wizard.ts +3 -2
- package/src/resources/extensions/gsd/journal.ts +30 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -5
- package/src/resources/extensions/gsd/memory-store.ts +31 -62
- package/src/resources/extensions/gsd/metrics.ts +26 -0
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
- package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
- package/src/resources/extensions/gsd/notification-widget.ts +2 -2
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
- package/src/resources/extensions/gsd/preferences-models.ts +61 -3
- package/src/resources/extensions/gsd/preferences-types.ts +44 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +130 -2
- package/src/resources/extensions/gsd/preferences.ts +28 -0
- package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
- package/src/resources/extensions/gsd/session-lock.ts +14 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
- package/src/resources/extensions/gsd/state.ts +80 -17
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +9 -5
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +51 -2
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
- package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +68 -8
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +137 -1
- package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +91 -2
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +9 -6
- package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
- package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
- package/src/resources/extensions/gsd/types.ts +14 -1
- package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
- package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
- package/src/resources/extensions/gsd/uok/audit.ts +51 -0
- package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
- package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
- package/src/resources/extensions/gsd/uok/flags.ts +45 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
- package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
- package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
- package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
- package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
- package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
- package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
- package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
- package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
- package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
- package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
- package/packages/pi-ai/dist/models.custom.js.map +0 -1
- package/packages/pi-ai/dist/models.generated.js +0 -14343
- package/packages/pi-ai/dist/models.generated.js.map +0 -1
- package/packages/pi-ai/src/models.generated.ts +0 -14345
- /package/dist/web/standalone/.next/static/{cGmbVq2su4f9tMpgIkG8u → tqdo0yKKYz6fJXQnIgbdx}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{cGmbVq2su4f9tMpgIkG8u → tqdo0yKKYz6fJXQnIgbdx}/_ssgManifest.js +0 -0
|
@@ -10,11 +10,14 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
|
10
10
|
import type { GSDPreferences } from "./preferences.js";
|
|
11
11
|
import { resolveModelWithFallbacksForUnit, resolveDynamicRoutingConfig } from "./preferences.js";
|
|
12
12
|
import type { ComplexityTier } from "./complexity-classifier.js";
|
|
13
|
-
import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
|
|
13
|
+
import { classifyUnitComplexity, extractTaskMetadata, tierLabel } from "./complexity-classifier.js";
|
|
14
14
|
import { resolveModelForComplexity, escalateTier, getEligibleModels, loadCapabilityOverrides, adjustToolSet, filterToolsForProvider } from "./model-router.js";
|
|
15
15
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
16
16
|
import { unitPhaseLabel } from "./auto-dashboard.js";
|
|
17
17
|
import { getSessionModelOverride } from "./session-model-override.js";
|
|
18
|
+
import { logWarning } from "./workflow-logger.js";
|
|
19
|
+
import { resolveUokFlags } from "./uok/flags.js";
|
|
20
|
+
import { applyModelPolicyFilter } from "./uok/model-policy.js";
|
|
18
21
|
|
|
19
22
|
export interface ModelSelectionResult {
|
|
20
23
|
/** Routing metadata for metrics recording */
|
|
@@ -25,9 +28,7 @@ export interface ModelSelectionResult {
|
|
|
25
28
|
|
|
26
29
|
export function resolvePreferredModelConfig(
|
|
27
30
|
unitType: string,
|
|
28
|
-
autoModeStartModel: { provider: string; id: string } | null,
|
|
29
|
-
/** When false, only return explicit per-phase model configs — do not
|
|
30
|
-
* synthesize a routing ceiling from dynamic_routing.tier_models (#3962). */
|
|
31
|
+
autoModeStartModel: { provider: string; id: string; flatRateCtx?: FlatRateContext } | null,
|
|
31
32
|
isAutoMode = true,
|
|
32
33
|
) {
|
|
33
34
|
const explicitConfig = resolveModelWithFallbacksForUnit(unitType);
|
|
@@ -41,7 +42,7 @@ export function resolvePreferredModelConfig(
|
|
|
41
42
|
if (!routingConfig.enabled || !routingConfig.tier_models) return undefined;
|
|
42
43
|
|
|
43
44
|
// Don't synthesize a routing config for flat-rate providers (#3453).
|
|
44
|
-
if (autoModeStartModel && isFlatRateProvider(autoModeStartModel.provider)) return undefined;
|
|
45
|
+
if (autoModeStartModel && isFlatRateProvider(autoModeStartModel.provider, autoModeStartModel.flatRateCtx)) return undefined;
|
|
45
46
|
|
|
46
47
|
const ceilingModel = routingConfig.tier_models.heavy
|
|
47
48
|
?? (autoModeStartModel ? `${autoModeStartModel.provider}/${autoModeStartModel.id}` : undefined);
|
|
@@ -68,7 +69,7 @@ export async function selectAndApplyModel(
|
|
|
68
69
|
basePath: string,
|
|
69
70
|
prefs: GSDPreferences | undefined,
|
|
70
71
|
verbose: boolean,
|
|
71
|
-
autoModeStartModel: { provider: string; id: string } | null,
|
|
72
|
+
autoModeStartModel: { provider: string; id: string; flatRateCtx?: FlatRateContext } | null,
|
|
72
73
|
retryContext?: { isRetry: boolean; previousTier?: string },
|
|
73
74
|
/** When false (interactive/guided-flow), skip dynamic routing and use the session model.
|
|
74
75
|
* Dynamic routing only applies in auto-mode where cost optimization is expected. (#3962) */
|
|
@@ -76,9 +77,21 @@ export async function selectAndApplyModel(
|
|
|
76
77
|
/** Explicit /gsd model pin captured at bootstrap for long-running auto loops. */
|
|
77
78
|
sessionModelOverride?: { provider: string; id: string } | null,
|
|
78
79
|
): Promise<ModelSelectionResult> {
|
|
80
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
79
81
|
const effectiveSessionModelOverride = sessionModelOverride === undefined
|
|
80
82
|
? getSessionModelOverride(ctx.sessionManager.getSessionId())
|
|
81
83
|
: (sessionModelOverride ?? undefined);
|
|
84
|
+
// Enrich the start model with a flat-rate context up front so routing
|
|
85
|
+
// synthesis and the dispatch-time guard see the same signals (built-in
|
|
86
|
+
// list + user `flat_rate_providers` preference + externalCli auto-
|
|
87
|
+
// detection). The dispatch-time primary-model check below builds its
|
|
88
|
+
// own per-provider context when it has a resolved primary model.
|
|
89
|
+
if (autoModeStartModel) {
|
|
90
|
+
autoModeStartModel = {
|
|
91
|
+
...autoModeStartModel,
|
|
92
|
+
flatRateCtx: buildFlatRateContext(autoModeStartModel.provider, ctx, prefs),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
82
95
|
const modelConfig = effectiveSessionModelOverride
|
|
83
96
|
? undefined
|
|
84
97
|
: resolvePreferredModelConfig(unitType, autoModeStartModel, isAutoMode);
|
|
@@ -87,6 +100,9 @@ export async function selectAndApplyModel(
|
|
|
87
100
|
|
|
88
101
|
if (modelConfig) {
|
|
89
102
|
const availableModels = ctx.modelRegistry.getAvailable();
|
|
103
|
+
const modelPolicyTraceId = `model:${ctx.sessionManager.getSessionId()}:${Date.now()}`;
|
|
104
|
+
const modelPolicyTurnId = `${unitType}:${unitId}`;
|
|
105
|
+
let policyAllowedModelKeys: Set<string> | null = null;
|
|
90
106
|
|
|
91
107
|
// ─── Dynamic Model Routing ─────────────────────────────────────────
|
|
92
108
|
// Dynamic routing (complexity-based downgrading) only applies in auto-mode.
|
|
@@ -96,8 +112,40 @@ export async function selectAndApplyModel(
|
|
|
96
112
|
if (!isAutoMode) {
|
|
97
113
|
routingConfig.enabled = false;
|
|
98
114
|
}
|
|
115
|
+
// burn-max defaults to quality-first dispatch (no downgrade routing).
|
|
116
|
+
if (prefs?.token_profile === "burn-max") {
|
|
117
|
+
routingConfig.enabled = false;
|
|
118
|
+
}
|
|
99
119
|
let effectiveModelConfig = modelConfig;
|
|
100
120
|
let routingTierLabel = "";
|
|
121
|
+
let routingEligibleModels = availableModels;
|
|
122
|
+
|
|
123
|
+
const taskMetadataForPolicy = unitType === "execute-task"
|
|
124
|
+
? extractTaskMetadata(unitId, basePath)
|
|
125
|
+
: undefined;
|
|
126
|
+
|
|
127
|
+
if (uokFlags.modelPolicy) {
|
|
128
|
+
const policy = applyModelPolicyFilter(
|
|
129
|
+
availableModels,
|
|
130
|
+
{
|
|
131
|
+
basePath,
|
|
132
|
+
traceId: modelPolicyTraceId,
|
|
133
|
+
turnId: modelPolicyTurnId,
|
|
134
|
+
unitType,
|
|
135
|
+
taskMetadata: taskMetadataForPolicy,
|
|
136
|
+
currentProvider: ctx.model?.provider,
|
|
137
|
+
allowCrossProvider: routingConfig.cross_provider !== false,
|
|
138
|
+
requiredTools: pi.getActiveTools(),
|
|
139
|
+
},
|
|
140
|
+
);
|
|
141
|
+
routingEligibleModels = policy.eligible;
|
|
142
|
+
policyAllowedModelKeys = new Set(
|
|
143
|
+
policy.eligible.map((m) => `${m.provider.toLowerCase()}/${m.id.toLowerCase()}`),
|
|
144
|
+
);
|
|
145
|
+
if (routingEligibleModels.length === 0) {
|
|
146
|
+
throw new Error(`Model policy denied all candidate models for ${unitType}/${unitId}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
101
149
|
|
|
102
150
|
// Disable routing for flat-rate providers like GitHub Copilot (#3453).
|
|
103
151
|
// All models cost the same per request, so downgrading to a cheaper
|
|
@@ -105,14 +153,18 @@ export async function selectAndApplyModel(
|
|
|
105
153
|
// Fail-closed: if primary model can't be resolved, fall back to
|
|
106
154
|
// provider-level signals rather than allowing unwanted downgrades.
|
|
107
155
|
if (routingConfig.enabled) {
|
|
108
|
-
const primaryModel = resolveModelId(modelConfig.primary,
|
|
156
|
+
const primaryModel = resolveModelId(modelConfig.primary, routingEligibleModels, ctx.model?.provider);
|
|
109
157
|
if (primaryModel) {
|
|
110
|
-
|
|
158
|
+
const primaryFlatRateCtx = buildFlatRateContext(primaryModel.provider, ctx, prefs);
|
|
159
|
+
if (isFlatRateProvider(primaryModel.provider, primaryFlatRateCtx)) {
|
|
111
160
|
routingConfig.enabled = false;
|
|
112
161
|
}
|
|
113
162
|
} else if (
|
|
114
|
-
(autoModeStartModel && isFlatRateProvider(autoModeStartModel.provider))
|
|
115
|
-
|| (ctx.model?.provider && isFlatRateProvider(
|
|
163
|
+
(autoModeStartModel && isFlatRateProvider(autoModeStartModel.provider, autoModeStartModel.flatRateCtx))
|
|
164
|
+
|| (ctx.model?.provider && isFlatRateProvider(
|
|
165
|
+
ctx.model.provider,
|
|
166
|
+
buildFlatRateContext(ctx.model.provider, ctx, prefs),
|
|
167
|
+
))
|
|
116
168
|
) {
|
|
117
169
|
// Primary model unresolvable but provider signals indicate flat-rate —
|
|
118
170
|
// disable routing to prevent quality degradation.
|
|
@@ -135,8 +187,14 @@ export async function selectAndApplyModel(
|
|
|
135
187
|
const shouldClassify = !isHook || routingConfig.hooks !== false;
|
|
136
188
|
|
|
137
189
|
if (shouldClassify) {
|
|
138
|
-
let classification = classifyUnitComplexity(
|
|
139
|
-
|
|
190
|
+
let classification = classifyUnitComplexity(
|
|
191
|
+
unitType,
|
|
192
|
+
unitId,
|
|
193
|
+
basePath,
|
|
194
|
+
budgetPct,
|
|
195
|
+
taskMetadataForPolicy,
|
|
196
|
+
);
|
|
197
|
+
const availableModelIds = routingEligibleModels.map(m => m.id);
|
|
140
198
|
|
|
141
199
|
// Escalate tier on retry when escalate_on_failure is enabled (default: true)
|
|
142
200
|
if (
|
|
@@ -243,15 +301,28 @@ export async function selectAndApplyModel(
|
|
|
243
301
|
}
|
|
244
302
|
|
|
245
303
|
const modelsToTry = [effectiveModelConfig.primary, ...effectiveModelConfig.fallbacks];
|
|
304
|
+
let attemptedPolicyEligible = false;
|
|
246
305
|
|
|
247
306
|
for (const modelId of modelsToTry) {
|
|
248
|
-
const
|
|
307
|
+
const resolutionPool = uokFlags.modelPolicy ? routingEligibleModels : availableModels;
|
|
308
|
+
const model = resolveModelId(modelId, resolutionPool, ctx.model?.provider);
|
|
249
309
|
|
|
250
310
|
if (!model) {
|
|
251
311
|
if (verbose) ctx.ui.notify(`Model ${modelId} not found, trying fallback.`, "info");
|
|
252
312
|
continue;
|
|
253
313
|
}
|
|
254
314
|
|
|
315
|
+
if (policyAllowedModelKeys) {
|
|
316
|
+
const key = `${model.provider.toLowerCase()}/${model.id.toLowerCase()}`;
|
|
317
|
+
if (!policyAllowedModelKeys.has(key)) {
|
|
318
|
+
if (verbose) {
|
|
319
|
+
ctx.ui.notify(`Model policy denied ${model.provider}/${model.id}; trying fallback.`, "warning");
|
|
320
|
+
}
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
attemptedPolicyEligible = true;
|
|
324
|
+
}
|
|
325
|
+
|
|
255
326
|
// Warn if the ID is ambiguous across providers
|
|
256
327
|
if (!modelId.includes("/")) {
|
|
257
328
|
const providers = availableModels.filter(m => m.id === modelId).map(m => m.provider);
|
|
@@ -317,6 +388,10 @@ export async function selectAndApplyModel(
|
|
|
317
388
|
}
|
|
318
389
|
}
|
|
319
390
|
}
|
|
391
|
+
|
|
392
|
+
if (uokFlags.modelPolicy && policyAllowedModelKeys && !attemptedPolicyEligible) {
|
|
393
|
+
throw new Error(`Model policy denied dispatch for ${unitType}/${unitId} before prompt send`);
|
|
394
|
+
}
|
|
320
395
|
} else if (autoModeStartModel) {
|
|
321
396
|
// No model preference for this unit type — re-apply the model captured
|
|
322
397
|
// at auto-mode start to prevent bleed from shared global settings.json (#650).
|
|
@@ -416,8 +491,68 @@ export function resolveModelId<T extends { id: string; provider: string }>(
|
|
|
416
491
|
* Uses case-insensitive matching with alias support to prevent fail-open on
|
|
417
492
|
* provider naming variations (e.g. "copilot" vs "github-copilot").
|
|
418
493
|
*/
|
|
419
|
-
const
|
|
494
|
+
const BUILTIN_FLAT_RATE = new Set(["github-copilot", "copilot", "claude-code"]);
|
|
420
495
|
|
|
421
|
-
|
|
422
|
-
|
|
496
|
+
/**
|
|
497
|
+
* Optional context that lets callers extend flat-rate detection beyond the
|
|
498
|
+
* hard-coded built-in list. Either signal on its own is enough to classify
|
|
499
|
+
* a provider as flat-rate.
|
|
500
|
+
*/
|
|
501
|
+
export interface FlatRateContext {
|
|
502
|
+
/**
|
|
503
|
+
* Auth mode for the specific provider being checked, as returned by
|
|
504
|
+
* `ctx.modelRegistry.getProviderAuthMode(provider)`. Any provider that
|
|
505
|
+
* wraps a local CLI (externalCli) is, by definition, a flat-rate
|
|
506
|
+
* subscription wrapper — every request costs the same regardless of
|
|
507
|
+
* model, so dynamic routing only degrades quality.
|
|
508
|
+
*/
|
|
509
|
+
authMode?: "apiKey" | "oauth" | "externalCli" | "none";
|
|
510
|
+
/**
|
|
511
|
+
* Case-insensitive list of extra provider IDs the user has declared as
|
|
512
|
+
* flat-rate via `preferences.flat_rate_providers`. Used for private
|
|
513
|
+
* subscription-backed proxies and enterprise-gated deployments that the
|
|
514
|
+
* built-in list doesn't know about.
|
|
515
|
+
*/
|
|
516
|
+
userFlatRate?: readonly string[];
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export function isFlatRateProvider(provider: string, opts?: FlatRateContext): boolean {
|
|
520
|
+
const p = provider.toLowerCase();
|
|
521
|
+
if (BUILTIN_FLAT_RATE.has(p)) return true;
|
|
522
|
+
if (opts?.userFlatRate?.some(id => id.toLowerCase() === p)) return true;
|
|
523
|
+
if (opts?.authMode === "externalCli") return true;
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Build a FlatRateContext for a given provider from live runtime state.
|
|
529
|
+
* Safe to call when ctx or prefs are undefined — missing pieces are
|
|
530
|
+
* treated as "no signal".
|
|
531
|
+
*/
|
|
532
|
+
export function buildFlatRateContext(
|
|
533
|
+
provider: string,
|
|
534
|
+
ctx?: { modelRegistry?: { getProviderAuthMode?: (p: string) => string } },
|
|
535
|
+
prefs?: { flat_rate_providers?: readonly string[] },
|
|
536
|
+
): FlatRateContext {
|
|
537
|
+
let authMode: FlatRateContext["authMode"];
|
|
538
|
+
const getAuthMode = ctx?.modelRegistry?.getProviderAuthMode;
|
|
539
|
+
if (typeof getAuthMode === "function") {
|
|
540
|
+
try {
|
|
541
|
+
const mode = getAuthMode(provider);
|
|
542
|
+
if (mode === "apiKey" || mode === "oauth" || mode === "externalCli" || mode === "none") {
|
|
543
|
+
authMode = mode;
|
|
544
|
+
}
|
|
545
|
+
} catch (err) {
|
|
546
|
+
// Registry lookup failure must never break flat-rate detection —
|
|
547
|
+
// fall through with authMode undefined and surface the cause.
|
|
548
|
+
logWarning(
|
|
549
|
+
"dispatch",
|
|
550
|
+
`flat-rate auth-mode lookup failed for ${provider}: ${err instanceof Error ? err.message : String(err)}`,
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
return {
|
|
555
|
+
authMode,
|
|
556
|
+
userFlatRate: prefs?.flat_rate_providers,
|
|
557
|
+
};
|
|
423
558
|
}
|
|
@@ -29,9 +29,10 @@ import { rebuildState } from "./doctor.js";
|
|
|
29
29
|
import { parseUnitId } from "./unit-id.js";
|
|
30
30
|
import { closeoutUnit, type CloseoutOptions } from "./auto-unit-closeout.js";
|
|
31
31
|
import {
|
|
32
|
-
|
|
32
|
+
runTurnGitAction,
|
|
33
33
|
type TaskCommitContext,
|
|
34
|
-
|
|
34
|
+
type TurnGitActionMode,
|
|
35
|
+
} from "./git-service.js";
|
|
35
36
|
import {
|
|
36
37
|
verifyExpectedArtifact,
|
|
37
38
|
resolveExpectedArtifactPath,
|
|
@@ -66,6 +67,9 @@ import { getSliceTasks } from "./gsd-db.js";
|
|
|
66
67
|
import { runPreExecutionChecks, type PreExecutionResult } from "./pre-execution-checks.js";
|
|
67
68
|
import { writePreExecutionEvidence } from "./verification-evidence.js";
|
|
68
69
|
import { ensureCodebaseMapFresh } from "./codebase-generator.js";
|
|
70
|
+
import { resolveUokFlags } from "./uok/flags.js";
|
|
71
|
+
import { UokGateRunner } from "./uok/gate-runner.js";
|
|
72
|
+
import { writeTurnGitTransaction } from "./uok/gitops.js";
|
|
69
73
|
|
|
70
74
|
/** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
|
|
71
75
|
const MAX_VERIFICATION_RETRIES = 3;
|
|
@@ -104,10 +108,12 @@ import {
|
|
|
104
108
|
updateSliceProgressCache,
|
|
105
109
|
unitVerb,
|
|
106
110
|
hideFooter,
|
|
111
|
+
describeNextUnit,
|
|
107
112
|
} from "./auto-dashboard.js";
|
|
108
113
|
import { existsSync, unlinkSync } from "node:fs";
|
|
109
114
|
import { join } from "node:path";
|
|
110
115
|
import { _resetHasChangesCache } from "./native-git-bridge.js";
|
|
116
|
+
import { autoCommitCurrentBranch } from "./worktree.js";
|
|
111
117
|
|
|
112
118
|
// ─── Rogue File Detection ──────────────────────────────────────────────────
|
|
113
119
|
|
|
@@ -233,6 +239,18 @@ export function detectRogueFileWrites(
|
|
|
233
239
|
return rogues;
|
|
234
240
|
}
|
|
235
241
|
|
|
242
|
+
export const STEP_COMPLETE_FALLBACK_MESSAGE =
|
|
243
|
+
"Step complete. Run /clear, then /gsd to continue (or /gsd auto to run continuously).";
|
|
244
|
+
|
|
245
|
+
export function buildStepCompleteMessage(nextState: import("./types.js").GSDState): string {
|
|
246
|
+
if (nextState.phase === "complete") {
|
|
247
|
+
return "Step complete — milestone finished. Run /gsd status to review, or start the next milestone.";
|
|
248
|
+
}
|
|
249
|
+
const next = describeNextUnit(nextState);
|
|
250
|
+
return `Step complete. Next: ${next.label}\n`
|
|
251
|
+
+ `Run /clear, then /gsd to continue (or /gsd auto to run continuously).`;
|
|
252
|
+
}
|
|
253
|
+
|
|
236
254
|
export interface PreVerificationOpts {
|
|
237
255
|
skipSettleDelay?: boolean;
|
|
238
256
|
skipWorktreeSync?: boolean;
|
|
@@ -249,6 +267,65 @@ export interface PostUnitContext {
|
|
|
249
267
|
updateProgressWidget: (ctx: ExtensionContext, unitType: string, unitId: string, state: import("./types.js").GSDState) => void;
|
|
250
268
|
}
|
|
251
269
|
|
|
270
|
+
export async function autoCommitUnit(
|
|
271
|
+
basePath: string,
|
|
272
|
+
unitType: string,
|
|
273
|
+
unitId: string,
|
|
274
|
+
ctx?: ExtensionContext,
|
|
275
|
+
): Promise<string | null> {
|
|
276
|
+
try {
|
|
277
|
+
let taskContext: TaskCommitContext | undefined;
|
|
278
|
+
|
|
279
|
+
if (unitType === "execute-task") {
|
|
280
|
+
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
|
|
281
|
+
if (mid && sid && tid) {
|
|
282
|
+
const summaryPath = resolveTaskFile(basePath, mid, sid, tid, "SUMMARY");
|
|
283
|
+
if (summaryPath) {
|
|
284
|
+
try {
|
|
285
|
+
const summaryContent = await loadFile(summaryPath);
|
|
286
|
+
if (summaryContent) {
|
|
287
|
+
const summary = parseSummary(summaryContent);
|
|
288
|
+
let ghIssueNumber: number | undefined;
|
|
289
|
+
try {
|
|
290
|
+
const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
|
|
291
|
+
ghIssueNumber = getTaskIssueNumberForCommit(basePath, mid, sid, tid) ?? undefined;
|
|
292
|
+
} catch (err) {
|
|
293
|
+
logWarning("engine", `GitHub issue lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
taskContext = {
|
|
297
|
+
taskId: `${sid}/${tid}`,
|
|
298
|
+
taskTitle: summary.title?.replace(/^T\d+:\s*/, "") || tid,
|
|
299
|
+
oneLiner: summary.oneLiner || undefined,
|
|
300
|
+
keyFiles: summary.frontmatter.key_files?.filter(f => !f.includes("{{")) || undefined,
|
|
301
|
+
issueNumber: ghIssueNumber,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
} catch (e) {
|
|
305
|
+
debugLog("postUnit", { phase: "task-summary-parse", error: String(e) });
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
_resetHasChangesCache();
|
|
312
|
+
|
|
313
|
+
if (LIFECYCLE_ONLY_UNITS.has(unitType)) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const commitMsg = autoCommitCurrentBranch(basePath, unitType, unitId, taskContext);
|
|
318
|
+
if (commitMsg) {
|
|
319
|
+
ctx?.ui.notify(`Committed: ${commitMsg.split("\n")[0]}`, "info");
|
|
320
|
+
}
|
|
321
|
+
return commitMsg;
|
|
322
|
+
} catch (e) {
|
|
323
|
+
debugLog("postUnit", { phase: "auto-commit", error: String(e) });
|
|
324
|
+
ctx?.ui.notify(`Auto-commit failed: ${String(e).split("\n")[0]}`, "warning");
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
252
329
|
/**
|
|
253
330
|
* Pre-verification processing: parallel worker signal check, cache invalidation,
|
|
254
331
|
* auto-commit, doctor run, state rebuild, worktree sync, artifact verification.
|
|
@@ -285,13 +362,21 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
285
362
|
await new Promise(r => setTimeout(r, 100));
|
|
286
363
|
}
|
|
287
364
|
|
|
288
|
-
|
|
365
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences;
|
|
366
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
367
|
+
|
|
368
|
+
// Turn-level git action (commit | snapshot | status-only)
|
|
289
369
|
if (s.currentUnit) {
|
|
290
370
|
const unit = s.currentUnit;
|
|
371
|
+
const turnAction: TurnGitActionMode = uokFlags.gitops ? uokFlags.gitopsTurnAction : "commit";
|
|
372
|
+
const traceId = s.currentTraceId ?? `turn:${unit.startedAt}`;
|
|
373
|
+
const turnId = s.currentTurnId ?? `${unit.type}/${unit.id}/${unit.startedAt}`;
|
|
374
|
+
s.lastGitActionFailure = null;
|
|
375
|
+
s.lastGitActionStatus = null;
|
|
291
376
|
try {
|
|
292
377
|
let taskContext: TaskCommitContext | undefined;
|
|
293
378
|
|
|
294
|
-
if (s.currentUnit.type === "execute-task") {
|
|
379
|
+
if (turnAction === "commit" && s.currentUnit.type === "execute-task") {
|
|
295
380
|
const { milestone: mid, slice: sid, task: tid } = parseUnitId(s.currentUnit.id);
|
|
296
381
|
if (mid && sid && tid) {
|
|
297
382
|
const summaryPath = resolveTaskFile(s.basePath, mid, sid, tid, "SUMMARY");
|
|
@@ -332,18 +417,105 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
332
417
|
// `git worktree remove --force` during teardown.
|
|
333
418
|
_resetHasChangesCache();
|
|
334
419
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
420
|
+
const skipLifecycleCommit =
|
|
421
|
+
turnAction === "commit" && LIFECYCLE_ONLY_UNITS.has(s.currentUnit.type);
|
|
422
|
+
|
|
423
|
+
if (skipLifecycleCommit) {
|
|
424
|
+
debugLog("postUnit", {
|
|
425
|
+
phase: "git-action-skipped",
|
|
426
|
+
reason: "lifecycle-only-unit",
|
|
427
|
+
unitType: s.currentUnit.type,
|
|
428
|
+
unitId: s.currentUnit.id,
|
|
429
|
+
});
|
|
430
|
+
} else {
|
|
431
|
+
const gitResult = runTurnGitAction({
|
|
432
|
+
basePath: s.basePath,
|
|
433
|
+
action: turnAction,
|
|
434
|
+
unitType: s.currentUnit.type,
|
|
435
|
+
unitId: s.currentUnit.id,
|
|
436
|
+
taskContext,
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
if (uokFlags.gitops) {
|
|
440
|
+
writeTurnGitTransaction({
|
|
441
|
+
basePath: s.basePath,
|
|
442
|
+
traceId,
|
|
443
|
+
turnId,
|
|
444
|
+
unitType: unit.type,
|
|
445
|
+
unitId: unit.id,
|
|
446
|
+
stage: "publish",
|
|
447
|
+
action: turnAction,
|
|
448
|
+
push: uokFlags.gitopsTurnPush,
|
|
449
|
+
status: gitResult.status,
|
|
450
|
+
error: gitResult.error,
|
|
451
|
+
metadata: {
|
|
452
|
+
dirty: gitResult.dirty,
|
|
453
|
+
commitMessage: gitResult.commitMessage,
|
|
454
|
+
snapshotLabel: gitResult.snapshotLabel,
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (gitResult.status === "failed") {
|
|
460
|
+
s.lastGitActionFailure = gitResult.error ?? `git ${turnAction} failed`;
|
|
461
|
+
s.lastGitActionStatus = "failed";
|
|
462
|
+
if (uokFlags.gitops && uokFlags.gates) {
|
|
463
|
+
const parsed = parseUnitId(unit.id);
|
|
464
|
+
const gateRunner = new UokGateRunner();
|
|
465
|
+
gateRunner.register({
|
|
466
|
+
id: "closeout-git-action",
|
|
467
|
+
type: "closeout",
|
|
468
|
+
execute: async () => ({
|
|
469
|
+
outcome: "fail",
|
|
470
|
+
failureClass: "git",
|
|
471
|
+
rationale: `turn git action "${turnAction}" failed`,
|
|
472
|
+
findings: gitResult.error ?? "unknown git failure",
|
|
473
|
+
}),
|
|
474
|
+
});
|
|
475
|
+
await gateRunner.run("closeout-git-action", {
|
|
476
|
+
basePath: s.basePath,
|
|
477
|
+
traceId,
|
|
478
|
+
turnId,
|
|
479
|
+
milestoneId: parsed.milestone ?? undefined,
|
|
480
|
+
sliceId: parsed.slice ?? undefined,
|
|
481
|
+
taskId: parsed.task ?? undefined,
|
|
482
|
+
unitType: unit.type,
|
|
483
|
+
unitId: unit.id,
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const failureMsg = `Git ${turnAction} failed: ${(gitResult.error ?? "unknown error").split("\n")[0]}`;
|
|
488
|
+
if (uokFlags.gitops) {
|
|
489
|
+
ctx.ui.notify(failureMsg, "error");
|
|
490
|
+
await pauseAuto(ctx, pi);
|
|
491
|
+
return "dispatched";
|
|
492
|
+
}
|
|
493
|
+
ctx.ui.notify(failureMsg, "warning");
|
|
494
|
+
debugLog("postUnit", {
|
|
495
|
+
phase: "git-action-failed-nonblocking",
|
|
496
|
+
action: turnAction,
|
|
497
|
+
error: gitResult.error ?? "unknown error",
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
s.lastGitActionStatus = "ok";
|
|
502
|
+
|
|
503
|
+
if (turnAction === "commit" && gitResult.commitMessage) {
|
|
504
|
+
ctx.ui.notify(`Committed: ${gitResult.commitMessage.split("\n")[0]}`, "info");
|
|
505
|
+
} else if (turnAction === "snapshot" && gitResult.snapshotLabel) {
|
|
506
|
+
ctx.ui.notify(`Snapshot recorded: ${gitResult.snapshotLabel}`, "info");
|
|
342
507
|
}
|
|
343
508
|
}
|
|
344
509
|
} catch (e) {
|
|
345
|
-
|
|
346
|
-
|
|
510
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
511
|
+
s.lastGitActionFailure = message;
|
|
512
|
+
s.lastGitActionStatus = "failed";
|
|
513
|
+
debugLog("postUnit", { phase: "git-action", error: message, action: turnAction });
|
|
514
|
+
ctx.ui.notify(`Git ${turnAction} failed: ${message.split("\n")[0]}`, uokFlags.gitops ? "error" : "warning");
|
|
515
|
+
if (uokFlags.gitops) {
|
|
516
|
+
await pauseAuto(ctx, pi);
|
|
517
|
+
return "dispatched";
|
|
518
|
+
}
|
|
347
519
|
}
|
|
348
520
|
|
|
349
521
|
// GitHub sync (non-blocking, opt-in)
|
|
@@ -619,6 +791,30 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
619
791
|
s.verificationRetryCount.set(retryKey, attempt);
|
|
620
792
|
|
|
621
793
|
if (attempt > MAX_VERIFICATION_RETRIES) {
|
|
794
|
+
// #4175: For complete-milestone, a blocker placeholder is harmful —
|
|
795
|
+
// the stub SUMMARY has no recovery value (milestone is terminal),
|
|
796
|
+
// it does not update DB status (so deriveState never advances),
|
|
797
|
+
// and it fools stopAuto's presence check into merging a milestone
|
|
798
|
+
// that was never legitimately completed. Pause auto-mode with a
|
|
799
|
+
// clear single failure signal and preserve the worktree branch.
|
|
800
|
+
if (s.currentUnit.type === "complete-milestone") {
|
|
801
|
+
debugLog("postUnit", {
|
|
802
|
+
phase: "artifact-verify-pause-complete-milestone",
|
|
803
|
+
unitType: s.currentUnit.type,
|
|
804
|
+
unitId: s.currentUnit.id,
|
|
805
|
+
attempt,
|
|
806
|
+
maxRetries: MAX_VERIFICATION_RETRIES,
|
|
807
|
+
});
|
|
808
|
+
s.verificationRetryCount.delete(retryKey);
|
|
809
|
+
s.pendingVerificationRetry = null;
|
|
810
|
+
ctx.ui.notify(
|
|
811
|
+
`Milestone ${s.currentUnit.id} verification failed after ${MAX_VERIFICATION_RETRIES} retries — worktree branch preserved. Re-run /gsd auto once blockers are resolved.`,
|
|
812
|
+
"error",
|
|
813
|
+
);
|
|
814
|
+
await pauseAuto(ctx, pi);
|
|
815
|
+
return "dispatched";
|
|
816
|
+
}
|
|
817
|
+
|
|
622
818
|
// Retries exhausted — write a blocker placeholder so the pipeline
|
|
623
819
|
// can advance past this stuck unit (#2653).
|
|
624
820
|
debugLog("postUnit", {
|
|
@@ -829,11 +1025,13 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
829
1025
|
s.currentUnit &&
|
|
830
1026
|
s.currentUnit.type === "plan-slice"
|
|
831
1027
|
) {
|
|
1028
|
+
const currentUnit = s.currentUnit;
|
|
832
1029
|
let preExecPauseNeeded = false;
|
|
833
1030
|
await runSafely("postUnitPostVerification", "pre-execution-checks", async () => {
|
|
1031
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences;
|
|
1032
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
834
1033
|
try {
|
|
835
1034
|
// Check preferences — respect enhanced_verification and enhanced_verification_pre
|
|
836
|
-
const prefs = loadEffectiveGSDPreferences()?.preferences;
|
|
837
1035
|
const enhancedEnabled = prefs?.enhanced_verification !== false; // default true
|
|
838
1036
|
const preEnabled = prefs?.enhanced_verification_pre !== false; // default true
|
|
839
1037
|
|
|
@@ -847,7 +1045,7 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
847
1045
|
}
|
|
848
1046
|
|
|
849
1047
|
// Parse the unit ID to get milestone/slice IDs
|
|
850
|
-
const { milestone: mid, slice: sid } = parseUnitId(
|
|
1048
|
+
const { milestone: mid, slice: sid } = parseUnitId(currentUnit.id);
|
|
851
1049
|
if (!mid || !sid) {
|
|
852
1050
|
debugLog("postUnitPostVerification", {
|
|
853
1051
|
phase: "pre-execution-checks",
|
|
@@ -868,6 +1066,8 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
868
1066
|
return;
|
|
869
1067
|
}
|
|
870
1068
|
|
|
1069
|
+
const strictMode = prefs?.enhanced_verification_strict === true;
|
|
1070
|
+
|
|
871
1071
|
// Run pre-execution checks
|
|
872
1072
|
const result: PreExecutionResult = await runPreExecutionChecks(tasks, s.basePath);
|
|
873
1073
|
|
|
@@ -891,6 +1091,36 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
891
1091
|
writePreExecutionEvidence(result, slicePath, mid, sid);
|
|
892
1092
|
}
|
|
893
1093
|
|
|
1094
|
+
if (uokFlags.gates) {
|
|
1095
|
+
const failedChecks = result.checks
|
|
1096
|
+
.filter((check) => !check.passed)
|
|
1097
|
+
.map((check) => `[${check.category}] ${check.target}: ${check.message}`);
|
|
1098
|
+
const warnEscalated = result.status === "warn" && strictMode;
|
|
1099
|
+
const blockingFailure = result.status === "fail" || warnEscalated;
|
|
1100
|
+
const gateRunner = new UokGateRunner();
|
|
1101
|
+
gateRunner.register({
|
|
1102
|
+
id: "pre-execution-checks",
|
|
1103
|
+
type: "input",
|
|
1104
|
+
execute: async () => ({
|
|
1105
|
+
outcome: blockingFailure ? "fail" : "pass",
|
|
1106
|
+
failureClass: result.status === "fail" ? "input" : warnEscalated ? "policy" : "none",
|
|
1107
|
+
rationale: blockingFailure
|
|
1108
|
+
? `pre-execution checks ${result.status}${warnEscalated ? " (strict)" : ""}`
|
|
1109
|
+
: "pre-execution checks passed",
|
|
1110
|
+
findings: failedChecks.join("\n"),
|
|
1111
|
+
}),
|
|
1112
|
+
});
|
|
1113
|
+
await gateRunner.run("pre-execution-checks", {
|
|
1114
|
+
basePath: s.basePath,
|
|
1115
|
+
traceId: `pre-execution:${currentUnit.id}`,
|
|
1116
|
+
turnId: currentUnit.id,
|
|
1117
|
+
milestoneId: mid,
|
|
1118
|
+
sliceId: sid,
|
|
1119
|
+
unitType: currentUnit.type,
|
|
1120
|
+
unitId: currentUnit.id,
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
|
|
894
1124
|
// Notify UI
|
|
895
1125
|
if (result.status === "fail") {
|
|
896
1126
|
const blockingCount = result.checks.filter(c => !c.passed && c.blocking).length;
|
|
@@ -929,6 +1159,29 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
929
1159
|
`Pre-execution checks error: ${errorMessage} — pausing for human review`,
|
|
930
1160
|
"error",
|
|
931
1161
|
);
|
|
1162
|
+
if (uokFlags.gates && s.currentUnit) {
|
|
1163
|
+
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
|
1164
|
+
const gateRunner = new UokGateRunner();
|
|
1165
|
+
gateRunner.register({
|
|
1166
|
+
id: "pre-execution-checks",
|
|
1167
|
+
type: "input",
|
|
1168
|
+
execute: async () => ({
|
|
1169
|
+
outcome: "manual-attention",
|
|
1170
|
+
failureClass: "manual-attention",
|
|
1171
|
+
rationale: "pre-execution checks threw before completion",
|
|
1172
|
+
findings: errorMessage,
|
|
1173
|
+
}),
|
|
1174
|
+
});
|
|
1175
|
+
await gateRunner.run("pre-execution-checks", {
|
|
1176
|
+
basePath: s.basePath,
|
|
1177
|
+
traceId: `pre-execution:${s.currentUnit.id}`,
|
|
1178
|
+
turnId: s.currentUnit.id,
|
|
1179
|
+
milestoneId: mid ?? undefined,
|
|
1180
|
+
sliceId: sid ?? undefined,
|
|
1181
|
+
unitType: s.currentUnit.type,
|
|
1182
|
+
unitId: s.currentUnit.id,
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
932
1185
|
preExecPauseNeeded = true;
|
|
933
1186
|
}
|
|
934
1187
|
});
|
|
@@ -1025,8 +1278,17 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1025
1278
|
}
|
|
1026
1279
|
}
|
|
1027
1280
|
|
|
1028
|
-
// Step mode → show wizard instead of dispatch
|
|
1281
|
+
// Step mode → show wizard instead of dispatch.
|
|
1282
|
+
// Without this notify(), /gsd in step mode finishes a unit and silently
|
|
1283
|
+
// exits the loop, leaving the user with no hint to /clear and /gsd again.
|
|
1029
1284
|
if (s.stepMode) {
|
|
1285
|
+
try {
|
|
1286
|
+
const nextState = await deriveState(s.basePath);
|
|
1287
|
+
ctx.ui.notify(buildStepCompleteMessage(nextState), "info");
|
|
1288
|
+
} catch (e) {
|
|
1289
|
+
debugLog("postUnit", { phase: "step-wizard-notify", error: String(e) });
|
|
1290
|
+
ctx.ui.notify(STEP_COMPLETE_FALLBACK_MESSAGE, "info");
|
|
1291
|
+
}
|
|
1030
1292
|
return "step-wizard";
|
|
1031
1293
|
}
|
|
1032
1294
|
|