gsd-pi 2.76.0-dev.fe143342a → 2.77.0-dev.1d17f366c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -35
- package/dist/claude-cli-check.js +32 -3
- package/dist/cli-web-branch.d.ts +1 -0
- package/dist/cli-web-branch.js +3 -0
- package/dist/cli.js +38 -2
- package/dist/extension-discovery.d.ts +6 -0
- package/dist/extension-discovery.js +37 -0
- package/dist/extension-registry.d.ts +3 -0
- package/dist/extension-sort.d.ts +18 -0
- package/dist/extension-sort.js +114 -0
- package/dist/extension-validator.d.ts +47 -0
- package/dist/extension-validator.js +127 -0
- package/dist/loader.js +35 -7
- package/dist/onboarding.js +45 -0
- package/dist/provider-migrations.d.ts +18 -0
- package/dist/provider-migrations.js +14 -0
- package/dist/resources/extensions/claude-code-cli/readiness.js +4 -3
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +78 -59
- package/dist/resources/extensions/cmux/index.js +20 -0
- package/dist/resources/extensions/github-sync/templates.js +103 -0
- package/dist/resources/extensions/google-search/extension-manifest.json +5 -4
- package/dist/resources/extensions/google-search/index.js +3 -375
- package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
- package/dist/resources/extensions/gsd/auto/loop.js +90 -2
- package/dist/resources/extensions/gsd/auto/phases.js +95 -21
- package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +48 -4
- package/dist/resources/extensions/gsd/auto/session.js +18 -1
- package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +115 -17
- package/dist/resources/extensions/gsd/auto-loop.js +1 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +1 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +90 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +46 -1
- package/dist/resources/extensions/gsd/auto-start.js +45 -39
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +109 -61
- package/dist/resources/extensions/gsd/auto.js +97 -31
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +27 -1
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +4 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +11 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -6
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -6
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
- package/dist/resources/extensions/gsd/commands-cmux.js +9 -6
- package/dist/resources/extensions/gsd/commands-extensions.js +634 -43
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
- package/dist/resources/extensions/gsd/dispatch-guard.js +29 -3
- package/dist/resources/extensions/gsd/file-lock.js +49 -9
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +2 -0
- package/dist/resources/extensions/gsd/gsd-db.js +90 -30
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
- package/dist/resources/extensions/gsd/guided-flow.js +212 -9
- package/dist/resources/extensions/gsd/health-widget.js +4 -1
- package/dist/resources/extensions/gsd/journal.js +17 -2
- package/dist/resources/extensions/gsd/key-manager.js +22 -0
- package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
- package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
- package/dist/resources/extensions/gsd/model-router.js +36 -3
- package/dist/resources/extensions/gsd/notifications.js +30 -16
- package/dist/resources/extensions/gsd/pre-execution-checks.js +31 -6
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +29 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/reports.js +5 -4
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +12 -4
- package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
- package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
- package/dist/resources/extensions/gsd/state.js +25 -25
- package/dist/resources/extensions/gsd/token-counter.js +22 -5
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
- package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
- package/dist/resources/extensions/gsd/uok/audit.js +18 -2
- package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
- package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
- package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
- package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
- package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +30 -7
- package/dist/resources/extensions/gsd/uok/writer.js +82 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
- package/dist/resources/extensions/mcp-client/auth.js +10 -1
- package/dist/resources/extensions/mcp-client/index.js +118 -9
- package/dist/resources/extensions/shared/cmux-events.js +12 -0
- package/dist/resources/extensions/shared/rtk-session-stats.js +1 -2
- package/dist/resources/skills/create-skill/SKILL.md +2 -2
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/dist/resources/skills/verify-before-complete/SKILL.md +2 -1
- package/dist/resources/skills/write-docs/SKILL.md +2 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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/notifications/route.js +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 +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 +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 +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 +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 +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 +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 +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 +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/skill-health/route.js +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 +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 +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 +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 +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 +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 +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/1926.js +1 -0
- package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/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/2826.e9f5195e91f9cad2.js +11 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-5fc74f13a25fa1bb.js → webpack-2e68521d7c82f7c2.js} +1 -1
- package/dist/welcome-screen.js +6 -1
- package/dist/wizard.js +2 -0
- package/package.json +16 -14
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +3 -3
- package/packages/mcp-server/dist/env-writer.d.ts +1 -0
- package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
- package/packages/mcp-server/dist/env-writer.js +74 -6
- package/packages/mcp-server/dist/env-writer.js.map +1 -1
- package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
- package/packages/mcp-server/dist/remote-questions.js +732 -0
- package/packages/mcp-server/dist/remote-questions.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +7 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +95 -10
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.d.ts +14 -0
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +49 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +15 -6
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +9 -3
- package/packages/mcp-server/src/env-writer.test.ts +79 -1
- package/packages/mcp-server/src/env-writer.ts +76 -6
- package/packages/mcp-server/src/mcp-server.test.ts +67 -0
- package/packages/mcp-server/src/readers/readers.test.ts +5 -1
- package/packages/mcp-server/src/remote-questions.test.ts +294 -0
- package/packages/mcp-server/src/remote-questions.ts +916 -0
- package/packages/mcp-server/src/server.ts +118 -16
- package/packages/mcp-server/src/session-manager.ts +43 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +44 -0
- package/packages/mcp-server/src/workflow-tools.ts +19 -6
- package/packages/mcp-server/tsconfig.test.json +19 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +6 -1
- package/packages/native/src/__tests__/clipboard.test.mjs +69 -23
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +6 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +220 -15
- package/packages/pi-ai/dist/models/custom.d.ts +38 -0
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/custom.js +41 -0
- package/packages/pi-ai/dist/models/custom.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +8 -3
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +16 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/package.json +6 -1
- package/packages/pi-ai/src/models/custom.ts +42 -0
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
- package/packages/pi-ai/src/providers/anthropic.ts +9 -3
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
- package/packages/pi-ai/src/providers/simple-options.ts +17 -1
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +7 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +105 -6
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +230 -28
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +30 -2
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +113 -12
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +29 -18
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +56 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +8 -15
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts +67 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js +167 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +3 -2
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +24 -8
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +14 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +11 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +14 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +21 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +3 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js +2 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +6 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
- package/packages/pi-coding-agent/src/core/agent-session.ts +11 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +368 -28
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +122 -6
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +111 -13
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +32 -18
- package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +68 -1
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +9 -18
- package/packages/pi-coding-agent/src/core/extensions/extension-discovery.ts +119 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-registry.ts +222 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +24 -11
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +15 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +13 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -2
- package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +16 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -1
- package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +30 -1
- package/packages/pi-coding-agent/src/core/session-manager.ts +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +3 -3
- package/packages/pi-coding-agent/src/core/tools/path-utils.test.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +14 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +12 -5
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +21 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +20 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +6 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -5
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +27 -0
- package/packages/pi-tui/src/stdin-buffer.ts +26 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +6 -1
- package/pkg/package.json +1 -1
- package/scripts/install.js +512 -0
- package/scripts/lib/workspace-manifest.cjs +86 -0
- package/scripts/link-workspace-packages.cjs +5 -17
- package/scripts/postinstall.js +9 -178
- package/src/resources/extensions/claude-code-cli/readiness.ts +4 -3
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +91 -63
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +114 -12
- package/src/resources/extensions/cmux/index.ts +35 -10
- package/src/resources/extensions/github-sync/templates.ts +151 -0
- package/src/resources/extensions/github-sync/tests/templates.test.ts +59 -0
- package/src/resources/extensions/google-search/extension-manifest.json +5 -4
- package/src/resources/extensions/google-search/index.ts +9 -470
- package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -1
- package/src/resources/extensions/gsd/auto/loop.ts +104 -2
- package/src/resources/extensions/gsd/auto/phases.ts +123 -21
- package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +56 -4
- package/src/resources/extensions/gsd/auto/session.ts +28 -1
- package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
- package/src/resources/extensions/gsd/auto/types.ts +1 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +117 -16
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +1 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +92 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +40 -1
- package/src/resources/extensions/gsd/auto-start.ts +48 -52
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +122 -68
- package/src/resources/extensions/gsd/auto.ts +105 -35
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -1
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -2
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +11 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +13 -9
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
- package/src/resources/extensions/gsd/commands-cmux.ts +10 -6
- package/src/resources/extensions/gsd/commands-extensions.ts +747 -41
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
- package/src/resources/extensions/gsd/dispatch-guard.ts +26 -2
- package/src/resources/extensions/gsd/file-lock.ts +84 -11
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +2 -1
- package/src/resources/extensions/gsd/gsd-db.ts +92 -32
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
- package/src/resources/extensions/gsd/guided-flow.ts +259 -10
- package/src/resources/extensions/gsd/health-widget.ts +3 -1
- package/src/resources/extensions/gsd/journal.ts +29 -3
- package/src/resources/extensions/gsd/key-manager.ts +22 -0
- package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
- package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
- package/src/resources/extensions/gsd/model-router.ts +42 -1
- package/src/resources/extensions/gsd/notifications.ts +27 -15
- package/src/resources/extensions/gsd/pre-execution-checks.ts +33 -7
- package/src/resources/extensions/gsd/preferences-types.ts +8 -0
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +29 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/reports.ts +5 -4
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +16 -3
- package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
- package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
- package/src/resources/extensions/gsd/state.ts +35 -30
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +238 -4
- package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/cmux.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +161 -0
- package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +1 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +14 -9
- package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
- package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +296 -1
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +337 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +39 -25
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +181 -0
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
- package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
- package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +42 -2
- package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/validate-extension-package.test.ts +168 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +138 -5
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +25 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
- package/src/resources/extensions/gsd/token-counter.ts +22 -5
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
- package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
- package/src/resources/extensions/gsd/uok/audit.ts +20 -2
- package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
- package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
- package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
- package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
- package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
- package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +39 -8
- package/src/resources/extensions/gsd/uok/writer.ts +113 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +23 -3
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
- package/src/resources/extensions/mcp-client/auth.ts +12 -1
- package/src/resources/extensions/mcp-client/index.ts +129 -10
- package/src/resources/extensions/shared/cmux-events.ts +59 -0
- package/src/resources/extensions/shared/rtk-session-stats.ts +1 -2
- package/src/resources/skills/create-skill/SKILL.md +2 -2
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/src/resources/skills/verify-before-complete/SKILL.md +2 -1
- package/src/resources/skills/write-docs/SKILL.md +2 -1
- package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
- /package/dist/web/standalone/.next/static/{n21VtX2hZlkpdEUO_nU4z → vidAVJkURvTJ0_V2-64ro}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{n21VtX2hZlkpdEUO_nU4z → vidAVJkURvTJ0_V2-64ro}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { Phase } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export type StateTransitionReasonCode =
|
|
4
|
+
| "state"
|
|
5
|
+
| "manual"
|
|
6
|
+
| "recovery"
|
|
7
|
+
| "dependency"
|
|
8
|
+
| "policy"
|
|
9
|
+
| "retry";
|
|
10
|
+
|
|
11
|
+
export interface StateTransitionEntry {
|
|
12
|
+
from: Phase | "*";
|
|
13
|
+
event: string;
|
|
14
|
+
guard: string;
|
|
15
|
+
to: Phase;
|
|
16
|
+
onFail: Phase | "manual-attention" | "blocked" | "no-transition";
|
|
17
|
+
reasonCode: StateTransitionReasonCode;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const STATE_TRANSITION_MATRIX: readonly StateTransitionEntry[] = [
|
|
21
|
+
{
|
|
22
|
+
from: "needs-discussion",
|
|
23
|
+
event: "context-ready",
|
|
24
|
+
guard: "CONTEXT artifact exists or PRD/context express path produced context",
|
|
25
|
+
to: "researching",
|
|
26
|
+
onFail: "needs-discussion",
|
|
27
|
+
reasonCode: "state",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
from: "researching",
|
|
31
|
+
event: "research-ready",
|
|
32
|
+
guard: "RESEARCH artifact exists or research is explicitly skipped",
|
|
33
|
+
to: "planning",
|
|
34
|
+
onFail: "researching",
|
|
35
|
+
reasonCode: "state",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
from: "planning",
|
|
39
|
+
event: "plan-ready",
|
|
40
|
+
guard: "ROADMAP/PLAN artifacts exist and plan gate passes",
|
|
41
|
+
to: "executing",
|
|
42
|
+
onFail: "replanning-slice",
|
|
43
|
+
reasonCode: "state",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
from: "executing",
|
|
47
|
+
event: "task-dispatched",
|
|
48
|
+
guard: "task inputs are ready and dependencies are closed",
|
|
49
|
+
to: "executing",
|
|
50
|
+
onFail: "blocked",
|
|
51
|
+
reasonCode: "dependency",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
from: "executing",
|
|
55
|
+
event: "slice-complete",
|
|
56
|
+
guard: "all slice tasks are closed and verification gate passes",
|
|
57
|
+
to: "summarizing",
|
|
58
|
+
onFail: "validating-milestone",
|
|
59
|
+
reasonCode: "state",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
from: "summarizing",
|
|
63
|
+
event: "summary-ready",
|
|
64
|
+
guard: "SUMMARY artifact exists for the completed work unit",
|
|
65
|
+
to: "validating-milestone",
|
|
66
|
+
onFail: "summarizing",
|
|
67
|
+
reasonCode: "state",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
from: "validating-milestone",
|
|
71
|
+
event: "validation-pass",
|
|
72
|
+
guard: "validation verdict is terminal and not remediation-required",
|
|
73
|
+
to: "completing-milestone",
|
|
74
|
+
onFail: "blocked",
|
|
75
|
+
reasonCode: "state",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
from: "blocked",
|
|
79
|
+
event: "recovery-plan-ready",
|
|
80
|
+
guard: "reassessment produced an executable next action",
|
|
81
|
+
to: "executing",
|
|
82
|
+
onFail: "blocked",
|
|
83
|
+
reasonCode: "recovery",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
from: "replanning-slice",
|
|
87
|
+
event: "replan-ready",
|
|
88
|
+
guard: "replacement slice/task plan exists and plan gate passes",
|
|
89
|
+
to: "executing",
|
|
90
|
+
onFail: "blocked",
|
|
91
|
+
reasonCode: "recovery",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
from: "completing-milestone",
|
|
95
|
+
event: "closeout-complete",
|
|
96
|
+
guard: "closeout gate passes and git transaction succeeds",
|
|
97
|
+
to: "complete",
|
|
98
|
+
onFail: "blocked",
|
|
99
|
+
reasonCode: "state",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
from: "*",
|
|
103
|
+
event: "manual-block",
|
|
104
|
+
guard: "operator or hard gate requested manual attention",
|
|
105
|
+
to: "blocked",
|
|
106
|
+
onFail: "manual-attention",
|
|
107
|
+
reasonCode: "manual",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
from: "*",
|
|
111
|
+
event: "retryable-failure",
|
|
112
|
+
guard: "retry budget remains for failure class",
|
|
113
|
+
to: "executing",
|
|
114
|
+
onFail: "blocked",
|
|
115
|
+
reasonCode: "retry",
|
|
116
|
+
},
|
|
117
|
+
] as const;
|
|
118
|
+
|
|
119
|
+
export interface MatrixValidationResult {
|
|
120
|
+
ok: boolean;
|
|
121
|
+
missingEvents: string[];
|
|
122
|
+
duplicateKeys: string[];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function findTransition(
|
|
126
|
+
from: Phase,
|
|
127
|
+
event: string,
|
|
128
|
+
): StateTransitionEntry | undefined {
|
|
129
|
+
return STATE_TRANSITION_MATRIX.find((entry) =>
|
|
130
|
+
(entry.from === from || entry.from === "*") && entry.event === event,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function validateTransitionMatrix(requiredEvents: readonly string[]): MatrixValidationResult {
|
|
135
|
+
const seen = new Set<string>();
|
|
136
|
+
const duplicateKeys: string[] = [];
|
|
137
|
+
|
|
138
|
+
for (const entry of STATE_TRANSITION_MATRIX) {
|
|
139
|
+
const key = `${entry.from}:${entry.event}`;
|
|
140
|
+
if (seen.has(key)) duplicateKeys.push(key);
|
|
141
|
+
seen.add(key);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const availableEvents = new Set(STATE_TRANSITION_MATRIX.map((entry) => entry.event));
|
|
145
|
+
const missingEvents = requiredEvents.filter((event) => !availableEvents.has(event));
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
ok: missingEvents.length === 0 && duplicateKeys.length === 0,
|
|
149
|
+
missingEvents,
|
|
150
|
+
duplicateKeys,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
@@ -46,6 +46,7 @@ import { logWarning, logError } from './workflow-logger.js';
|
|
|
46
46
|
import { extractVerdict } from './verdict-parser.js';
|
|
47
47
|
import { loadEffectiveGSDPreferences } from './preferences.js';
|
|
48
48
|
import { detectPendingEscalation } from './escalation.js';
|
|
49
|
+
import { isTerminalMilestoneSummaryContent } from './milestone-summary-classifier.js';
|
|
49
50
|
|
|
50
51
|
import {
|
|
51
52
|
isDbAvailable,
|
|
@@ -139,6 +140,14 @@ export function isValidationTerminal(validationContent: string): boolean {
|
|
|
139
140
|
return extractVerdict(validationContent) != null;
|
|
140
141
|
}
|
|
141
142
|
|
|
143
|
+
async function isTerminalMilestoneSummaryFile(
|
|
144
|
+
path: string,
|
|
145
|
+
loader: (path: string) => Promise<string | null>,
|
|
146
|
+
): Promise<boolean> {
|
|
147
|
+
const content = await loader(path);
|
|
148
|
+
return content != null && isTerminalMilestoneSummaryContent(content);
|
|
149
|
+
}
|
|
150
|
+
|
|
142
151
|
// ─── State Derivation ──────────────────────────────────────────────────────
|
|
143
152
|
|
|
144
153
|
// ── deriveState memoization ─────────────────────────────────────────────────
|
|
@@ -211,15 +220,15 @@ export async function getActiveMilestoneId(basePath: string): Promise<string | n
|
|
|
211
220
|
const content = roadmapFile ? await loadFile(roadmapFile) : null;
|
|
212
221
|
if (!content) {
|
|
213
222
|
const summaryFile = resolveMilestoneFile(basePath, mid, "SUMMARY");
|
|
214
|
-
if (summaryFile) continue;
|
|
223
|
+
if (summaryFile && await isTerminalMilestoneSummaryFile(summaryFile, loadFile)) continue;
|
|
215
224
|
if (isGhostMilestone(basePath, mid)) continue;
|
|
216
225
|
return mid;
|
|
217
226
|
}
|
|
218
227
|
const roadmap = parseRoadmap(content);
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
228
|
+
const summaryFile = resolveMilestoneFile(basePath, mid, "SUMMARY");
|
|
229
|
+
if (summaryFile && await isTerminalMilestoneSummaryFile(summaryFile, loadFile)) continue;
|
|
230
|
+
if (!isMilestoneComplete(roadmap)) return mid;
|
|
231
|
+
return mid;
|
|
223
232
|
}
|
|
224
233
|
return null;
|
|
225
234
|
}
|
|
@@ -668,7 +677,6 @@ function resolveSliceDependencies(activeMilestoneSlices: SliceRow[]): { activeSl
|
|
|
668
677
|
}
|
|
669
678
|
}
|
|
670
679
|
|
|
671
|
-
// First pass: find a slice with ALL dependencies satisfied (strict)
|
|
672
680
|
let bestFallback: SliceRow | null = null;
|
|
673
681
|
let bestFallbackSatisfied = -1;
|
|
674
682
|
|
|
@@ -678,7 +686,6 @@ function resolveSliceDependencies(activeMilestoneSlices: SliceRow[]): { activeSl
|
|
|
678
686
|
if (s.depends.every(dep => doneSliceIds.has(dep))) {
|
|
679
687
|
return { activeSlice: { id: s.id, title: s.title }, activeSliceRow: s };
|
|
680
688
|
}
|
|
681
|
-
// Track the slice with the most satisfied dependencies as fallback
|
|
682
689
|
const satisfied = s.depends.filter(dep => doneSliceIds.has(dep)).length;
|
|
683
690
|
if (satisfied > bestFallbackSatisfied || (satisfied === bestFallbackSatisfied && !bestFallback)) {
|
|
684
691
|
bestFallback = s;
|
|
@@ -686,16 +693,13 @@ function resolveSliceDependencies(activeMilestoneSlices: SliceRow[]): { activeSl
|
|
|
686
693
|
}
|
|
687
694
|
}
|
|
688
695
|
|
|
689
|
-
// Fallback: if no slice has all deps met but there ARE incomplete non-deferred
|
|
690
|
-
// slices, pick the one with the most deps satisfied. This prevents hard-blocking
|
|
691
|
-
// when dependency metadata is stale (e.g. after reassessment added/removed slices)
|
|
692
|
-
// or when deps reference slices from previous milestones.
|
|
693
696
|
if (bestFallback) {
|
|
694
697
|
const unmet = bestFallback.depends.filter(dep => !doneSliceIds.has(dep));
|
|
695
|
-
logWarning(
|
|
698
|
+
logWarning(
|
|
699
|
+
"state",
|
|
696
700
|
`No slice has all deps satisfied — falling back to ${bestFallback.id} ` +
|
|
697
|
-
|
|
698
|
-
|
|
701
|
+
`(${bestFallbackSatisfied}/${bestFallback.depends.length} deps met, ` +
|
|
702
|
+
`unmet: ${unmet.join(", ")})`,
|
|
699
703
|
{ mid: activeMilestoneSlices[0]?.milestone_id, sid: bestFallback.id },
|
|
700
704
|
);
|
|
701
705
|
return { activeSlice: { id: bestFallback.id, title: bestFallback.title }, activeSliceRow: bestFallback };
|
|
@@ -1160,7 +1164,7 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|
|
1160
1164
|
const rc = rf ? await cachedLoadFile(rf) : null;
|
|
1161
1165
|
if (!rc) {
|
|
1162
1166
|
const sf = resolveMilestoneFile(basePath, mid, "SUMMARY");
|
|
1163
|
-
if (sf) completeMilestoneIds.add(mid);
|
|
1167
|
+
if (sf && await isTerminalMilestoneSummaryFile(sf, cachedLoadFile)) completeMilestoneIds.add(mid);
|
|
1164
1168
|
continue;
|
|
1165
1169
|
}
|
|
1166
1170
|
const rmap = parseRoadmap(rc);
|
|
@@ -1169,11 +1173,11 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|
|
1169
1173
|
// Summary is the terminal artifact — if it exists, the milestone is
|
|
1170
1174
|
// complete even when roadmap checkboxes weren't ticked (#864).
|
|
1171
1175
|
const sf = resolveMilestoneFile(basePath, mid, "SUMMARY");
|
|
1172
|
-
if (sf) completeMilestoneIds.add(mid);
|
|
1176
|
+
if (sf && await isTerminalMilestoneSummaryFile(sf, cachedLoadFile)) completeMilestoneIds.add(mid);
|
|
1173
1177
|
continue;
|
|
1174
1178
|
}
|
|
1175
1179
|
const sf = resolveMilestoneFile(basePath, mid, "SUMMARY");
|
|
1176
|
-
if (sf) completeMilestoneIds.add(mid);
|
|
1180
|
+
if (sf && await isTerminalMilestoneSummaryFile(sf, cachedLoadFile)) completeMilestoneIds.add(mid);
|
|
1177
1181
|
}
|
|
1178
1182
|
|
|
1179
1183
|
// Phase 2: Build registry using cached roadmaps (no re-parsing or re-reading)
|
|
@@ -1201,12 +1205,14 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|
|
1201
1205
|
const summaryFile = resolveMilestoneFile(basePath, mid, "SUMMARY");
|
|
1202
1206
|
if (summaryFile) {
|
|
1203
1207
|
const summaryContent = await cachedLoadFile(summaryFile);
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1208
|
+
if (summaryContent != null && isTerminalMilestoneSummaryContent(summaryContent)) {
|
|
1209
|
+
const summaryTitle = summaryContent
|
|
1210
|
+
? (parseSummary(summaryContent).title || mid)
|
|
1211
|
+
: mid;
|
|
1212
|
+
registry.push({ id: mid, title: summaryTitle, status: 'complete' });
|
|
1213
|
+
completeMilestoneIds.add(mid);
|
|
1214
|
+
continue;
|
|
1215
|
+
}
|
|
1210
1216
|
}
|
|
1211
1217
|
// Ghost milestone (only META.json, no CONTEXT/ROADMAP/SUMMARY) — skip entirely
|
|
1212
1218
|
if (isGhostMilestone(basePath, mid)) continue;
|
|
@@ -1262,7 +1268,7 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|
|
1262
1268
|
// needs-remediation is terminal but requires re-validation (#3596)
|
|
1263
1269
|
const needsRevalidation = !validationTerminal || verdict === 'needs-remediation';
|
|
1264
1270
|
|
|
1265
|
-
if (summaryFile) {
|
|
1271
|
+
if (summaryFile && await isTerminalMilestoneSummaryFile(summaryFile, cachedLoadFile)) {
|
|
1266
1272
|
// Summary exists → milestone is complete regardless of validation state.
|
|
1267
1273
|
// The summary is the terminal artifact (#864).
|
|
1268
1274
|
registry.push({ id: mid, title, status: 'complete' });
|
|
@@ -1288,7 +1294,7 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|
|
1288
1294
|
// Roadmap slices not all checked — but if a summary exists, the milestone
|
|
1289
1295
|
// is still complete. The summary is the terminal artifact (#864).
|
|
1290
1296
|
const summaryFile = resolveMilestoneFile(basePath, mid, "SUMMARY");
|
|
1291
|
-
if (summaryFile) {
|
|
1297
|
+
if (summaryFile && await isTerminalMilestoneSummaryFile(summaryFile, cachedLoadFile)) {
|
|
1292
1298
|
registry.push({ id: mid, title, status: 'complete' });
|
|
1293
1299
|
} else if (!activeMilestoneFound) {
|
|
1294
1300
|
// Check milestone-level dependencies before promoting to active.
|
|
@@ -1572,7 +1578,6 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|
|
1572
1578
|
activeSlice = { id: s.id, title: s.title };
|
|
1573
1579
|
break;
|
|
1574
1580
|
}
|
|
1575
|
-
// Track best fallback
|
|
1576
1581
|
const satisfied = s.depends.filter(dep => doneSliceIds.has(dep)).length;
|
|
1577
1582
|
if (satisfied > bestFallbackLegacySatisfied) {
|
|
1578
1583
|
bestFallbackLegacy = s;
|
|
@@ -1580,13 +1585,13 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|
|
1580
1585
|
}
|
|
1581
1586
|
}
|
|
1582
1587
|
|
|
1583
|
-
// Fallback: if no slice has all deps met, pick the one with the most deps satisfied
|
|
1584
1588
|
if (!activeSlice && bestFallbackLegacy) {
|
|
1585
1589
|
const unmet = bestFallbackLegacy.depends.filter(dep => !doneSliceIds.has(dep));
|
|
1586
|
-
logWarning(
|
|
1590
|
+
logWarning(
|
|
1591
|
+
"state",
|
|
1587
1592
|
`No slice has all deps satisfied — falling back to ${bestFallbackLegacy.id} ` +
|
|
1588
|
-
|
|
1589
|
-
|
|
1593
|
+
`(${bestFallbackLegacySatisfied}/${bestFallbackLegacy.depends.length} deps met, ` +
|
|
1594
|
+
`unmet: ${unmet.join(", ")})`,
|
|
1590
1595
|
);
|
|
1591
1596
|
activeSlice = { id: bestFallbackLegacy.id, title: bestFallbackLegacy.title };
|
|
1592
1597
|
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
autoLoop,
|
|
11
11
|
detectStuck,
|
|
12
12
|
_resetPendingResolve,
|
|
13
|
+
_hasPendingResolveForTest,
|
|
13
14
|
_setActiveSession,
|
|
14
15
|
isSessionSwitchInFlight,
|
|
15
16
|
type UnitResult,
|
|
@@ -35,12 +36,15 @@ function makeMockSession(opts?: {
|
|
|
35
36
|
newSessionDelayMs?: number;
|
|
36
37
|
onNewSessionStart?: (session: any) => void;
|
|
37
38
|
onNewSessionSettle?: (session: any) => void;
|
|
39
|
+
/** Called after the delay with the aborted state of any passed abortSignal.
|
|
40
|
+
* Used to verify that runUnit passes an aborted signal on late resolution (#3731). */
|
|
41
|
+
onSignalCheck?: (aborted: boolean) => void;
|
|
38
42
|
}) {
|
|
39
43
|
const session = {
|
|
40
44
|
active: true,
|
|
41
45
|
verbose: false,
|
|
42
46
|
cmdCtx: {
|
|
43
|
-
newSession: () => {
|
|
47
|
+
newSession: (options?: { abortSignal?: AbortSignal }) => {
|
|
44
48
|
opts?.onNewSessionStart?.(session);
|
|
45
49
|
if (opts?.newSessionThrows) {
|
|
46
50
|
return Promise.reject(new Error(opts.newSessionThrows));
|
|
@@ -50,11 +54,17 @@ function makeMockSession(opts?: {
|
|
|
50
54
|
if (delay > 0) {
|
|
51
55
|
return new Promise<{ cancelled: boolean }>((res) =>
|
|
52
56
|
setTimeout(() => {
|
|
57
|
+
// Simulate AgentSession.newSession() checking abortSignal after
|
|
58
|
+
// its internal async work (abort()) completes — this is where the
|
|
59
|
+
// real code captures process.cwd() and rebuilds the tool runtime.
|
|
60
|
+
// If the signal is aborted, the real code discards the session.
|
|
61
|
+
opts?.onSignalCheck?.(options?.abortSignal?.aborted ?? false);
|
|
53
62
|
opts?.onNewSessionSettle?.(session);
|
|
54
63
|
res(result);
|
|
55
64
|
}, delay),
|
|
56
65
|
);
|
|
57
66
|
}
|
|
67
|
+
opts?.onSignalCheck?.(options?.abortSignal?.aborted ?? false);
|
|
58
68
|
opts?.onNewSessionSettle?.(session);
|
|
59
69
|
return Promise.resolve(result);
|
|
60
70
|
},
|
|
@@ -349,6 +359,182 @@ test("runUnit cancels before dispatch when model restore fails after newSession"
|
|
|
349
359
|
]);
|
|
350
360
|
});
|
|
351
361
|
|
|
362
|
+
test("runUnit cancels before dispatch when provider is not request-ready (#4555)", async () => {
|
|
363
|
+
_resetPendingResolve();
|
|
364
|
+
|
|
365
|
+
const ctx = makeMockCtx();
|
|
366
|
+
ctx.model = { provider: "anthropic", id: "claude-opus-4-6" };
|
|
367
|
+
ctx.modelRegistry = {
|
|
368
|
+
isProviderRequestReady: (_provider: string) => false,
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const pi = makeMockPi();
|
|
372
|
+
const s = makeMockSession();
|
|
373
|
+
|
|
374
|
+
const result = await runUnit(ctx, pi, s, "task", "T01", "prompt");
|
|
375
|
+
|
|
376
|
+
assert.equal(result.status, "cancelled");
|
|
377
|
+
assert.equal(result.errorContext?.category, "provider");
|
|
378
|
+
assert.match(
|
|
379
|
+
result.errorContext?.message ?? "",
|
|
380
|
+
/Provider anthropic is not request-ready/,
|
|
381
|
+
);
|
|
382
|
+
assert.equal(pi.calls.length, 0, "sendMessage must not be called when provider is not ready");
|
|
383
|
+
assert.equal(_hasPendingResolveForTest(), false, "provider cancellation must clear the pending resolver");
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
test("runUnit cancels before dispatch using currentUnitModel provider when set (#4555)", async () => {
|
|
387
|
+
_resetPendingResolve();
|
|
388
|
+
|
|
389
|
+
const ctx = makeMockCtx();
|
|
390
|
+
// ctx.model uses "openai" which IS ready — if the code ignores currentUnitModel
|
|
391
|
+
// and falls back to ctx.model.provider, the unit would NOT be cancelled. The
|
|
392
|
+
// test therefore differentiates: only a bug (wrong provider lookup) would pass.
|
|
393
|
+
ctx.model = { provider: "openai", id: "gpt-4o" };
|
|
394
|
+
// modelRegistry says anthropic is not ready but openai is
|
|
395
|
+
ctx.modelRegistry = {
|
|
396
|
+
isProviderRequestReady: (provider: string) => provider === "openai",
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const pi = makeMockPi();
|
|
400
|
+
const s = makeMockSession();
|
|
401
|
+
// currentUnitModel overrides the provider used in the readiness check
|
|
402
|
+
s.currentUnitModel = { provider: "anthropic", id: "claude-opus-4-6" };
|
|
403
|
+
|
|
404
|
+
const result = await runUnit(ctx, pi, s, "task", "T01", "prompt");
|
|
405
|
+
|
|
406
|
+
assert.equal(result.status, "cancelled");
|
|
407
|
+
assert.equal(result.errorContext?.category, "provider");
|
|
408
|
+
assert.match(
|
|
409
|
+
result.errorContext?.message ?? "",
|
|
410
|
+
/Provider anthropic is not request-ready/,
|
|
411
|
+
);
|
|
412
|
+
assert.equal(pi.calls.length, 0, "sendMessage must not be called — anthropic (currentUnitModel) is not ready");
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
test("runUnit does not cancel before dispatch when provider is request-ready (#4555)", async () => {
|
|
416
|
+
_resetPendingResolve();
|
|
417
|
+
|
|
418
|
+
const ctx = makeMockCtx();
|
|
419
|
+
ctx.model = { provider: "anthropic", id: "claude-opus-4-6" };
|
|
420
|
+
ctx.modelRegistry = {
|
|
421
|
+
isProviderRequestReady: (_provider: string) => true,
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
const pi = makeMockPi();
|
|
425
|
+
const s = makeMockSession();
|
|
426
|
+
|
|
427
|
+
const resultPromise = runUnit(ctx, pi, s, "task", "T01", "prompt");
|
|
428
|
+
|
|
429
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
430
|
+
resolveAgentEnd(makeEvent());
|
|
431
|
+
|
|
432
|
+
const result = await resultPromise;
|
|
433
|
+
assert.equal(result.status, "completed");
|
|
434
|
+
assert.equal(pi.calls.length, 1, "sendMessage must be called when provider is ready");
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
test("runUnit proceeds when modelRegistry is absent (no readiness check available) (#4555)", async () => {
|
|
438
|
+
_resetPendingResolve();
|
|
439
|
+
|
|
440
|
+
const ctx = makeMockCtx();
|
|
441
|
+
ctx.model = { provider: "anthropic", id: "claude-opus-4-6" };
|
|
442
|
+
// No modelRegistry on ctx — pre-check should be skipped
|
|
443
|
+
|
|
444
|
+
const pi = makeMockPi();
|
|
445
|
+
const s = makeMockSession();
|
|
446
|
+
|
|
447
|
+
const resultPromise = runUnit(ctx, pi, s, "task", "T01", "prompt");
|
|
448
|
+
|
|
449
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
450
|
+
resolveAgentEnd(makeEvent());
|
|
451
|
+
|
|
452
|
+
const result = await resultPromise;
|
|
453
|
+
assert.equal(result.status, "completed");
|
|
454
|
+
assert.equal(pi.calls.length, 1);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
test("runUnit proceeds when isProviderRequestReady throws (defensive) (#4555)", async () => {
|
|
458
|
+
_resetPendingResolve();
|
|
459
|
+
|
|
460
|
+
const ctx = makeMockCtx();
|
|
461
|
+
ctx.model = { provider: "anthropic", id: "claude-opus-4-6" };
|
|
462
|
+
ctx.modelRegistry = {
|
|
463
|
+
isProviderRequestReady: (_provider: string) => {
|
|
464
|
+
throw new Error("registry error");
|
|
465
|
+
},
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
const pi = makeMockPi();
|
|
469
|
+
const s = makeMockSession();
|
|
470
|
+
|
|
471
|
+
const result = await runUnit(ctx, pi, s, "task", "T01", "prompt");
|
|
472
|
+
|
|
473
|
+
// When the readyCheck throws, ready=false → unit cancelled
|
|
474
|
+
assert.equal(result.status, "cancelled");
|
|
475
|
+
assert.equal(result.errorContext?.category, "provider");
|
|
476
|
+
assert.equal(pi.calls.length, 0);
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
test("late-resolving newSession() after timeout receives aborted signal so tool runtime is not configured with root cwd (#3731)", async () => {
|
|
480
|
+
// When newSession() times out in runUnit(), auto-mode restores cwd to project
|
|
481
|
+
// root. If newSession() later resolves, it must NOT use process.cwd() to
|
|
482
|
+
// configure the tool runtime (which would give it root cwd, not worktree cwd).
|
|
483
|
+
//
|
|
484
|
+
// The fix: runUnit creates an AbortController, aborts it on timeout, and passes
|
|
485
|
+
// the signal to newSession(). AgentSession.newSession() checks the signal after
|
|
486
|
+
// its internal await this.abort() completes and returns early (discards) if aborted.
|
|
487
|
+
//
|
|
488
|
+
// This test uses mock.timers to control timing precisely.
|
|
489
|
+
_resetPendingResolve();
|
|
490
|
+
mock.timers.enable();
|
|
491
|
+
|
|
492
|
+
try {
|
|
493
|
+
let abortedWhenLateSessionSettled: boolean | null = null;
|
|
494
|
+
|
|
495
|
+
// newSession mock simulates AgentSession.newSession() behavior:
|
|
496
|
+
// after an internal delay (representing await this.abort()), it checks the
|
|
497
|
+
// abortSignal — that's where the real code would capture process.cwd() and
|
|
498
|
+
// call _buildRuntime. If aborted, the real code must discard the session.
|
|
499
|
+
const s = makeMockSession({
|
|
500
|
+
newSessionDelayMs: 200_000, // longer than NEW_SESSION_TIMEOUT_MS (120s)
|
|
501
|
+
onSignalCheck: (aborted) => {
|
|
502
|
+
abortedWhenLateSessionSettled = aborted;
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
const ctx = makeMockCtx();
|
|
507
|
+
const pi = makeMockPi();
|
|
508
|
+
|
|
509
|
+
const resultPromise = runUnit(ctx, pi, s, "task", "T01", "prompt");
|
|
510
|
+
|
|
511
|
+
// Tick past the 120s NEW_SESSION_TIMEOUT_MS — runUnit returns cancelled
|
|
512
|
+
mock.timers.tick(121_000);
|
|
513
|
+
await Promise.resolve();
|
|
514
|
+
|
|
515
|
+
const result = await resultPromise;
|
|
516
|
+
assert.equal(result.status, "cancelled", "runUnit must return cancelled on session timeout");
|
|
517
|
+
|
|
518
|
+
// Tick past the delayed newSession (200s total) — the late newSession resolves
|
|
519
|
+
mock.timers.tick(80_000);
|
|
520
|
+
// Drain microtask queue so the .finally() and setTimeout callbacks run
|
|
521
|
+
await Promise.resolve();
|
|
522
|
+
await Promise.resolve();
|
|
523
|
+
|
|
524
|
+
// The key assertion: when the late newSession() resolves, runUnit must have
|
|
525
|
+
// passed an aborted AbortSignal. Without the fix, no signal is passed and
|
|
526
|
+
// abortedWhenLateSessionSettled would be false (or null, if signal not passed at all).
|
|
527
|
+
assert.equal(
|
|
528
|
+
abortedWhenLateSessionSettled,
|
|
529
|
+
true,
|
|
530
|
+
"runUnit must pass an aborted AbortSignal to newSession() when it resolves after the session-creation timeout (#3731). " +
|
|
531
|
+
"Without this, AgentSession.newSession() captures root process.cwd() and rebuilds the tool runtime with wrong cwd.",
|
|
532
|
+
);
|
|
533
|
+
} finally {
|
|
534
|
+
mock.timers.reset();
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
|
|
352
538
|
// ─── Structural assertions ───────────────────────────────────────────────────
|
|
353
539
|
|
|
354
540
|
test("auto-loop.ts exports autoLoop, runUnit, resolveAgentEnd", async () => {
|
|
@@ -409,7 +595,7 @@ test("auto/phases.ts: selectAndApplyModel called exactly once and before updateP
|
|
|
409
595
|
// Extract the runUnitPhase function body
|
|
410
596
|
const fnStart = src.indexOf("export async function runUnitPhase");
|
|
411
597
|
assert.ok(fnStart > 0, "runUnitPhase should exist in phases.ts");
|
|
412
|
-
const fnBody = src.slice(fnStart, fnStart +
|
|
598
|
+
const fnBody = src.slice(fnStart, fnStart + 16000);
|
|
413
599
|
|
|
414
600
|
// selectAndApplyModel must appear exactly once
|
|
415
601
|
const allOccurrences = [...fnBody.matchAll(/selectAndApplyModel\(/g)];
|
|
@@ -497,6 +683,8 @@ function makeMockDeps(
|
|
|
497
683
|
autoWorktreeBranch: () => "auto/M001",
|
|
498
684
|
resolveMilestoneFile: () => null,
|
|
499
685
|
reconcileMergeState: () => "clean",
|
|
686
|
+
preflightCleanRoot: () => ({ stashPushed: false, summary: "" }),
|
|
687
|
+
postflightPopStash: () => {},
|
|
500
688
|
getLedger: () => null,
|
|
501
689
|
getProjectTotals: () => ({ cost: 0 }),
|
|
502
690
|
formatCost: (c: number) => `$${c.toFixed(2)}`,
|
|
@@ -663,6 +851,45 @@ test("autoLoop exits on terminal complete state", async (t) => {
|
|
|
663
851
|
);
|
|
664
852
|
});
|
|
665
853
|
|
|
854
|
+
test("autoLoop pauses when provider readiness cancels before dispatch", async () => {
|
|
855
|
+
_resetPendingResolve();
|
|
856
|
+
|
|
857
|
+
const notifications: Array<{ message: string; level?: string }> = [];
|
|
858
|
+
const ctx = makeMockCtx();
|
|
859
|
+
ctx.ui.setStatus = () => {};
|
|
860
|
+
ctx.ui.notify = (message: string, level?: string) => {
|
|
861
|
+
notifications.push({ message, level });
|
|
862
|
+
};
|
|
863
|
+
ctx.model = { provider: "anthropic", id: "claude-opus-4-6" };
|
|
864
|
+
ctx.modelRegistry = {
|
|
865
|
+
getProviderAuthMode: () => "api-key",
|
|
866
|
+
isProviderRequestReady: () => false,
|
|
867
|
+
};
|
|
868
|
+
|
|
869
|
+
const pi = makeMockPi();
|
|
870
|
+
const s = makeLoopSession();
|
|
871
|
+
const deps = makeMockDeps({
|
|
872
|
+
selectAndApplyModel: async () => ({
|
|
873
|
+
routing: null,
|
|
874
|
+
appliedModel: { provider: "anthropic", id: "claude-opus-4-6" },
|
|
875
|
+
}),
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
await autoLoop(ctx, pi, s, deps);
|
|
879
|
+
|
|
880
|
+
assert.equal(pi.calls.length, 0, "provider readiness cancellation must not dispatch a message");
|
|
881
|
+
assert.ok(deps.callLog.includes("pauseAuto"), "provider readiness cancellation should pause auto-mode");
|
|
882
|
+
assert.ok(!deps.callLog.includes("stopAuto"), "provider readiness cancellation should not hard-stop auto-mode");
|
|
883
|
+
assert.ok(
|
|
884
|
+
!deps.callLog.includes("postUnitPreVerification"),
|
|
885
|
+
"post-unit verification must not run after pre-dispatch provider cancellation",
|
|
886
|
+
);
|
|
887
|
+
assert.ok(
|
|
888
|
+
notifications.some(n => /Provider anthropic is not request-ready/.test(n.message)),
|
|
889
|
+
"provider pause should notify with the readiness failure",
|
|
890
|
+
);
|
|
891
|
+
});
|
|
892
|
+
|
|
666
893
|
test("autoLoop passes structured session-lock failure details to the handler", async () => {
|
|
667
894
|
_resetPendingResolve();
|
|
668
895
|
|
|
@@ -1423,9 +1650,16 @@ test("auto-timeout-recovery.ts calls resolveAgentEnd instead of dispatchNextUnit
|
|
|
1423
1650
|
!src.includes("await dispatchNextUnit"),
|
|
1424
1651
|
"auto-timeout-recovery.ts must not call dispatchNextUnit",
|
|
1425
1652
|
);
|
|
1653
|
+
// After PR #4716, advance branches go through bumpAndResolveSynthetic()
|
|
1654
|
+
// (which bumps the turn epoch and calls resolveAgentEnd atomically).
|
|
1655
|
+
// Either direct resolveAgentEnd() or the helper satisfies the invariant:
|
|
1656
|
+
// the loop must be re-iterated on timeout recovery.
|
|
1657
|
+
const reIteratesLoop =
|
|
1658
|
+
src.includes("resolveAgentEnd(") ||
|
|
1659
|
+
src.includes("bumpAndResolveSynthetic(");
|
|
1426
1660
|
assert.ok(
|
|
1427
|
-
|
|
1428
|
-
"auto-timeout-recovery.ts must call resolveAgentEnd to re-iterate the loop on timeout recovery",
|
|
1661
|
+
reIteratesLoop,
|
|
1662
|
+
"auto-timeout-recovery.ts must call resolveAgentEnd (directly or via bumpAndResolveSynthetic) to re-iterate the loop on timeout recovery",
|
|
1429
1663
|
);
|
|
1430
1664
|
});
|
|
1431
1665
|
|