@opengsd/gsd-pi 1.2.0-dev.b1abb545 → 1.2.0-dev.e8563f58
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-style.d.ts +17 -0
- package/dist/cli-style.js +28 -0
- package/dist/cli.js +1 -1
- package/dist/headless-events.d.ts +4 -2
- package/dist/headless-events.js +14 -34
- package/dist/mcp-server.js +2 -1
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/resource-loader.js +2 -14
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/bg-shell/utilities.js +5 -2
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
- package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
- package/dist/resources/extensions/browser-tools/index.js +69 -12
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +122 -58
- package/dist/resources/extensions/gsd/auto/phases.js +8 -3
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +8 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +40 -57
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
- package/dist/resources/extensions/gsd/auto-post-unit.js +31 -14
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
- package/dist/resources/extensions/gsd/auto-start.js +24 -26
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
- package/dist/resources/extensions/gsd/auto-verification.js +9 -28
- package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +35 -352
- package/dist/resources/extensions/gsd/auto.js +15 -20
- package/dist/resources/extensions/gsd/blocked-models.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +229 -36
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +319 -71
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
- package/dist/resources/extensions/gsd/captures.js +5 -15
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
- package/dist/resources/extensions/gsd/consent-question.js +353 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
- package/dist/resources/extensions/gsd/db/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +398 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-git-checks.js +6 -21
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/error-classifier.js +9 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
- package/dist/resources/extensions/gsd/gsd-db.js +172 -2048
- package/dist/resources/extensions/gsd/guidance.js +158 -0
- package/dist/resources/extensions/gsd/guided-flow.js +51 -5
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
- package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
- package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
- package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
- package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/paths.js +37 -24
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +14 -48
- package/dist/resources/extensions/gsd/preferences.js +14 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +6 -4
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
- package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
- package/dist/resources/extensions/gsd/publication.js +87 -0
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +6 -20
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +44 -53
- package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
- package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
- package/dist/resources/extensions/gsd/uat-policy.js +42 -16
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +337 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +12 -3
- package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +28 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
- package/dist/resources/extensions/search-the-web/native-search.js +5 -3
- package/dist/resources/extensions/shared/browser-contract.js +59 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
- package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
- package/dist/resources/shared/package-manager-detection.js +1 -1
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-check.d.ts +2 -0
- package/dist/update-check.js +24 -1
- package/dist/update-cmd.js +20 -3
- 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 +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.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/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +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 +8 -8
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/package.json +1 -1
- package/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -11
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +4 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +8 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/cli.js +6 -3
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +4 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +145 -59
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/README.md +1 -0
- package/packages/pi-ai/dist/index.d.ts +2 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +2 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +192 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +166 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +12 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
- package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.js +12 -3
- package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +5 -4
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/bg-shell/utilities.ts +5 -2
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
- package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
- package/src/resources/extensions/browser-tools/index.ts +71 -13
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +137 -61
- package/src/resources/extensions/gsd/auto/phases.ts +12 -3
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -32
- package/src/resources/extensions/gsd/auto-dispatch.ts +38 -52
- package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +37 -13
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
- package/src/resources/extensions/gsd/auto-start.ts +24 -29
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
- package/src/resources/extensions/gsd/auto-verification.ts +8 -26
- package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +41 -364
- package/src/resources/extensions/gsd/auto.ts +28 -24
- package/src/resources/extensions/gsd/blocked-models.ts +49 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +270 -37
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +368 -78
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
- package/src/resources/extensions/gsd/captures.ts +5 -16
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
- package/src/resources/extensions/gsd/consent-question.ts +431 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
- package/src/resources/extensions/gsd/db/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +490 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -22
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/error-classifier.ts +11 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
- package/src/resources/extensions/gsd/gsd-db.ts +176 -2375
- package/src/resources/extensions/gsd/guidance.ts +217 -0
- package/src/resources/extensions/gsd/guided-flow.ts +50 -5
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
- package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
- package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
- package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
- package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
- package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/paths.ts +42 -22
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +12 -47
- package/src/resources/extensions/gsd/preferences.ts +18 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +6 -4
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
- package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
- package/src/resources/extensions/gsd/publication.ts +122 -0
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +9 -21
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
- package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
- package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +109 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +43 -68
- package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
- package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
- package/src/resources/extensions/gsd/uat-policy.ts +62 -16
- package/src/resources/extensions/gsd/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +412 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +13 -9
- package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +29 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
- package/src/resources/extensions/search-the-web/native-search.ts +5 -3
- package/src/resources/extensions/shared/browser-contract.ts +66 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
- package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
- package/src/resources/shared/package-manager-detection.ts +1 -1
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/src/resources/skills/gsd-browser/SKILL.md +1 -1
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
- package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
- /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → LDHRKiRBIVZmiuMjrL1Vy}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → LDHRKiRBIVZmiuMjrL1Vy}/_ssgManifest.js +0 -0
|
@@ -8,6 +8,7 @@ import { fileURLToPath } from "node:url";
|
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
|
|
10
10
|
import { ModelPolicyDispatchBlockedError, resolvePreferredModelConfig, resolveModelId, selectAndApplyModel, floorThinkingLevelForUnit } from "../auto-model-selection.js";
|
|
11
|
+
import { blockModelUntil, clearTemporaryModelBlocksForTest } from "../blocked-models.ts";
|
|
11
12
|
|
|
12
13
|
function makeTempDir(prefix: string): string {
|
|
13
14
|
return mkdtempSync(join(tmpdir(), prefix));
|
|
@@ -223,6 +224,74 @@ test("selectAndApplyModel honors explicit phase models without downgrading (#361
|
|
|
223
224
|
}
|
|
224
225
|
});
|
|
225
226
|
|
|
227
|
+
test("selectAndApplyModel skips a rate-limited primary until its reset time", async () => {
|
|
228
|
+
const originalCwd = process.cwd();
|
|
229
|
+
const originalGsdHome = process.env.GSD_HOME;
|
|
230
|
+
const tempProject = makeTempDir("gsd-rate-limit-fallback-project-");
|
|
231
|
+
const tempGsdHome = makeTempDir("gsd-rate-limit-fallback-home-");
|
|
232
|
+
const setModelCalls: string[] = [];
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
clearTemporaryModelBlocksForTest();
|
|
236
|
+
mkdirSync(join(tempProject, ".gsd"), { recursive: true });
|
|
237
|
+
writeFileSync(
|
|
238
|
+
join(tempProject, ".gsd", "PREFERENCES.md"),
|
|
239
|
+
[
|
|
240
|
+
"---",
|
|
241
|
+
"models:",
|
|
242
|
+
" execution:",
|
|
243
|
+
" model: gpt-5.5",
|
|
244
|
+
" provider: openai-codex",
|
|
245
|
+
" fallbacks:",
|
|
246
|
+
" - anthropic/claude-sonnet-4-6",
|
|
247
|
+
"---",
|
|
248
|
+
].join("\n"),
|
|
249
|
+
"utf-8",
|
|
250
|
+
);
|
|
251
|
+
process.env.GSD_HOME = tempGsdHome;
|
|
252
|
+
process.chdir(tempProject);
|
|
253
|
+
|
|
254
|
+
const availableModels = [
|
|
255
|
+
{ id: "gpt-5.5", provider: "openai-codex", api: "responses" },
|
|
256
|
+
{ id: "claude-sonnet-4-6", provider: "anthropic", api: "anthropic-messages" },
|
|
257
|
+
];
|
|
258
|
+
const ctx = {
|
|
259
|
+
modelRegistry: { getAvailable: () => availableModels },
|
|
260
|
+
sessionManager: { getSessionId: () => "test-session" },
|
|
261
|
+
ui: { notify: () => {} },
|
|
262
|
+
model: { provider: "openai-codex", id: "gpt-5.5", api: "responses" },
|
|
263
|
+
} as any;
|
|
264
|
+
const pi = {
|
|
265
|
+
setModel: async (model: { provider: string; id: string }) => {
|
|
266
|
+
setModelCalls.push(`${model.provider}/${model.id}`);
|
|
267
|
+
return true;
|
|
268
|
+
},
|
|
269
|
+
emitBeforeModelSelect: async () => undefined,
|
|
270
|
+
getActiveTools: () => [],
|
|
271
|
+
emitAdjustToolSet: async () => undefined,
|
|
272
|
+
setActiveTools: () => {},
|
|
273
|
+
} as any;
|
|
274
|
+
|
|
275
|
+
blockModelUntil(tempProject, "openai-codex", "gpt-5.5", Date.now() + 60_000, "session limit");
|
|
276
|
+
await selectAndApplyModel(ctx, pi, "execute-task", "M001/S01/T01", tempProject, undefined, false, { provider: "openai-codex", id: "gpt-5.5" }, undefined, true);
|
|
277
|
+
|
|
278
|
+
blockModelUntil(tempProject, "openai-codex", "gpt-5.5", Date.now() - 1, "expired");
|
|
279
|
+
await selectAndApplyModel(ctx, pi, "execute-task", "M001/S01/T02", tempProject, undefined, false, { provider: "openai-codex", id: "gpt-5.5" }, undefined, true);
|
|
280
|
+
|
|
281
|
+
assert.deepEqual(setModelCalls, [
|
|
282
|
+
"anthropic/claude-sonnet-4-6",
|
|
283
|
+
"openai-codex/gpt-5.5",
|
|
284
|
+
]);
|
|
285
|
+
} finally {
|
|
286
|
+
clearTemporaryModelBlocksForTest();
|
|
287
|
+
process.chdir(originalCwd);
|
|
288
|
+
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
289
|
+
else process.env.GSD_HOME = originalGsdHome;
|
|
290
|
+
rmSync(tempProject, { recursive: true, force: true });
|
|
291
|
+
rmSync(tempGsdHome, { recursive: true, force: true });
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
226
295
|
test("selectAndApplyModel lets explicit unit models bypass stale cross-provider lock (#116)", async () => {
|
|
227
296
|
const originalCwd = process.cwd();
|
|
228
297
|
const originalGsdHome = process.env.GSD_HOME;
|
|
@@ -857,3 +926,25 @@ test("resolveModelId: claude-code wins when session is claude-code regardless of
|
|
|
857
926
|
assert.ok(result, "should resolve a model");
|
|
858
927
|
assert.equal(result.provider, "claude-code", "claude-code must win when it is the session provider");
|
|
859
928
|
});
|
|
929
|
+
|
|
930
|
+
test("resolveModelId: openai-codex wins over openai for bare GPT IDs when both are available", () => {
|
|
931
|
+
const availableModels = [
|
|
932
|
+
{ id: "gpt-5.5", provider: "openai" },
|
|
933
|
+
{ id: "gpt-5.5", provider: "openai-codex" },
|
|
934
|
+
];
|
|
935
|
+
|
|
936
|
+
const result = resolveModelId("gpt-5.5", availableModels, undefined);
|
|
937
|
+
assert.ok(result, "should resolve a model");
|
|
938
|
+
assert.equal(result.provider, "openai-codex", "ChatGPT OAuth must win over platform API for bare IDs");
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
test("resolveModelId: github-copilot wins over openai when both offer the same GPT model", () => {
|
|
942
|
+
const availableModels = [
|
|
943
|
+
{ id: "gpt-5.5", provider: "openai" },
|
|
944
|
+
{ id: "gpt-5.5", provider: "github-copilot" },
|
|
945
|
+
];
|
|
946
|
+
|
|
947
|
+
const result = resolveModelId("gpt-5.5", availableModels, undefined);
|
|
948
|
+
assert.ok(result);
|
|
949
|
+
assert.equal(result.provider, "github-copilot");
|
|
950
|
+
});
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
createAutoOrchestrator,
|
|
23
23
|
decideOrchestratorDispatch,
|
|
24
24
|
resolveLiveOrchestratorBasePath,
|
|
25
|
-
STUCK_WINDOW_SIZE,
|
|
26
25
|
} from "../auto/orchestrator.js";
|
|
26
|
+
import { STUCK_WINDOW_SIZE } from "../auto/dispatch-history.js";
|
|
27
27
|
import type { OrchestratorContext } from "../auto/orchestrator.js";
|
|
28
28
|
import type { AutoOrchestrationModule, AutoSessionContext } from "../auto/contracts.js";
|
|
29
29
|
import type { GSDState } from "../types.js";
|
|
@@ -41,6 +41,10 @@ import {
|
|
|
41
41
|
openDatabase,
|
|
42
42
|
} from "../gsd-db.js";
|
|
43
43
|
import { AutoSession } from "../auto/session.js";
|
|
44
|
+
import { registerAutoWorker } from "../db/auto-workers.js";
|
|
45
|
+
import { claimMilestoneLease } from "../db/milestone-leases.js";
|
|
46
|
+
import { recordDispatchClaim, markFailed } from "../db/unit-dispatches.js";
|
|
47
|
+
import { normalizeRealPath } from "../paths.js";
|
|
44
48
|
import { acquireSessionLock, releaseSessionLock } from "../session-lock.js";
|
|
45
49
|
import { queryJournal } from "../journal.js";
|
|
46
50
|
import { invalidateAllCaches } from "../cache.js";
|
|
@@ -518,13 +522,12 @@ test("advance() is idempotent for the same active unit", async (t) => {
|
|
|
518
522
|
if (first.kind === "advanced") {
|
|
519
523
|
assert.deepEqual(first.unit, { unitType: "execute-task", unitId: "M001/S01/T01" });
|
|
520
524
|
}
|
|
521
|
-
assert.equal(second.kind, "
|
|
522
|
-
if (second.kind !== "
|
|
525
|
+
assert.equal(second.kind, "skipped");
|
|
526
|
+
if (second.kind !== "skipped") return;
|
|
523
527
|
assert.equal(second.reason, "idempotent advance: unit already active");
|
|
524
|
-
assert.equal(second.action, "pause");
|
|
525
528
|
});
|
|
526
529
|
|
|
527
|
-
test("idempotency
|
|
530
|
+
test("idempotency skip fires with its own reason before saturation", async (t) => {
|
|
528
531
|
const f = makeFixture();
|
|
529
532
|
t.after(() => f.cleanup());
|
|
530
533
|
|
|
@@ -532,10 +535,9 @@ test("idempotency block fires with its own reason before saturation", async (t)
|
|
|
532
535
|
const second = await f.orchestrator.advance();
|
|
533
536
|
|
|
534
537
|
assert.equal(first.kind, "advanced");
|
|
535
|
-
assert.equal(second.kind, "
|
|
536
|
-
if (second.kind !== "
|
|
538
|
+
assert.equal(second.kind, "skipped");
|
|
539
|
+
if (second.kind !== "skipped") return;
|
|
537
540
|
assert.equal(second.reason, "idempotent advance: unit already active");
|
|
538
|
-
assert.equal(second.action, "pause");
|
|
539
541
|
});
|
|
540
542
|
|
|
541
543
|
test("completeActiveUnit clears in-flight idempotency and stops stale same-unit advance", async (t) => {
|
|
@@ -671,12 +673,12 @@ test("resume() clears idempotent lock and allows re-advance", async (t) => {
|
|
|
671
673
|
t.after(() => f.cleanup());
|
|
672
674
|
|
|
673
675
|
const first = await f.orchestrator.advance();
|
|
674
|
-
const
|
|
676
|
+
const idempotent = await f.orchestrator.advance();
|
|
675
677
|
const resumed = await f.orchestrator.resume();
|
|
676
678
|
const next = await f.orchestrator.advance();
|
|
677
679
|
|
|
678
680
|
assert.equal(first.kind, "advanced");
|
|
679
|
-
assert.equal(
|
|
681
|
+
assert.equal(idempotent.kind, "skipped");
|
|
680
682
|
assert.equal(resumed.kind, "resumed");
|
|
681
683
|
assert.equal(next.kind, "advanced");
|
|
682
684
|
});
|
|
@@ -686,11 +688,11 @@ test("start() clears prior idempotent lock", async (t) => {
|
|
|
686
688
|
t.after(() => f.cleanup());
|
|
687
689
|
|
|
688
690
|
await f.orchestrator.advance();
|
|
689
|
-
const
|
|
691
|
+
const idempotent = await f.orchestrator.advance();
|
|
690
692
|
const restarted = await f.orchestrator.start(SESSION_CONTEXT);
|
|
691
693
|
const next = await f.orchestrator.advance();
|
|
692
694
|
|
|
693
|
-
assert.equal(
|
|
695
|
+
assert.equal(idempotent.kind, "skipped");
|
|
694
696
|
assert.equal(restarted.kind, "started");
|
|
695
697
|
assert.equal(next.kind, "advanced");
|
|
696
698
|
});
|
|
@@ -700,32 +702,28 @@ test("stop() clears idempotent unit lock so advance can run again", async (t) =>
|
|
|
700
702
|
t.after(() => f.cleanup());
|
|
701
703
|
|
|
702
704
|
const first = await f.orchestrator.advance();
|
|
703
|
-
const
|
|
705
|
+
const idempotent = await f.orchestrator.advance();
|
|
704
706
|
const stopped = await f.orchestrator.stop("reset");
|
|
705
707
|
const second = await f.orchestrator.advance();
|
|
706
708
|
|
|
707
709
|
assert.equal(first.kind, "advanced");
|
|
708
|
-
assert.equal(
|
|
710
|
+
assert.equal(idempotent.kind, "skipped");
|
|
709
711
|
assert.equal(stopped.kind, "stopped");
|
|
710
712
|
assert.equal(second.kind, "advanced");
|
|
711
713
|
});
|
|
712
714
|
|
|
713
|
-
test("
|
|
715
|
+
test("idempotent path journals advance-skipped and records a health snapshot", async (t) => {
|
|
714
716
|
const f = makeFixture();
|
|
715
717
|
t.after(() => f.cleanup());
|
|
716
718
|
|
|
717
719
|
await f.orchestrator.advance();
|
|
718
720
|
await f.orchestrator.advance();
|
|
719
721
|
|
|
720
|
-
assert.ok(f.journalNames().includes("advance-
|
|
722
|
+
assert.ok(f.journalNames().includes("advance-skipped"));
|
|
721
723
|
});
|
|
722
724
|
|
|
723
725
|
// ─── Stuck-loop ring buffer (issue #5787) ──────────────────────────────────
|
|
724
726
|
|
|
725
|
-
test("STUCK_WINDOW_SIZE matches the legacy auto/phases.ts constant", () => {
|
|
726
|
-
assert.equal(STUCK_WINDOW_SIZE, 6);
|
|
727
|
-
});
|
|
728
|
-
|
|
729
727
|
test("stuck-loop: empty ring on a freshly constructed orchestrator advances normally", async (t) => {
|
|
730
728
|
const f = makeFixture();
|
|
731
729
|
t.after(() => f.cleanup());
|
|
@@ -761,21 +759,24 @@ test("stuck-loop: ring saturated with same unit blocks with action 'stop' and st
|
|
|
761
759
|
// First call advances.
|
|
762
760
|
assert.equal(results[0].kind, "advanced");
|
|
763
761
|
|
|
764
|
-
// Intermediate calls are
|
|
762
|
+
// Intermediate calls are skipped by idempotency (not stuck-loop yet).
|
|
765
763
|
for (let i = 1; i < STUCK_WINDOW_SIZE - 1; i++) {
|
|
766
764
|
const r = results[i];
|
|
767
|
-
assert.equal(r.kind, "
|
|
768
|
-
if (r.kind !== "
|
|
765
|
+
assert.equal(r.kind, "skipped", `round ${i} should be skipped`);
|
|
766
|
+
if (r.kind !== "skipped") return;
|
|
769
767
|
assert.equal(r.reason, "idempotent advance: unit already active");
|
|
770
|
-
assert.equal(r.action, "pause");
|
|
771
768
|
}
|
|
772
769
|
|
|
773
|
-
// The final call (ring now holds STUCK_WINDOW_SIZE copies) returns stuck-loop
|
|
770
|
+
// The final call (ring now holds STUCK_WINDOW_SIZE copies) returns stuck-loop
|
|
771
|
+
// with the detect-stuck rule verdict in the reason.
|
|
774
772
|
const last = results[STUCK_WINDOW_SIZE - 1];
|
|
775
773
|
assert.equal(last.kind, "blocked");
|
|
776
774
|
if (last.kind !== "blocked") return;
|
|
777
775
|
assert.equal(last.action, "stop");
|
|
778
|
-
assert.
|
|
776
|
+
assert.ok(
|
|
777
|
+
last.reason.startsWith("stuck-loop: execute-task:M001/S01/T01 derived"),
|
|
778
|
+
`expected detect-stuck verdict reason, got: ${last.reason}`,
|
|
779
|
+
);
|
|
779
780
|
});
|
|
780
781
|
|
|
781
782
|
test("stuck-loop: start() resets the ring so a fresh saturation cycle is required", async (t) => {
|
|
@@ -855,6 +856,80 @@ test("stuck-loop: stop('user-request') resets the ring (hard stop)", async (t) =
|
|
|
855
856
|
assert.equal(next.kind, "advanced");
|
|
856
857
|
});
|
|
857
858
|
|
|
859
|
+
test("stuck-loop #482 regression: start() rehydrates the window from the dispatch ledger so cross-session re-dispatch loops are detected", async (t) => {
|
|
860
|
+
const f = makeFixture();
|
|
861
|
+
t.after(() => f.cleanup());
|
|
862
|
+
|
|
863
|
+
// Simulate a PRIOR session: the dispatch ledger recorded the same unit
|
|
864
|
+
// being re-dispatched repeatedly without progress. The orchestrator under test is a
|
|
865
|
+
// fresh instance (as it would be after a session restart) — before the
|
|
866
|
+
// Dispatch History module, start() reset the window to [] and the loop
|
|
867
|
+
// would silently re-dispatch the unit forever (#482: 146 re-dispatches).
|
|
868
|
+
const worker = registerAutoWorker({ projectRootRealpath: normalizeRealPath(f.base) });
|
|
869
|
+
const lease = claimMilestoneLease(worker, "M001");
|
|
870
|
+
assert.equal(lease.ok, true);
|
|
871
|
+
if (!lease.ok) return;
|
|
872
|
+
for (let i = 0; i < STUCK_WINDOW_SIZE - 1; i++) {
|
|
873
|
+
const claim = recordDispatchClaim({
|
|
874
|
+
traceId: `prior-session-${i}`,
|
|
875
|
+
workerId: worker,
|
|
876
|
+
milestoneLeaseToken: lease.token,
|
|
877
|
+
milestoneId: "M001",
|
|
878
|
+
unitType: "execute-task",
|
|
879
|
+
unitId: "M001/S01/T01",
|
|
880
|
+
});
|
|
881
|
+
assert.equal(claim.ok, true);
|
|
882
|
+
if (!claim.ok) return;
|
|
883
|
+
markFailed(claim.dispatchId, { errorSummary: "" });
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
const started = await f.orchestrator.start(SESSION_CONTEXT);
|
|
887
|
+
assert.equal(started.kind, "started");
|
|
888
|
+
|
|
889
|
+
// The very next decision for the same unit must trip the stuck verdict
|
|
890
|
+
// instead of advancing.
|
|
891
|
+
const result = await f.orchestrator.advance();
|
|
892
|
+
assert.equal(result.kind, "blocked");
|
|
893
|
+
if (result.kind !== "blocked") return;
|
|
894
|
+
assert.equal(result.action, "stop");
|
|
895
|
+
assert.ok(result.reason.startsWith("stuck-loop:"), `expected stuck-loop reason, got: ${result.reason}`);
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
test("stuck-loop #482: resume() with an empty window rehydrates from the dispatch ledger", async (t) => {
|
|
899
|
+
const f = makeFixture();
|
|
900
|
+
t.after(() => f.cleanup());
|
|
901
|
+
|
|
902
|
+
const worker = registerAutoWorker({ projectRootRealpath: normalizeRealPath(f.base) });
|
|
903
|
+
const lease = claimMilestoneLease(worker, "M001");
|
|
904
|
+
assert.equal(lease.ok, true);
|
|
905
|
+
if (!lease.ok) return;
|
|
906
|
+
for (let i = 0; i < STUCK_WINDOW_SIZE - 1; i++) {
|
|
907
|
+
const claim = recordDispatchClaim({
|
|
908
|
+
traceId: `prior-session-resume-${i}`,
|
|
909
|
+
workerId: worker,
|
|
910
|
+
milestoneLeaseToken: lease.token,
|
|
911
|
+
milestoneId: "M001",
|
|
912
|
+
unitType: "execute-task",
|
|
913
|
+
unitId: "M001/S01/T01",
|
|
914
|
+
});
|
|
915
|
+
assert.equal(claim.ok, true);
|
|
916
|
+
if (!claim.ok) return;
|
|
917
|
+
markFailed(claim.dispatchId, { errorSummary: "" });
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// Fresh orchestrator resuming a prior session: window starts empty, so
|
|
921
|
+
// resume() must rehydrate (while in-process resume keeps the live window —
|
|
922
|
+
// see the #572 preservation tests above).
|
|
923
|
+
const resumed = await f.orchestrator.resume();
|
|
924
|
+
assert.equal(resumed.kind, "resumed");
|
|
925
|
+
|
|
926
|
+
const result = await f.orchestrator.advance();
|
|
927
|
+
assert.equal(result.kind, "blocked");
|
|
928
|
+
if (result.kind !== "blocked") return;
|
|
929
|
+
assert.equal(result.action, "stop");
|
|
930
|
+
assert.ok(result.reason.startsWith("stuck-loop:"), `expected stuck-loop reason, got: ${result.reason}`);
|
|
931
|
+
});
|
|
932
|
+
|
|
858
933
|
test("stuck-loop: journal records the stuck-loop reason on advance-blocked", async (t) => {
|
|
859
934
|
const f = makeFixture();
|
|
860
935
|
t.after(() => f.cleanup());
|
|
@@ -1148,6 +1223,103 @@ test("decideOrchestratorDispatch forwards constructor session when advance input
|
|
|
1148
1223
|
}
|
|
1149
1224
|
});
|
|
1150
1225
|
|
|
1226
|
+
test("decideOrchestratorDispatch evaluates deep pre-planning rules without an active milestone", async (t) => {
|
|
1227
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-orchestrator-no-active-"));
|
|
1228
|
+
t.after(() => {
|
|
1229
|
+
resetRegistry();
|
|
1230
|
+
rmSync(base, { recursive: true, force: true });
|
|
1231
|
+
});
|
|
1232
|
+
resetRegistry();
|
|
1233
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
1234
|
+
writeFileSync(
|
|
1235
|
+
join(base, ".gsd", "PREFERENCES.md"),
|
|
1236
|
+
[
|
|
1237
|
+
"---",
|
|
1238
|
+
"planning_depth: deep",
|
|
1239
|
+
"workflow_prefs_captured: true",
|
|
1240
|
+
"---",
|
|
1241
|
+
"",
|
|
1242
|
+
].join("\n"),
|
|
1243
|
+
);
|
|
1244
|
+
|
|
1245
|
+
const stateSnapshot: GSDState = {
|
|
1246
|
+
...makeState(),
|
|
1247
|
+
activeMilestone: null,
|
|
1248
|
+
phase: "pre-planning",
|
|
1249
|
+
nextAction: "All remaining milestones are parked (M027). Run /gsd unpark M027 or create a new milestone.",
|
|
1250
|
+
registry: [{ id: "M027", title: "Parked", status: "parked" }],
|
|
1251
|
+
};
|
|
1252
|
+
const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as never;
|
|
1253
|
+
const pi = { getActiveTools: () => [] } as never;
|
|
1254
|
+
const session = {
|
|
1255
|
+
basePath: base,
|
|
1256
|
+
originalBasePath: base,
|
|
1257
|
+
currentMilestoneId: "M027",
|
|
1258
|
+
} as never;
|
|
1259
|
+
|
|
1260
|
+
const result = await decideOrchestratorDispatch(ctx, pi, base, session, { stateSnapshot });
|
|
1261
|
+
|
|
1262
|
+
assert.ok(result && "unitType" in result, `expected project-level dispatch, got ${JSON.stringify(result)}`);
|
|
1263
|
+
assert.equal(result.unitType, "discuss-project");
|
|
1264
|
+
assert.equal(result.unitId, "PROJECT");
|
|
1265
|
+
});
|
|
1266
|
+
|
|
1267
|
+
test("decideOrchestratorDispatch does not replay milestone-scoped verification retry when no milestone is active", async (t) => {
|
|
1268
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-orchestrator-no-active-retry-"));
|
|
1269
|
+
t.after(() => {
|
|
1270
|
+
resetRegistry();
|
|
1271
|
+
rmSync(base, { recursive: true, force: true });
|
|
1272
|
+
});
|
|
1273
|
+
resetRegistry();
|
|
1274
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
1275
|
+
writeFileSync(
|
|
1276
|
+
join(base, ".gsd", "PREFERENCES.md"),
|
|
1277
|
+
[
|
|
1278
|
+
"---",
|
|
1279
|
+
"planning_depth: deep",
|
|
1280
|
+
"workflow_prefs_captured: true",
|
|
1281
|
+
"---",
|
|
1282
|
+
"",
|
|
1283
|
+
].join("\n"),
|
|
1284
|
+
);
|
|
1285
|
+
|
|
1286
|
+
const stateSnapshot: GSDState = {
|
|
1287
|
+
...makeState(),
|
|
1288
|
+
activeMilestone: null,
|
|
1289
|
+
phase: "pre-planning",
|
|
1290
|
+
nextAction: "All remaining milestones are parked (M027). Run /gsd unpark M027 or create a new milestone.",
|
|
1291
|
+
registry: [{ id: "M027", title: "Parked", status: "parked" }],
|
|
1292
|
+
};
|
|
1293
|
+
const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as never;
|
|
1294
|
+
const pi = { getActiveTools: () => [] } as never;
|
|
1295
|
+
const stalePendingRetry = {
|
|
1296
|
+
unitType: "execute-task",
|
|
1297
|
+
unitId: "M027.S1.T1",
|
|
1298
|
+
prompt: "stale retry prompt",
|
|
1299
|
+
pauseAfterUatDispatch: false,
|
|
1300
|
+
state: stateSnapshot,
|
|
1301
|
+
mid: "M027",
|
|
1302
|
+
midTitle: "Parked",
|
|
1303
|
+
};
|
|
1304
|
+
const session = {
|
|
1305
|
+
basePath: base,
|
|
1306
|
+
originalBasePath: base,
|
|
1307
|
+
currentMilestoneId: "M027",
|
|
1308
|
+
pendingVerificationRetryDispatch: stalePendingRetry,
|
|
1309
|
+
} as never;
|
|
1310
|
+
|
|
1311
|
+
const result = await decideOrchestratorDispatch(ctx, pi, base, session, { stateSnapshot });
|
|
1312
|
+
|
|
1313
|
+
assert.ok(result && "unitType" in result, `expected project-level dispatch, got ${JSON.stringify(result)}`);
|
|
1314
|
+
assert.equal(result.unitType, "discuss-project");
|
|
1315
|
+
assert.equal(result.unitId, "PROJECT");
|
|
1316
|
+
// The stale retry must be preserved for a future tick, not consumed by this
|
|
1317
|
+
// no-active-milestone path (mirrors pre-#712-fix behavior where !active
|
|
1318
|
+
// returned null before touching the retry).
|
|
1319
|
+
const sess = session as unknown as { pendingVerificationRetryDispatch: unknown };
|
|
1320
|
+
assert.equal(sess.pendingVerificationRetryDispatch, stalePendingRetry);
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1151
1323
|
test("decideOrchestratorDispatch adopts next active milestone after the session milestone is closed", async (t) => {
|
|
1152
1324
|
const base = mkdtempSync(join(tmpdir(), "gsd-orchestrator-milestone-adopt-"));
|
|
1153
1325
|
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
@@ -306,7 +306,9 @@ test("pauseAuto records the expected worktree path when paused from project root
|
|
|
306
306
|
|
|
307
307
|
const meta = readPausedSessionMetadata(base);
|
|
308
308
|
assert.ok(meta);
|
|
309
|
-
|
|
309
|
+
// No worktree exists yet, so the recorded path is the canonical
|
|
310
|
+
// .gsd-worktrees/ creation location (worktree-placement seam).
|
|
311
|
+
assert.equal(meta.worktreePath, join(base, ".gsd-worktrees", "M001"));
|
|
310
312
|
} finally {
|
|
311
313
|
autoSession.reset();
|
|
312
314
|
try {
|
|
@@ -88,3 +88,49 @@ test("detects session execution tools supported by the evidence collector", () =
|
|
|
88
88
|
|
|
89
89
|
assert.equal(_hasExecutionToolCallsInSessionForTest(entries), true);
|
|
90
90
|
});
|
|
91
|
+
|
|
92
|
+
test("detects execution tool calls in bare agent-end messages (no session-entry wrapper)", () => {
|
|
93
|
+
// The auto loop passes opts.agentEndMessages as bare {role, content}
|
|
94
|
+
// messages — not {type: "message", message} session-manager entries.
|
|
95
|
+
const entries = [
|
|
96
|
+
{
|
|
97
|
+
role: "assistant",
|
|
98
|
+
content: [
|
|
99
|
+
{
|
|
100
|
+
type: "toolCall",
|
|
101
|
+
name: "Bash",
|
|
102
|
+
arguments: { command: "test -s index.html && grep -q localStorage index.html" },
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
assert.equal(_hasExecutionToolCallsInSessionForTest(entries), true);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("does not suppress for bare agent-end messages without execution tools", () => {
|
|
112
|
+
const entries = [
|
|
113
|
+
{
|
|
114
|
+
role: "assistant",
|
|
115
|
+
content: [
|
|
116
|
+
{ type: "text", text: "Task complete." },
|
|
117
|
+
{ type: "toolCall", name: "Write", arguments: { file_path: "index.html" } },
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
assert.equal(_hasExecutionToolCallsInSessionForTest(entries), false);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("ignores bare user messages with toolCall-shaped content", () => {
|
|
126
|
+
const entries = [
|
|
127
|
+
{
|
|
128
|
+
role: "user",
|
|
129
|
+
content: [
|
|
130
|
+
{ type: "toolCall", name: "bash", arguments: { command: "echo hi" } },
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
assert.equal(_hasExecutionToolCallsInSessionForTest(entries), false);
|
|
136
|
+
});
|
|
@@ -184,7 +184,7 @@ describe("auto-worktree workspace registry", () => {
|
|
|
184
184
|
git(["commit", "-m", "add milestone"], tempDir);
|
|
185
185
|
|
|
186
186
|
createAutoWorktree(tempDir, "M003");
|
|
187
|
-
const wtDir = join(tempDir, ".gsd
|
|
187
|
+
const wtDir = join(tempDir, ".gsd-worktrees", "M003");
|
|
188
188
|
writeFileSync(join(wtDir, "feature.txt"), "implemented\n");
|
|
189
189
|
git(["add", "feature.txt"], wtDir);
|
|
190
190
|
git(["commit", "-m", "feat: implement M003"], wtDir);
|
|
@@ -216,7 +216,7 @@ describe("auto-worktree workspace registry", () => {
|
|
|
216
216
|
git(["commit", "-m", "add milestone"], tempDir);
|
|
217
217
|
|
|
218
218
|
createAutoWorktree(tempDir, "M004");
|
|
219
|
-
const wtDir = join(tempDir, ".gsd
|
|
219
|
+
const wtDir = join(tempDir, ".gsd-worktrees", "M004");
|
|
220
220
|
writeFileSync(join(wtDir, "feature.txt"), "implemented\n");
|
|
221
221
|
git(["add", "feature.txt"], wtDir);
|
|
222
222
|
git(["commit", "-m", "feat: implement M004"], wtDir);
|
|
@@ -35,7 +35,8 @@ test("repair target accepts a missing expected milestone worktree", () => {
|
|
|
35
35
|
|
|
36
36
|
assert.equal(result.ok, true);
|
|
37
37
|
if (result.ok) {
|
|
38
|
-
|
|
38
|
+
// No worktree exists yet, so the expected path is the canonical container.
|
|
39
|
+
assert.equal(result.expectedPath, join(base, ".gsd-worktrees", "M001"));
|
|
39
40
|
}
|
|
40
41
|
} finally {
|
|
41
42
|
cleanup(base);
|
|
@@ -192,7 +193,8 @@ test("paused metadata path resolves to the expected worktree while paused at pro
|
|
|
192
193
|
baseIsAutoWorktree: false,
|
|
193
194
|
});
|
|
194
195
|
|
|
195
|
-
|
|
196
|
+
// No worktree exists yet, so resolution lands at the canonical container.
|
|
197
|
+
assert.equal(result, join(base, ".gsd-worktrees", "M001"));
|
|
196
198
|
} finally {
|
|
197
199
|
cleanup(base);
|
|
198
200
|
}
|
|
@@ -8,7 +8,10 @@ import { join } from "node:path";
|
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
blockModel,
|
|
11
|
+
blockModelUntil,
|
|
12
|
+
clearTemporaryModelBlocksForTest,
|
|
11
13
|
isModelBlocked,
|
|
14
|
+
isModelTemporarilyUnavailable,
|
|
12
15
|
loadBlockedModels,
|
|
13
16
|
} from "../blocked-models.ts";
|
|
14
17
|
|
|
@@ -96,3 +99,19 @@ test("blocked-models: file created under .gsd/runtime/", () => {
|
|
|
96
99
|
rmSync(base, { recursive: true, force: true });
|
|
97
100
|
}
|
|
98
101
|
});
|
|
102
|
+
|
|
103
|
+
test("blocked-models: temporary rate-limit blocks expire without persisting", () => {
|
|
104
|
+
const base = mkBase();
|
|
105
|
+
try {
|
|
106
|
+
clearTemporaryModelBlocksForTest();
|
|
107
|
+
blockModelUntil(base, "openai-codex", "gpt-5.5", Date.now() + 60_000, "session limit");
|
|
108
|
+
assert.equal(isModelTemporarilyUnavailable(base, "openai-codex", "gpt-5.5"), true);
|
|
109
|
+
assert.equal(loadBlockedModels(base).length, 0, "rate-limit windows must not persist as account blocks");
|
|
110
|
+
|
|
111
|
+
blockModelUntil(base, "openai-codex", "gpt-5.5", Date.now() - 1, "expired");
|
|
112
|
+
assert.equal(isModelTemporarilyUnavailable(base, "openai-codex", "gpt-5.5"), false);
|
|
113
|
+
} finally {
|
|
114
|
+
clearTemporaryModelBlocksForTest();
|
|
115
|
+
rmSync(base, { recursive: true, force: true });
|
|
116
|
+
}
|
|
117
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getUatBrowserToolSupportError,
|
|
5
|
+
hasUatBrowserToolSurface,
|
|
6
|
+
type UatType,
|
|
7
|
+
} from "../uat-policy.ts";
|
|
8
|
+
|
|
9
|
+
export const BROWSER_AUTOMATION_CONTRACT_TOOLS = {
|
|
10
|
+
piProvider: ["read", "browser_navigate"],
|
|
11
|
+
externalMcpClient: ["read", "mcp__gsd-browser__browser_navigate"],
|
|
12
|
+
externalMcpWildcard: ["read", "mcp__gsd-browser__*"],
|
|
13
|
+
otherBrowserMcp: ["read", "mcp__browser-uat__*"],
|
|
14
|
+
workflowOnly: ["read", "mcp__gsd-workflow__*"],
|
|
15
|
+
withoutBrowser: ["read", "gsd_uat_exec"],
|
|
16
|
+
} as const;
|
|
17
|
+
|
|
18
|
+
export function assertBrowserAutomationContractAvailable(tools: readonly string[]): void {
|
|
19
|
+
assert.equal(hasUatBrowserToolSurface(tools), true, `${tools.join(", ")} should satisfy the Browser Automation Contract`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function assertBrowserAutomationContractMissing(tools: readonly string[] | undefined): void {
|
|
23
|
+
assert.equal(hasUatBrowserToolSurface(tools), false, `${tools?.join(", ") ?? "undefined"} should not satisfy the Browser Automation Contract`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function assertBrowserBackedUatCanDispatch(options: {
|
|
27
|
+
uatType: UatType;
|
|
28
|
+
activeTools: readonly string[] | undefined;
|
|
29
|
+
registeredTools?: readonly string[];
|
|
30
|
+
}): void {
|
|
31
|
+
assert.equal(
|
|
32
|
+
getUatBrowserToolSupportError({
|
|
33
|
+
...options,
|
|
34
|
+
milestoneId: "M001",
|
|
35
|
+
sliceId: "S01",
|
|
36
|
+
}),
|
|
37
|
+
null,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
BROWSER_CONTRACT_TOOL_NAMES,
|
|
6
|
+
BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES,
|
|
7
|
+
hasBrowserContractPrefix,
|
|
8
|
+
isBrowserContractToolName,
|
|
9
|
+
} from "../../shared/browser-contract.ts";
|
|
10
|
+
import { isUatBrowserToolName } from "../uat-policy.ts";
|
|
11
|
+
import { BROWSER_REQUIREMENT_RE, BROWSER_RUNTIME_RE } from "../browser-evidence.ts";
|
|
12
|
+
|
|
13
|
+
// Note: RUN_UAT_BROWSER_TOOL_NAMES and MANAGED_GSD_BROWSER_TOOL_NAMES are
|
|
14
|
+
// reference-equal aliases of BROWSER_CONTRACT_TOOL_NAMES, and the managed
|
|
15
|
+
// adapter's spec table is Record-keyed by BrowserContractToolName — both
|
|
16
|
+
// derivations are pinned by the type system, not by runtime assertions here.
|
|
17
|
+
describe("Browser Automation Contract parity", () => {
|
|
18
|
+
it("every contract name satisfies the UAT browser-tool predicate, bare and MCP-prefixed", () => {
|
|
19
|
+
for (const name of BROWSER_CONTRACT_TOOL_NAMES) {
|
|
20
|
+
assert.equal(isUatBrowserToolName(name), true, name);
|
|
21
|
+
assert.equal(isUatBrowserToolName(`mcp__gsd-browser__${name}`), true, `mcp__gsd-browser__${name}`);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("contract names are canonical browser_* names with no duplicates", () => {
|
|
26
|
+
assert.equal(new Set(BROWSER_CONTRACT_TOOL_NAMES).size, BROWSER_CONTRACT_TOOL_NAMES.length);
|
|
27
|
+
for (const name of BROWSER_CONTRACT_TOOL_NAMES) {
|
|
28
|
+
assert.equal(hasBrowserContractPrefix(name), true, name);
|
|
29
|
+
assert.equal(isBrowserContractToolName(name), true, name);
|
|
30
|
+
}
|
|
31
|
+
assert.equal(isBrowserContractToolName("browser_not_a_real_tool"), false);
|
|
32
|
+
assert.equal(hasBrowserContractPrefix("gsd_uat_exec"), false);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("evidence-signal names stay a subset of the contract and drive the detection regexes", () => {
|
|
36
|
+
for (const name of BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES) {
|
|
37
|
+
assert.equal(isBrowserContractToolName(name), true, name);
|
|
38
|
+
// Identifier-shaped names keep the regex splice in browser-evidence.ts escape-free.
|
|
39
|
+
assert.match(name, /^browser_[a-z_]+$/);
|
|
40
|
+
assert.match(`Verified via ${name} call`, BROWSER_REQUIREMENT_RE);
|
|
41
|
+
assert.match(`Verified via ${name} call`, BROWSER_RUNTIME_RE);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|