@opengsd/gsd-pi 1.2.0-dev.4c756166 → 1.2.0-dev.5457a158
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 +7 -29
- 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/extensions/bg-shell/utilities.js +5 -2
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +35 -4
- package/dist/resources/extensions/gsd/auto/orchestrator.js +33 -4
- package/dist/resources/extensions/gsd/auto/phases.js +6 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +19 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +3 -0
- package/dist/resources/extensions/gsd/auto-start.js +12 -14
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +7 -16
- 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 +8 -20
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +9 -6
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +86 -6
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +30 -4
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- package/dist/resources/extensions/gsd/captures.js +5 -15
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- 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 +372 -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/doctor-environment.js +5 -11
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
- package/dist/resources/extensions/gsd/error-classifier.js +9 -0
- 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-db.js +171 -2048
- package/dist/resources/extensions/gsd/guidance.js +98 -0
- package/dist/resources/extensions/gsd/guided-flow.js +51 -5
- 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/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/paths.js +37 -24
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +12 -46
- package/dist/resources/extensions/gsd/preferences.js +14 -0
- 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/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/recovery-classification.js +41 -87
- 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 +1 -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-surface-readiness.js +56 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -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/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +9 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +350 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- 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 +9 -1
- 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/skills/gsd-browser/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- 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/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/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 +9 -9
- 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 +1 -1
- package/dist/web/standalone/.next/server/middleware-build-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/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/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/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/workflow-tools.d.ts +8 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +46 -21
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +294 -239
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +260 -256
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +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/package.json +7 -7
- 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/extensions/bg-shell/utilities.ts +5 -2
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +37 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +39 -5
- package/src/resources/extensions/gsd/auto/phases.ts +10 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +25 -7
- package/src/resources/extensions/gsd/auto-prompts.ts +3 -0
- package/src/resources/extensions/gsd/auto-start.ts +12 -15
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +10 -17
- 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 +20 -24
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +10 -6
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +87 -6
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +29 -3
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- package/src/resources/extensions/gsd/captures.ts +5 -16
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- 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 +453 -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/doctor-environment.ts +5 -13
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
- package/src/resources/extensions/gsd/error-classifier.ts +11 -0
- 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-db.ts +173 -2373
- package/src/resources/extensions/gsd/guidance.ts +139 -0
- package/src/resources/extensions/gsd/guided-flow.ts +50 -5
- 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/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/paths.ts +42 -22
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +10 -46
- package/src/resources/extensions/gsd/preferences.ts +18 -0
- 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/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/recovery-classification.ts +47 -88
- 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 +4 -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-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/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/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/guidance.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +51 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +54 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- 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/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/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +23 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
- 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.test.ts +42 -0
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
- package/src/resources/extensions/gsd/tools/exec-tool.ts +5 -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/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +12 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +425 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- 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 +10 -1
- 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/skills/gsd-browser/SKILL.md +1 -1
- /package/dist/web/standalone/.next/static/{DUFWcMFRH3iXh7d2fbrOF → 2p9Rv9pQflAxCBbGVI2vb}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{DUFWcMFRH3iXh7d2fbrOF → 2p9Rv9pQflAxCBbGVI2vb}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability-patches.d.ts","sourceRoot":"","sources":["../../src/core/capability-patches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE7C,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,KAAK,eAAe,GAAG;IAAE,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC;IAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAEtF,eAAO,MAAM,kBAAkB,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"capability-patches.d.ts","sourceRoot":"","sources":["../../src/core/capability-patches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE7C,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,KAAK,eAAe,GAAG;IAAE,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC;IAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAEtF,eAAO,MAAM,kBAAkB,EAAE,eAAe,EAyB/C,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAe7E"}
|
|
@@ -16,7 +16,9 @@ export const CAPABILITY_PATCHES = [
|
|
|
16
16
|
m.id.includes("opus-4-7") ||
|
|
17
17
|
m.id.includes("opus-4.7") ||
|
|
18
18
|
m.id.includes("opus-4-8") ||
|
|
19
|
-
m.id.includes("opus-4.8")
|
|
19
|
+
m.id.includes("opus-4.8") ||
|
|
20
|
+
m.id.includes("fable-5") ||
|
|
21
|
+
m.id.includes("fable.5")),
|
|
20
22
|
caps: { supportsXhigh: true },
|
|
21
23
|
},
|
|
22
24
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability-patches.js","sourceRoot":"","sources":["../../src/core/capability-patches.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACpD;QACC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACZ,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACxB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACxB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;QACzB,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE;KACxD;IACD;QACC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;QACtC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;KAC7B;IACD;QACC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACZ,CAAC,CAAC,GAAG,KAAK,oBAAoB;YAC9B,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"capability-patches.js","sourceRoot":"","sources":["../../src/core/capability-patches.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACpD;QACC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACZ,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACxB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACxB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;QACzB,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE;KACxD;IACD;QACC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;QACtC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;KAC7B;IACD;QACC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACZ,CAAC,CAAC,GAAG,KAAK,oBAAoB;YAC9B,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;gBACzB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACxB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC3B,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;KAC7B;CACD,CAAC;AAEF,kEAAkE;AAClE,MAAM,UAAU,sBAAsB,CAAuB,MAAW;IACvE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3B,KAAK,MAAM,KAAK,IAAI,kBAAkB,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO;oBACN,GAAG,KAAK;oBACR,YAAY,EAAE;wBACb,GAAG,KAAK,CAAC,IAAI;wBACb,GAAI,KAAwD,CAAC,YAAY;qBACzE;iBACI,CAAC;YACR,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { Api, Model } from \"@gsd/pi-ai\";\n\n/** GSD extension: provider-agnostic capability flags on models. */\nexport interface ModelCapabilities {\n\tsupportsXhigh?: boolean;\n\trequiresToolCallId?: boolean;\n\tsupportsServiceTier?: boolean;\n\tcharsPerToken?: number;\n}\n\ntype CapabilityPatch = { match: (m: Model<Api>) => boolean; caps: ModelCapabilities };\n\nexport const CAPABILITY_PATCHES: CapabilityPatch[] = [\n\t{\n\t\tmatch: (m) =>\n\t\t\tm.id.includes(\"gpt-5.2\") ||\n\t\t\tm.id.includes(\"gpt-5.3\") ||\n\t\t\tm.id.includes(\"gpt-5.4\"),\n\t\tcaps: { supportsXhigh: true, supportsServiceTier: true },\n\t},\n\t{\n\t\tmatch: (m) => m.id.includes(\"gpt-5.5\"),\n\t\tcaps: { supportsXhigh: true },\n\t},\n\t{\n\t\tmatch: (m) =>\n\t\t\tm.api === \"anthropic-messages\" &&\n\t\t\t(m.id.includes(\"opus-4-6\") ||\n\t\t\t\tm.id.includes(\"opus-4.6\") ||\n\t\t\t\tm.id.includes(\"opus-4-7\") ||\n\t\t\t\tm.id.includes(\"opus-4.7\") ||\n\t\t\t\tm.id.includes(\"opus-4-8\") ||\n\t\t\t\tm.id.includes(\"opus-4.8\") ||\n\t\t\t\tm.id.includes(\"fable-5\") ||\n\t\t\t\tm.id.includes(\"fable.5\")),\n\t\tcaps: { supportsXhigh: true },\n\t},\n];\n\n/** Apply GSD capability patches after assembling a model list. */\nexport function applyCapabilityPatches<T extends Model<Api>>(models: T[]): T[] {\n\treturn models.map((model) => {\n\t\tfor (const patch of CAPABILITY_PATCHES) {\n\t\t\tif (patch.match(model)) {\n\t\t\t\treturn {\n\t\t\t\t\t...model,\n\t\t\t\t\tcapabilities: {\n\t\t\t\t\t\t...patch.caps,\n\t\t\t\t\t\t...(model as T & { capabilities?: Record<string, boolean> }).capabilities,\n\t\t\t\t\t},\n\t\t\t\t} as T;\n\t\t\t}\n\t\t}\n\t\treturn model;\n\t});\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gsd/pi-coding-agent",
|
|
3
|
-
"version": "1.2.0-dev.
|
|
3
|
+
"version": "1.2.0-dev.5457a158",
|
|
4
4
|
"description": "Coding agent CLI (vendored from earendil-works/pi)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"gsd": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"copy-assets": "node scripts/copy-assets.cjs"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@opengsd/contracts": "^1.2.0-dev.
|
|
36
|
+
"@opengsd/contracts": "^1.2.0-dev.5457a158",
|
|
37
37
|
"@mariozechner/jiti": "^2.6.2",
|
|
38
38
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
39
39
|
"chalk": "5.6.2",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"typebox": "1.1.38",
|
|
54
54
|
"undici": "7.26.0",
|
|
55
55
|
"yaml": "2.9.0",
|
|
56
|
-
"@gsd/agent-core": "^1.2.0-dev.
|
|
57
|
-
"@gsd/native": "^1.2.0-dev.
|
|
58
|
-
"@gsd/pi-agent-core": "^1.2.0-dev.
|
|
59
|
-
"@gsd/pi-ai": "^1.2.0-dev.
|
|
60
|
-
"@gsd/pi-tui": "^1.2.0-dev.
|
|
56
|
+
"@gsd/agent-core": "^1.2.0-dev.5457a158",
|
|
57
|
+
"@gsd/native": "^1.2.0-dev.5457a158",
|
|
58
|
+
"@gsd/pi-agent-core": "^1.2.0-dev.5457a158",
|
|
59
|
+
"@gsd/pi-ai": "^1.2.0-dev.5457a158",
|
|
60
|
+
"@gsd/pi-tui": "^1.2.0-dev.5457a158",
|
|
61
61
|
"@sinclair/typebox": "^0.34.41"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gsd/pi-tui",
|
|
3
|
-
"version": "1.2.0-dev.
|
|
3
|
+
"version": "1.2.0-dev.5457a158",
|
|
4
4
|
"description": "Terminal UI library (vendored from earendil-works/pi)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"gsd": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"build": "node ../../scripts/clean-package-dist.cjs && tsc -p tsconfig.json --incremental false"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@gsd/native": "^1.2.0-dev.
|
|
24
|
+
"@gsd/native": "^1.2.0-dev.5457a158",
|
|
25
25
|
"get-east-asian-width": "1.6.0",
|
|
26
26
|
"marked": "15.0.12",
|
|
27
27
|
"@sinclair/typebox": "^0.34.41"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengsd/rpc-client",
|
|
3
|
-
"version": "1.2.0-dev.
|
|
3
|
+
"version": "1.2.0-dev.5457a158",
|
|
4
4
|
"description": "Standalone RPC client SDK for GSD — zero internal dependencies",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"gsd": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"test": "node --test dist/rpc-client.test.js"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@opengsd/contracts": "^1.2.0-dev.
|
|
37
|
+
"@opengsd/contracts": "^1.2.0-dev.5457a158"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
|
40
40
|
"node": ">=22.0.0"
|
package/pkg/package.json
CHANGED
|
@@ -43,9 +43,12 @@ export function formatTimeAgo(timestamp: number): string {
|
|
|
43
43
|
return formatDuration(Date.now() - timestamp) + " ago";
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// NOTE: these worktree-layout regexes mirror findWorktreeSegment in
|
|
47
|
+
// src/resources/extensions/gsd/worktree-root.ts (bg-shell does not import the
|
|
48
|
+
// gsd extension). Keep them synchronized when a layout changes.
|
|
46
49
|
function deriveProjectRootFromAutoWorktree(cachedCwd?: string): string | undefined {
|
|
47
50
|
if (!cachedCwd) return undefined;
|
|
48
|
-
const match = cachedCwd.match(/^(.*?)[\\/]\.gsd[\\/]worktrees[\\/][^\\/]+(?:[\\/].*)?$/);
|
|
51
|
+
const match = cachedCwd.match(/^(.*?)[\\/]\.gsd(?:-worktrees|[\\/]worktrees)[\\/][^\\/]+(?:[\\/].*)?$/);
|
|
49
52
|
return match?.[1];
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -84,7 +87,7 @@ export function resolveBgShellPersistenceCwd(
|
|
|
84
87
|
pathExists: (path: string) => boolean = existsSync,
|
|
85
88
|
): string {
|
|
86
89
|
const resolvedLiveCwd = liveCwd ?? getBgShellLiveCwd(cachedCwd, pathExists);
|
|
87
|
-
const cachedIsAutoWorktree = /(?:^|[\\/])\.gsd[\\/]worktrees[\\/]/.test(cachedCwd);
|
|
90
|
+
const cachedIsAutoWorktree = /(?:^|[\\/])\.gsd(?:-worktrees|[\\/]worktrees)[\\/]/.test(cachedCwd);
|
|
88
91
|
if (!cachedIsAutoWorktree) return cachedCwd;
|
|
89
92
|
if (cachedCwd === resolvedLiveCwd && pathExists(cachedCwd)) return cachedCwd;
|
|
90
93
|
if (!pathExists(cachedCwd)) return resolvedLiveCwd;
|
|
@@ -39,6 +39,15 @@ export const CLAUDE_CODE_MODELS = [
|
|
|
39
39
|
contextWindow: 1_000_000,
|
|
40
40
|
maxTokens: 128_000,
|
|
41
41
|
},
|
|
42
|
+
{
|
|
43
|
+
id: "claude-fable-5",
|
|
44
|
+
name: "Claude Fable 5 (via Claude Code)",
|
|
45
|
+
reasoning: true,
|
|
46
|
+
input: ["text", "image"] as ("text" | "image")[],
|
|
47
|
+
cost: ZERO_COST,
|
|
48
|
+
contextWindow: 1_000_000,
|
|
49
|
+
maxTokens: 128_000,
|
|
50
|
+
},
|
|
42
51
|
{
|
|
43
52
|
id: "claude-sonnet-4-6",
|
|
44
53
|
name: "Claude Sonnet 4.6 (via Claude Code)",
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
computeMcpDisallowedTools,
|
|
60
60
|
} from "../gsd/mcp-filter.js";
|
|
61
61
|
import { RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES, RUN_UAT_FORBIDDEN_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES, resolveToolPresentationPlan } from "../gsd/tool-presentation-plan.js";
|
|
62
|
+
import { getToolSurfaceReadinessError } from "../gsd/tool-surface-readiness.js";
|
|
62
63
|
import { showInterviewRound, type Question, type RoundResult } from "../shared/tui.js";
|
|
63
64
|
import type {
|
|
64
65
|
SDKAssistantMessage,
|
|
@@ -1542,6 +1543,8 @@ function modelSupportsAdaptiveThinking(modelId: string): boolean {
|
|
|
1542
1543
|
|| modelId.includes("opus-4.7")
|
|
1543
1544
|
|| modelId.includes("opus-4-8")
|
|
1544
1545
|
|| modelId.includes("opus-4.8")
|
|
1546
|
+
|| modelId.includes("fable-5")
|
|
1547
|
+
|| modelId.includes("fable.5")
|
|
1545
1548
|
|| modelId.includes("sonnet-4-6")
|
|
1546
1549
|
|| modelId.includes("sonnet-4.6")
|
|
1547
1550
|
|| modelId.includes("sonnet-4-7")
|
|
@@ -1567,6 +1570,8 @@ function mapThinkingLevelToAnthropicEffort(level: ThinkingLevel | undefined, mod
|
|
|
1567
1570
|
|| modelId.includes("opus-4.7")
|
|
1568
1571
|
|| modelId.includes("opus-4-8")
|
|
1569
1572
|
|| modelId.includes("opus-4.8")
|
|
1573
|
+
|| modelId.includes("fable-5")
|
|
1574
|
+
|| modelId.includes("fable.5")
|
|
1570
1575
|
) return "xhigh";
|
|
1571
1576
|
if (modelId.includes("opus-4-6") || modelId.includes("opus-4.6")) return "max";
|
|
1572
1577
|
return "high";
|
|
@@ -1899,6 +1904,8 @@ export function buildSdkOptions(
|
|
|
1899
1904
|
|| modelId.includes("opus-4.7")
|
|
1900
1905
|
|| modelId.includes("opus-4-8")
|
|
1901
1906
|
|| modelId.includes("opus-4.8")
|
|
1907
|
+
|| modelId.includes("fable-5")
|
|
1908
|
+
|| modelId.includes("fable.5")
|
|
1902
1909
|
) ? ["context-1m-2025-08-07"] : [],
|
|
1903
1910
|
...(thinkingConfig ?? {}),
|
|
1904
1911
|
...(effort ? { effort } : {}),
|
|
@@ -1992,8 +1999,9 @@ async function pumpSdkMessages(
|
|
|
1992
1999
|
: {}),
|
|
1993
2000
|
},
|
|
1994
2001
|
);
|
|
2002
|
+
const workflowMcpServerName = workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools);
|
|
1995
2003
|
const prompt = buildPromptFromContext(context, {
|
|
1996
|
-
workflowMcpServerName
|
|
2004
|
+
workflowMcpServerName,
|
|
1997
2005
|
browserMcpServerName: browserMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
|
|
1998
2006
|
});
|
|
1999
2007
|
const queryPrompt = buildSdkQueryPrompt(context, prompt);
|
|
@@ -2035,7 +2043,34 @@ async function pumpSdkMessages(
|
|
|
2035
2043
|
switch (msg.type) {
|
|
2036
2044
|
// -- Init --
|
|
2037
2045
|
case "system": {
|
|
2038
|
-
//
|
|
2046
|
+
// Tool Surface Readiness gate: the init message is the first (and
|
|
2047
|
+
// only) point where the session reports its live tool surface and
|
|
2048
|
+
// MCP server statuses. If the workflow server failed or has not
|
|
2049
|
+
// registered this Unit's required tools, abort before the first
|
|
2050
|
+
// model turn with a transient, recovery-classifiable error
|
|
2051
|
+
// (tool-unavailable → retry) instead of letting the model hit
|
|
2052
|
+
// "No such tool available" mid-Unit and improvise around it.
|
|
2053
|
+
const init = msg as unknown as {
|
|
2054
|
+
subtype?: string;
|
|
2055
|
+
tools?: string[];
|
|
2056
|
+
mcp_servers?: { name: string; status: string }[];
|
|
2057
|
+
};
|
|
2058
|
+
if (init.subtype === "init") {
|
|
2059
|
+
const readinessError = getToolSurfaceReadinessError({
|
|
2060
|
+
unitType: gsdPhase,
|
|
2061
|
+
workflowServerName: workflowMcpServerName,
|
|
2062
|
+
observation: { tools: init.tools ?? [], mcpServers: init.mcp_servers ?? [] },
|
|
2063
|
+
});
|
|
2064
|
+
if (readinessError) {
|
|
2065
|
+
controller.abort();
|
|
2066
|
+
stream.push({
|
|
2067
|
+
type: "error",
|
|
2068
|
+
reason: "error",
|
|
2069
|
+
error: makeErrorMessage(modelId, readinessError),
|
|
2070
|
+
});
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2039
2074
|
break;
|
|
2040
2075
|
}
|
|
2041
2076
|
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
autoInitClaudeCodeWorkflowMcp,
|
|
37
37
|
inferGsdPhaseFromContext,
|
|
38
38
|
} from "../stream-adapter.ts";
|
|
39
|
+
import { CLAUDE_CODE_MODELS } from "../models.ts";
|
|
39
40
|
import type { AssistantMessage, Context, Message } from "@gsd/pi-ai";
|
|
40
41
|
import type { SDKUserMessage } from "../sdk-types.ts";
|
|
41
42
|
import { _setAutoActiveForTest } from "../../gsd/auto.ts";
|
|
@@ -793,6 +794,33 @@ describe("stream-adapter — Claude Code external tool results", () => {
|
|
|
793
794
|
});
|
|
794
795
|
});
|
|
795
796
|
|
|
797
|
+
describe("claude-code-cli — Claude Fable 5 Opus-tier support", () => {
|
|
798
|
+
test("Fable 5 is exposed in the Claude Code model picker list", () => {
|
|
799
|
+
const fable = CLAUDE_CODE_MODELS.find((m) => m.id === "claude-fable-5");
|
|
800
|
+
assert.ok(fable, "claude-fable-5 must appear in CLAUDE_CODE_MODELS");
|
|
801
|
+
assert.equal(fable!.reasoning, true);
|
|
802
|
+
assert.equal(fable!.contextWindow, 1_000_000);
|
|
803
|
+
assert.equal(fable!.maxTokens, 128_000);
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
test("Fable 5 gets Opus-tier gates: xhigh effort, adaptive thinking, 1M-context beta", () => {
|
|
807
|
+
const options = buildSdkOptions("claude-fable-5", "test prompt", undefined, { reasoning: "xhigh" });
|
|
808
|
+
assert.equal(options.effort, "xhigh", "xhigh must pass through natively for Fable 5");
|
|
809
|
+
assert.deepEqual(options.thinking, { type: "adaptive" }, "Fable 5 must use adaptive thinking");
|
|
810
|
+
assert.ok(
|
|
811
|
+
Array.isArray(options.betas) && (options.betas as string[]).includes("context-1m-2025-08-07"),
|
|
812
|
+
"Fable 5 must enable the 1M-context beta",
|
|
813
|
+
);
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
test("non-Opus models do not receive Fable 5's Opus-tier gates", () => {
|
|
817
|
+
// Failure/contrast path: Haiku supports adaptive thinking but is not xhigh/1M-tier.
|
|
818
|
+
const options = buildSdkOptions("claude-haiku-4-5", "test prompt", undefined, { reasoning: "xhigh" });
|
|
819
|
+
assert.equal(options.effort, "high", "xhigh must clamp to high for non-Opus-tier models");
|
|
820
|
+
assert.deepEqual(options.betas, [], "Haiku must not enable the 1M-context beta");
|
|
821
|
+
});
|
|
822
|
+
});
|
|
823
|
+
|
|
796
824
|
describe("stream-adapter — session persistence (#2859)", () => {
|
|
797
825
|
test("buildSdkOptions enables persistSession by default", () => {
|
|
798
826
|
const options = buildSdkOptions("claude-sonnet-4-20250514", "test prompt");
|
|
@@ -143,7 +143,7 @@ export interface LoopDeps {
|
|
|
143
143
|
basePath: string,
|
|
144
144
|
mid: string,
|
|
145
145
|
) => void;
|
|
146
|
-
getIsolationMode: (basePath?: string) =>
|
|
146
|
+
getIsolationMode: (basePath?: string) => "none" | "worktree" | "branch";
|
|
147
147
|
getCurrentBranch: (basePath: string) => string;
|
|
148
148
|
autoWorktreeBranch: (milestoneId: string) => string;
|
|
149
149
|
resolveMilestoneFile: (
|
|
@@ -14,13 +14,14 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
|
14
14
|
|
|
15
15
|
import type { AutoAdvanceResult, AutoOrchestrationModule, AutoSessionContext, AutoStatus, AutoTerminalOutcome } from "./contracts.js";
|
|
16
16
|
import type { AutoSession, PendingOrchestrationDispatch } from "./session.js";
|
|
17
|
-
import type { GSDState } from "../types.js";
|
|
17
|
+
import type { GSDState, Phase } from "../types.js";
|
|
18
18
|
import type { MinimalModelRegistry } from "../context-budget.js";
|
|
19
19
|
|
|
20
20
|
type BlockedAdvanceResult = Extract<AutoAdvanceResult, { kind: "blocked" }>;
|
|
21
21
|
|
|
22
|
-
import { debugCount, debugTime } from "../debug-logger.js";
|
|
22
|
+
import { debugCount, debugLog, debugTime } from "../debug-logger.js";
|
|
23
23
|
import { reconcileBeforeDispatch } from "../state-reconciliation.js";
|
|
24
|
+
import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
|
|
24
25
|
import { resolveDispatch } from "../auto-dispatch.js";
|
|
25
26
|
import { classifyFailure } from "../recovery-classification.js";
|
|
26
27
|
import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
|
|
@@ -37,7 +38,7 @@ import { checkResourcesStale, autoWorktreeBranch, mergeMilestoneToMain } from ".
|
|
|
37
38
|
import { getSessionLockStatus } from "../session-lock.js";
|
|
38
39
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
39
40
|
import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
|
|
40
|
-
import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
|
|
41
|
+
import { loadEffectiveGSDPreferences, getIsolationMode, resolveEffectiveUnitIsolationMode } from "../preferences.js";
|
|
41
42
|
import {
|
|
42
43
|
detectWorktreeName,
|
|
43
44
|
getMainBranch,
|
|
@@ -330,6 +331,10 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
330
331
|
private lastAdvanceKey: string | null = null;
|
|
331
332
|
private lastFinalizedUnitKey: string | null = null;
|
|
332
333
|
private dispatchKeyWindow: string[] = [];
|
|
334
|
+
// ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
|
|
335
|
+
// the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
|
|
336
|
+
// so the first advance of a session has no edge to assert.
|
|
337
|
+
private lastDerivedPhase: Phase | null = null;
|
|
333
338
|
// #442: the unit key we last attempted graduated stuck-recovery for. Bounds
|
|
334
339
|
// recovery to one attempt per stuck episode per run (reset on start/resume/
|
|
335
340
|
// stop), mirroring the legacy Level-1-then-Level-2 escalation in phases.ts.
|
|
@@ -612,8 +617,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
612
617
|
// ── WorktreeAdapter (folded) ─────────────────────────────────────────────
|
|
613
618
|
|
|
614
619
|
private getEffectiveUnitIsolationMode(basePath: string): ReturnType<typeof getIsolationMode> {
|
|
615
|
-
|
|
616
|
-
|
|
620
|
+
return resolveEffectiveUnitIsolationMode(
|
|
621
|
+
getIsolationMode(basePath),
|
|
622
|
+
this.s.isolationDegraded,
|
|
623
|
+
this.s.strandedRecoveryIsolationMode,
|
|
624
|
+
);
|
|
617
625
|
}
|
|
618
626
|
|
|
619
627
|
private buildLifecycle(): WorktreeLifecycle {
|
|
@@ -724,6 +732,21 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
724
732
|
return { action: recovery.action, reason: recovery.reason };
|
|
725
733
|
}
|
|
726
734
|
|
|
735
|
+
/**
|
|
736
|
+
* ADR-030 Phase Transition Invariant (advisory mode). The matrix is an
|
|
737
|
+
* assertion, not a decision-maker — deriveState already chose the phase; we
|
|
738
|
+
* only observe illegal *derived* edges that survived reconciliation. The
|
|
739
|
+
* matrix is still a sparse hardening spec, so this is telemetry-only (no
|
|
740
|
+
* block) until it is expanded into a validated legal-edge graph. To enforce:
|
|
741
|
+
* `throw violation;` instead of logging — recovery-classification maps
|
|
742
|
+
* IllegalPhaseTransitionError to kind "illegal-transition" (escalate).
|
|
743
|
+
*/
|
|
744
|
+
private observePhaseTransition(from: Phase, to: Phase): void {
|
|
745
|
+
if (isLegalEdge(from, to)) return;
|
|
746
|
+
const violation = new IllegalPhaseTransitionError(from, to);
|
|
747
|
+
debugLog("phase-transition-advisory", { from, to, message: violation.message });
|
|
748
|
+
}
|
|
749
|
+
|
|
727
750
|
// ── Lifecycle verbs ──────────────────────────────────────────────────────
|
|
728
751
|
|
|
729
752
|
/**
|
|
@@ -787,6 +810,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
787
810
|
this.lastFinalizedUnitKey = null;
|
|
788
811
|
this.dispatchKeyWindow = [];
|
|
789
812
|
this.lastStuckRecoveryKey = null;
|
|
813
|
+
this.lastDerivedPhase = null;
|
|
790
814
|
this.status.phase = "running";
|
|
791
815
|
this.bumpTransition();
|
|
792
816
|
this.journalTransition({ name: "start" });
|
|
@@ -876,6 +900,12 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
876
900
|
return blocked;
|
|
877
901
|
}
|
|
878
902
|
|
|
903
|
+
const reconciledPhase = reconciliation.stateSnapshot.phase;
|
|
904
|
+
if (this.lastDerivedPhase !== null) {
|
|
905
|
+
this.observePhaseTransition(this.lastDerivedPhase, reconciledPhase);
|
|
906
|
+
}
|
|
907
|
+
this.lastDerivedPhase = reconciledPhase;
|
|
908
|
+
|
|
879
909
|
const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
|
|
880
910
|
if (!decision) {
|
|
881
911
|
const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
|
|
@@ -1146,6 +1176,9 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1146
1176
|
// Preserve dispatchKeyWindow across resume so stuck-loop detection
|
|
1147
1177
|
// accumulates across pause/resume cycles rather than resetting each time.
|
|
1148
1178
|
this.lastStuckRecoveryKey = null;
|
|
1179
|
+
// ADR-030: drop the prior "from" — the first advance after resume has no
|
|
1180
|
+
// edge to assert (avoids a false illegal-edge across the pause boundary).
|
|
1181
|
+
this.lastDerivedPhase = null;
|
|
1149
1182
|
this.status.phase = "running";
|
|
1150
1183
|
this.bumpTransition();
|
|
1151
1184
|
this.journalTransition({ name: "resume" });
|
|
@@ -1162,6 +1195,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1162
1195
|
this.status.activeUnit = undefined;
|
|
1163
1196
|
this.lastAdvanceKey = null;
|
|
1164
1197
|
this.lastFinalizedUnitKey = null;
|
|
1198
|
+
this.lastDerivedPhase = null;
|
|
1165
1199
|
// Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
|
|
1166
1200
|
// across pause/resume cycles. Only clear on a hard stop.
|
|
1167
1201
|
if (reason !== "pause") {
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type PreVerificationOpts,
|
|
21
21
|
} from "../auto-post-unit.js";
|
|
22
22
|
import { lastAssistantText } from "../user-input-boundary.js";
|
|
23
|
+
import { resolveEffectiveUnitIsolationMode } from "../preferences.js";
|
|
23
24
|
import type { Phase } from "../types.js";
|
|
24
25
|
import {
|
|
25
26
|
MAX_RECOVERY_CHARS,
|
|
@@ -362,7 +363,15 @@ async function validateSourceWriteWorktreeSafety(
|
|
|
362
363
|
if (!writesSource) return null;
|
|
363
364
|
|
|
364
365
|
const projectRoot = s.canonicalProjectRoot ?? resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
365
|
-
|
|
366
|
+
// A degraded session already fell back to the milestone branch in the
|
|
367
|
+
// project root — validating against the canonical worktree root there
|
|
368
|
+
// would fail every dispatch with a false invalid-root. The same applies
|
|
369
|
+
// to a stranded-recovery session that adopted the milestone branch.
|
|
370
|
+
const isolationMode = resolveEffectiveUnitIsolationMode(
|
|
371
|
+
deps.getIsolationMode(projectRoot),
|
|
372
|
+
s.isolationDegraded,
|
|
373
|
+
s.strandedRecoveryIsolationMode,
|
|
374
|
+
);
|
|
366
375
|
if (isolationMode !== "worktree") return null;
|
|
367
376
|
|
|
368
377
|
const safety = createWorktreeSafetyModule();
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
} from "./milestone-closeout.js";
|
|
73
73
|
import type { AutoSession, SidecarItem } from "./auto/session.js";
|
|
74
74
|
import { getEvidence, clearEvidenceFromDisk, isExecutionToolName } from "./safety/evidence-collector.js";
|
|
75
|
-
import { validateFileChanges } from "./safety/file-change-validator.js";
|
|
75
|
+
import { validateFileChanges, effectiveFileChangeAllowlist } from "./safety/file-change-validator.js";
|
|
76
76
|
import { crossReferenceEvidence, type ClaimedEvidence } from "./safety/evidence-cross-ref.js";
|
|
77
77
|
import { validateContent } from "./safety/content-validator.js";
|
|
78
78
|
import { resolveSafetyHarnessConfig } from "./safety/safety-harness.js";
|
|
@@ -88,7 +88,7 @@ import { writeTurnGitTransaction } from "./uok/gitops.js";
|
|
|
88
88
|
import { isClosedStatus } from "./status-guards.js";
|
|
89
89
|
import { detectAbandonMilestone } from "./abandon-detect.js";
|
|
90
90
|
import { getPendingGate } from "./bootstrap/write-gate.js";
|
|
91
|
-
import { isDeterministicPolicyError } from "./auto-tool-tracking.js";
|
|
91
|
+
import { isDeterministicPolicyError, isToolUnavailableError } from "./auto-tool-tracking.js";
|
|
92
92
|
import { formatConnectedStepStack, formatPostUnitStatusCard } from "./auto-status-message.js";
|
|
93
93
|
import {
|
|
94
94
|
clearProjectResearchInflightMarker,
|
|
@@ -619,8 +619,10 @@ export function _hasExecutionToolCallsInSessionForTest(entries: readonly unknown
|
|
|
619
619
|
return true;
|
|
620
620
|
}
|
|
621
621
|
|
|
622
|
-
|
|
623
|
-
|
|
622
|
+
// Accept both session-manager entries ({type: "message", message}) and
|
|
623
|
+
// bare agent-end messages ({role, content}) — the auto loop passes the
|
|
624
|
+
// latter via opts.agentEndMessages.
|
|
625
|
+
const msg = e?.type === "message" ? e?.message : e;
|
|
624
626
|
if (!msg || msg.role !== "assistant" || !Array.isArray(msg.content)) continue;
|
|
625
627
|
for (const block of msg.content) {
|
|
626
628
|
if (block?.type !== "toolCall") continue;
|
|
@@ -1535,6 +1537,11 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1535
1537
|
if (safetyConfig.enabled) {
|
|
1536
1538
|
const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
|
|
1537
1539
|
|
|
1540
|
+
const fileChangeAllowlist = effectiveFileChangeAllowlist(
|
|
1541
|
+
safetyConfig.file_change_allowlist,
|
|
1542
|
+
(prefs?.git as { manage_gitignore?: boolean } | undefined)?.manage_gitignore,
|
|
1543
|
+
);
|
|
1544
|
+
|
|
1538
1545
|
// File change validation (execute-task only, after unit execution)
|
|
1539
1546
|
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
|
|
1540
1547
|
try {
|
|
@@ -1554,7 +1561,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1554
1561
|
files: taskRow.files,
|
|
1555
1562
|
})),
|
|
1556
1563
|
);
|
|
1557
|
-
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles,
|
|
1564
|
+
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, fileChangeAllowlist);
|
|
1558
1565
|
if (audit && audit.violations.length > 0) {
|
|
1559
1566
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
1560
1567
|
for (const v of warnings) {
|
|
@@ -1576,7 +1583,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1576
1583
|
s.basePath,
|
|
1577
1584
|
expectedOutput,
|
|
1578
1585
|
plannedFiles,
|
|
1579
|
-
|
|
1586
|
+
fileChangeAllowlist,
|
|
1580
1587
|
);
|
|
1581
1588
|
if (audit && audit.violations.length > 0) {
|
|
1582
1589
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
@@ -2015,7 +2022,18 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
2015
2022
|
"error",
|
|
2016
2023
|
);
|
|
2017
2024
|
} else if (!triggerArtifactVerified) {
|
|
2018
|
-
if (s.lastToolInvocationError) {
|
|
2025
|
+
if (s.lastToolInvocationError && isToolUnavailableError(s.lastToolInvocationError)) {
|
|
2026
|
+
// Tool-unavailable is the one transient invocation error: the
|
|
2027
|
+
// workflow MCP server registers its surface asynchronously, so a
|
|
2028
|
+
// Unit's first call can race the registration. Fall through to the
|
|
2029
|
+
// bounded verification retry instead of pausing.
|
|
2030
|
+
debugLog("postUnit", { phase: "tool-unavailable-retry", unitType: s.currentUnit.type, unitId: s.currentUnit.id, error: s.lastToolInvocationError });
|
|
2031
|
+
ctx.ui.notify(
|
|
2032
|
+
`Tool unavailable for ${s.currentUnit.type}: ${s.lastToolInvocationError}. The tool surface may still be registering — retrying.`,
|
|
2033
|
+
"warning",
|
|
2034
|
+
);
|
|
2035
|
+
s.lastToolInvocationError = null;
|
|
2036
|
+
} else if (s.lastToolInvocationError) {
|
|
2019
2037
|
const isUserSkip = /queued user message/i.test(s.lastToolInvocationError);
|
|
2020
2038
|
const errMsg = isUserSkip
|
|
2021
2039
|
? `Tool skipped for ${s.currentUnit.type}: ${s.lastToolInvocationError}. Queued user message interrupted the turn — pausing auto-mode.`
|
|
@@ -2470,6 +2470,9 @@ export async function buildPlanSlicePrompt(
|
|
|
2470
2470
|
`Either (a) add an earlier task that creates X on disk before the task that needs it, ` +
|
|
2471
2471
|
`or (b) if this task IS the one that creates X, move X from inputs to expected_output. ` +
|
|
2472
2472
|
`Do NOT put X in a task's expected_output if that task only reads or verifies X — only tasks that actually write X to disk should list it in expected_output.\n` +
|
|
2473
|
+
`- **"[file] X: ... GSD planning artifacts are projections preloaded as context / written by workflow tools"**: ` +
|
|
2474
|
+
`Remove X from the task's inputs, files, and expectedOutput entirely. Planning artifacts (anything under .gsd/, .planning/, or .audits/, or names like M001-CONTEXT.md / S01-PLAN.md) are preloaded as context and written by workflow tools — ` +
|
|
2475
|
+
`do NOT add a task that creates X and do NOT move X to expectedOutput.\n` +
|
|
2473
2476
|
`- **"[file] X: Task T_early reads X but it's created by task T_late (sequence violation)"**: ` +
|
|
2474
2477
|
`Either (a) reorder tasks so T_late (the creator) runs before T_early (the reader), ` +
|
|
2475
2478
|
`or (b) if T_late doesn't actually create X (it only reads/tests it), remove X from T_late's expected_output entirely.\n` +
|
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
ExtensionCommandContext,
|
|
17
17
|
} from "@gsd/pi-coding-agent";
|
|
18
18
|
import { deriveState } from "./state.js";
|
|
19
|
+
import { findWorktreeSegment, isGsdWorktreePath } from "./worktree-root.js";
|
|
19
20
|
import { loadFile, getManifestStatus } from "./files.js";
|
|
20
21
|
import type { InterruptedSessionAssessment } from "./interrupted-session.js";
|
|
21
22
|
import {
|
|
@@ -56,7 +57,8 @@ import {
|
|
|
56
57
|
detectWorktreeName,
|
|
57
58
|
setActiveMilestoneId,
|
|
58
59
|
} from "./worktree.js";
|
|
59
|
-
import { getAutoWorktreePath, isInAutoWorktree
|
|
60
|
+
import { getAutoWorktreePath, isInAutoWorktree } from "./auto-worktree.js";
|
|
61
|
+
import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
|
|
60
62
|
import { readResourceVersion, cleanStaleRuntimeUnits } from "./auto-worktree.js";
|
|
61
63
|
import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
|
|
62
64
|
import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
|
|
@@ -96,7 +98,6 @@ import {
|
|
|
96
98
|
rmSync,
|
|
97
99
|
} from "node:fs";
|
|
98
100
|
import { join } from "node:path";
|
|
99
|
-
import { sep as pathSep } from "node:path";
|
|
100
101
|
|
|
101
102
|
import { validateDirectory } from "./validate-directory.js";
|
|
102
103
|
import {
|
|
@@ -601,7 +602,7 @@ export function auditOrphanedMilestoneBranches(
|
|
|
601
602
|
warnings.push(`Failed to remove worktree directory for ${milestoneId}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
602
603
|
}
|
|
603
604
|
} else {
|
|
604
|
-
warnings.push(`Orphaned worktree directory for ${milestoneId} is outside
|
|
605
|
+
warnings.push(`Orphaned worktree directory for ${milestoneId} is outside the GSD worktrees containers — skipping removal for safety.`);
|
|
605
606
|
}
|
|
606
607
|
} else {
|
|
607
608
|
pushAction({
|
|
@@ -717,7 +718,7 @@ export function auditOrphanedMilestoneBranches(
|
|
|
717
718
|
if (!existsSync(wtDir)) continue;
|
|
718
719
|
if (!isInsideWorktreesDir(basePath, wtDir)) {
|
|
719
720
|
warnings.push(
|
|
720
|
-
`Orphaned worktree directory for ${m.id} is outside
|
|
721
|
+
`Orphaned worktree directory for ${m.id} is outside the GSD worktrees containers — skipping removal for safety.`,
|
|
721
722
|
);
|
|
722
723
|
continue;
|
|
723
724
|
}
|
|
@@ -1325,7 +1326,7 @@ export async function bootstrapAutoSession(
|
|
|
1325
1326
|
(state.phase === "pre-planning" || state.phase === "complete") &&
|
|
1326
1327
|
survivorIsolationMode !== "none" &&
|
|
1327
1328
|
!detectWorktreeName(base) &&
|
|
1328
|
-
!base
|
|
1329
|
+
!isGsdWorktreePath(base)
|
|
1329
1330
|
) {
|
|
1330
1331
|
const milestoneBranch = `milestone/${survivorMilestoneId}`;
|
|
1331
1332
|
const { nativeBranchExists } = await import("./native-git-bridge.js");
|
|
@@ -1610,16 +1611,12 @@ export async function bootstrapAutoSession(
|
|
|
1610
1611
|
// live here is gone.
|
|
1611
1612
|
|
|
1612
1613
|
const isUnderGsdWorktrees = (p: string): boolean => {
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
const symlinkRe = new RegExp(
|
|
1620
|
-
`\\${pathSep}\\.gsd\\${pathSep}projects\\${pathSep}[a-f0-9]+\\${pathSep}worktrees(?:\\${pathSep}|$)`,
|
|
1621
|
-
);
|
|
1622
|
-
return symlinkRe.test(p);
|
|
1614
|
+
const normalized = p.replaceAll("\\", "/");
|
|
1615
|
+
if (findWorktreeSegment(normalized) !== null) return true;
|
|
1616
|
+
// The container directory itself (no trailing worktree name), in any layout.
|
|
1617
|
+
return normalized.endsWith("/.gsd/worktrees")
|
|
1618
|
+
|| normalized.endsWith("/.gsd-worktrees")
|
|
1619
|
+
|| /\/\.gsd\/projects\/[^/]+\/worktrees$/.test(normalized);
|
|
1623
1620
|
};
|
|
1624
1621
|
|
|
1625
1622
|
if (
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { stripMcpToolPrefix } from "@gsd/pi-ai";
|
|
8
|
+
import { TOOL_SURFACE_NOT_READY } from "./tool-surface-readiness.js";
|
|
8
9
|
|
|
9
10
|
interface InFlightTool {
|
|
10
11
|
startedAt: number;
|
|
@@ -132,6 +133,15 @@ export function clearInFlightTools(): void {
|
|
|
132
133
|
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Input validation error|Invalid arguments for tool|MCP error -32602|No such tool available|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
|
|
133
134
|
const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
|
|
134
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Matches the runtime's "tool not registered" error. Unlike the deterministic
|
|
138
|
+
* invocation failures above, this one is usually transient: the workflow MCP
|
|
139
|
+
* server registers its tool surface asynchronously after session start, so a
|
|
140
|
+
* Unit's first tool call can race the registration. Callers should retry
|
|
141
|
+
* (bounded) instead of breaking the loop.
|
|
142
|
+
*/
|
|
143
|
+
const TOOL_UNAVAILABLE_ERROR_RE = new RegExp(`No such tool available|${TOOL_SURFACE_NOT_READY}`, "i");
|
|
144
|
+
|
|
135
145
|
/**
|
|
136
146
|
* Returns true if the error message indicates a deterministic invocation or
|
|
137
147
|
* policy failure (as opposed to a normal tool execution error).
|
|
@@ -141,6 +151,15 @@ export function isToolInvocationError(errorMsg: string): boolean {
|
|
|
141
151
|
return TOOL_INVOCATION_ERROR_RE.test(errorMsg) || isDeterministicPolicyError(errorMsg);
|
|
142
152
|
}
|
|
143
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Returns true if the error message indicates the called tool was not on the
|
|
156
|
+
* session's tool surface (MCP startup race — see TOOL_UNAVAILABLE_ERROR_RE).
|
|
157
|
+
*/
|
|
158
|
+
export function isToolUnavailableError(errorMsg: string): boolean {
|
|
159
|
+
if (!errorMsg) return false;
|
|
160
|
+
return TOOL_UNAVAILABLE_ERROR_RE.test(errorMsg);
|
|
161
|
+
}
|
|
162
|
+
|
|
144
163
|
/**
|
|
145
164
|
* Returns true if the error message indicates the tool was skipped because
|
|
146
165
|
* a queued user message interrupted the turn (#3595). Retrying will produce
|