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,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auto/turn-epoch.ts — Turn generation counter + AsyncLocalStorage-backed
|
|
3
|
+
* capture for stale-turn write dropping.
|
|
4
|
+
*
|
|
5
|
+
* Problem: when auto-timeout-recovery synthetically resolves a timed-out
|
|
6
|
+
* unit so the loop can advance, the original LLM turn keeps running in the
|
|
7
|
+
* background. Its subsequent writes (journal events, audit events, tool
|
|
8
|
+
* calls that flow through closeout) then race the replacement unit's
|
|
9
|
+
* writes. DB-level guards (complete-task/complete-slice) block double
|
|
10
|
+
* state transitions, but journal/audit/closeout side-effects still fire
|
|
11
|
+
* with fresh identifiers and pollute forensics.
|
|
12
|
+
*
|
|
13
|
+
* Containment: every time we decide a turn is done (timeout recovery,
|
|
14
|
+
* explicit cancellation), bump a module-level generation counter.
|
|
15
|
+
* Turn-aware call sites wrap their body in `runWithTurnGeneration`, which
|
|
16
|
+
* captures the generation into AsyncLocalStorage. Write sites deep in the
|
|
17
|
+
* stack call `isStaleWrite` — if the captured generation is older than
|
|
18
|
+
* current, the turn has been superseded and the write is dropped.
|
|
19
|
+
*
|
|
20
|
+
* Failure mode: if AsyncLocalStorage context is lost across some exotic
|
|
21
|
+
* async boundary (e.g. a native-side worker callback), the write site sees
|
|
22
|
+
* `no-store` and falls through to current behavior — the write proceeds
|
|
23
|
+
* normally. That is a safe default; the correctness regression is only
|
|
24
|
+
* "noisier forensics under rare boundary loss," not duplicated state.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
28
|
+
|
|
29
|
+
import { debugLog } from "../debug-logger.js";
|
|
30
|
+
|
|
31
|
+
let _currentGeneration = 0;
|
|
32
|
+
|
|
33
|
+
const turnContext = new AsyncLocalStorage<{ capturedGen: number }>();
|
|
34
|
+
|
|
35
|
+
/** Current turn generation. Mutated only by bumpTurnGeneration. */
|
|
36
|
+
export function getCurrentTurnGeneration(): number {
|
|
37
|
+
return _currentGeneration;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Bump the turn generation and return the new value. Every caller should
|
|
42
|
+
* pass a short `reason` string so forensics can reconstruct why a given
|
|
43
|
+
* turn was marked stale.
|
|
44
|
+
*/
|
|
45
|
+
export function bumpTurnGeneration(reason: string): number {
|
|
46
|
+
_currentGeneration += 1;
|
|
47
|
+
debugLog("turnEpoch.bump", { reason, newGeneration: _currentGeneration });
|
|
48
|
+
return _currentGeneration;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Run fn() with `capturedGen` attached to AsyncLocalStorage so that any
|
|
53
|
+
* write site reached from within fn() can check for staleness without
|
|
54
|
+
* parameter threading.
|
|
55
|
+
*/
|
|
56
|
+
export function runWithTurnGeneration<T>(capturedGen: number, fn: () => T): T {
|
|
57
|
+
return turnContext.run({ capturedGen }, fn);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* True when the current async context was started at a turn generation
|
|
62
|
+
* older than the current one — meaning the turn has been superseded by
|
|
63
|
+
* recovery/cancellation since it began.
|
|
64
|
+
*
|
|
65
|
+
* Returns false when there is no captured generation (e.g. the write is
|
|
66
|
+
* happening outside any wrapped turn). That is the safe default: writes
|
|
67
|
+
* proceed as they did before this epoch was introduced.
|
|
68
|
+
*/
|
|
69
|
+
export function isStaleWrite(component?: string): boolean {
|
|
70
|
+
const store = turnContext.getStore();
|
|
71
|
+
if (!store) return false;
|
|
72
|
+
const captured = store.capturedGen;
|
|
73
|
+
const current = _currentGeneration;
|
|
74
|
+
if (captured < current) {
|
|
75
|
+
debugLog("turnEpoch.stale", {
|
|
76
|
+
component: component ?? "unknown",
|
|
77
|
+
captured,
|
|
78
|
+
current,
|
|
79
|
+
});
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Snapshot of both the captured turn generation and the current one.
|
|
87
|
+
* Used by closeoutUnit to persist an orphan-marker entry instead of
|
|
88
|
+
* silently skipping the full closeout on a stale turn.
|
|
89
|
+
*/
|
|
90
|
+
export function describeTurnEpoch(): {
|
|
91
|
+
captured: number | null;
|
|
92
|
+
current: number;
|
|
93
|
+
stale: boolean;
|
|
94
|
+
} {
|
|
95
|
+
const store = turnContext.getStore();
|
|
96
|
+
const captured = store?.capturedGen ?? null;
|
|
97
|
+
const current = _currentGeneration;
|
|
98
|
+
return {
|
|
99
|
+
captured,
|
|
100
|
+
current,
|
|
101
|
+
stale: captured !== null && captured < current,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Test helper — resets module state so tests start from a known baseline. */
|
|
106
|
+
export function _resetTurnEpoch(): void {
|
|
107
|
+
_currentGeneration = 0;
|
|
108
|
+
}
|
|
@@ -9,7 +9,7 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
|
9
9
|
import type { AutoSession } from "./session.js";
|
|
10
10
|
import type { GSDPreferences } from "../preferences.js";
|
|
11
11
|
import type { GSDState } from "../types.js";
|
|
12
|
-
import type { CmuxLogLevel } from "../../cmux
|
|
12
|
+
import type { CmuxLogLevel } from "../../shared/cmux-events.js";
|
|
13
13
|
import type { LoopDeps } from "./loop-deps.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -34,6 +34,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
34
34
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
35
35
|
import { join } from "node:path";
|
|
36
36
|
import { hasImplementationArtifacts } from "./auto-recovery.js";
|
|
37
|
+
import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
|
|
37
38
|
import {
|
|
38
39
|
buildDiscussMilestonePrompt,
|
|
39
40
|
buildResearchMilestonePrompt,
|
|
@@ -58,6 +59,7 @@ import {
|
|
|
58
59
|
import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
|
|
59
60
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
60
61
|
import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
|
|
62
|
+
import { EXECUTION_ENTRY_PHASES, hasFinalizedMilestoneContext } from "./uok/plan-v2.js";
|
|
61
63
|
|
|
62
64
|
// ─── Types ────────────────────────────────────────────────────────────────
|
|
63
65
|
|
|
@@ -242,6 +244,38 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
242
244
|
};
|
|
243
245
|
},
|
|
244
246
|
},
|
|
247
|
+
{
|
|
248
|
+
// #4671 — Recovery path for execution-entry phases with missing CONTEXT.md.
|
|
249
|
+
//
|
|
250
|
+
// Once `deriveStateFromDb` returns an execution-entry phase (executing /
|
|
251
|
+
// summarizing / validating-milestone / completing-milestone), the
|
|
252
|
+
// pre-planning guard at `pre-planning (no context) → discuss-milestone`
|
|
253
|
+
// no longer fires. The plan-v2 gate correctly detects the missing context
|
|
254
|
+
// but can only block — it cannot redispatch. Without this rule the
|
|
255
|
+
// milestone is stuck until `/gsd doctor heal` repairs it (and heal
|
|
256
|
+
// historically missed this check too).
|
|
257
|
+
//
|
|
258
|
+
// Fire BEFORE the execution-entry phase rules so we redispatch to
|
|
259
|
+
// `discuss-milestone` instead of hitting the plan-v2 gate.
|
|
260
|
+
name: "execution-entry phase (no context) → discuss-milestone",
|
|
261
|
+
match: async ({ state, mid, midTitle, basePath, structuredQuestionsAvailable }) => {
|
|
262
|
+
if (!EXECUTION_ENTRY_PHASES.has(state.phase)) return null;
|
|
263
|
+
// Align with the plan-v2 gate's lookup semantics: whitespace-only counts
|
|
264
|
+
// as missing, and an auto worktree may fall back to GSD_PROJECT_ROOT.
|
|
265
|
+
if (hasFinalizedMilestoneContext(basePath, mid)) return null;
|
|
266
|
+
return {
|
|
267
|
+
action: "dispatch",
|
|
268
|
+
unitType: "discuss-milestone",
|
|
269
|
+
unitId: mid,
|
|
270
|
+
prompt: await buildDiscussMilestonePrompt(
|
|
271
|
+
mid,
|
|
272
|
+
midTitle,
|
|
273
|
+
basePath,
|
|
274
|
+
structuredQuestionsAvailable,
|
|
275
|
+
),
|
|
276
|
+
};
|
|
277
|
+
},
|
|
278
|
+
},
|
|
245
279
|
{
|
|
246
280
|
name: "summarizing → complete-slice",
|
|
247
281
|
match: async ({ state, mid, midTitle, basePath }) => {
|
|
@@ -421,6 +455,26 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
421
455
|
};
|
|
422
456
|
},
|
|
423
457
|
},
|
|
458
|
+
{
|
|
459
|
+
name: "planning (require_slice_discussion) → pause for discussion (#3454)",
|
|
460
|
+
match: async ({ state, mid, basePath, prefs }) => {
|
|
461
|
+
if (state.phase !== "planning") return null;
|
|
462
|
+
if (!prefs?.phases?.require_slice_discussion) return null;
|
|
463
|
+
if (!state.activeSlice) return null;
|
|
464
|
+
// Only pause if the slice has no context file yet (discussion not done).
|
|
465
|
+
// resolveSliceFile returns null when the file does not exist on disk,
|
|
466
|
+
// but cachedReaddir could return a stale hit — verify with existsSync
|
|
467
|
+
// so the guard is defence-in-depth and the contract is explicit at the
|
|
468
|
+
// call site.
|
|
469
|
+
const sliceContextFile = resolveSliceFile(basePath, mid, state.activeSlice.id, "CONTEXT");
|
|
470
|
+
if (sliceContextFile && existsSync(sliceContextFile)) return null; // discussion already done, proceed
|
|
471
|
+
return {
|
|
472
|
+
action: "stop" as const,
|
|
473
|
+
reason: `Slice ${state.activeSlice.id} requires discussion before planning (require_slice_discussion is enabled). Run /gsd discuss to discuss this slice, then /gsd auto to resume.`,
|
|
474
|
+
level: "info" as const,
|
|
475
|
+
};
|
|
476
|
+
},
|
|
477
|
+
},
|
|
424
478
|
{
|
|
425
479
|
// Keep this rule before the single-slice research rule so the multi-slice
|
|
426
480
|
// path wins whenever 2+ slices are ready.
|
|
@@ -568,15 +622,28 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
568
622
|
},
|
|
569
623
|
{
|
|
570
624
|
name: "planning → plan-slice",
|
|
571
|
-
match: async ({ state, mid, midTitle, basePath, sessionContextWindow, modelRegistry }) => {
|
|
625
|
+
match: async ({ state, mid, midTitle, basePath, sessionContextWindow, modelRegistry, session }) => {
|
|
572
626
|
if (state.phase !== "planning") return null;
|
|
573
627
|
if (!state.activeSlice) return missingSliceStop(mid, state.phase);
|
|
574
628
|
const sid = state.activeSlice!.id;
|
|
575
629
|
const sTitle = state.activeSlice!.title;
|
|
630
|
+
// #4551: Consume any persisted pre-exec failure for this slice so the
|
|
631
|
+
// re-dispatched prompt includes the exact blocked references. Clear the
|
|
632
|
+
// field immediately after reading to prevent stale context leaking into
|
|
633
|
+
// a later, unrelated plan-slice run.
|
|
634
|
+
const unitId = `${mid}/${sid}`;
|
|
635
|
+
let priorPreExecFailure: { blockingFindings: string[]; verdictExcerpt: string } | undefined;
|
|
636
|
+
if (session?.lastPreExecFailure?.unitId === unitId) {
|
|
637
|
+
priorPreExecFailure = {
|
|
638
|
+
blockingFindings: session.lastPreExecFailure.blockingFindings,
|
|
639
|
+
verdictExcerpt: session.lastPreExecFailure.verdictExcerpt,
|
|
640
|
+
};
|
|
641
|
+
session.lastPreExecFailure = null;
|
|
642
|
+
}
|
|
576
643
|
return {
|
|
577
644
|
action: "dispatch",
|
|
578
645
|
unitType: "plan-slice",
|
|
579
|
-
unitId
|
|
646
|
+
unitId,
|
|
580
647
|
prompt: await buildPlanSlicePrompt(
|
|
581
648
|
mid,
|
|
582
649
|
midTitle,
|
|
@@ -584,7 +651,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
584
651
|
sTitle,
|
|
585
652
|
basePath,
|
|
586
653
|
undefined,
|
|
587
|
-
{ sessionContextWindow, modelRegistry },
|
|
654
|
+
{ sessionContextWindow, modelRegistry, priorPreExecFailure },
|
|
588
655
|
),
|
|
589
656
|
};
|
|
590
657
|
},
|
|
@@ -870,21 +937,13 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
870
937
|
}
|
|
871
938
|
}
|
|
872
939
|
|
|
873
|
-
// Reconciliation guard (#4324): when the SUMMARY file already exists
|
|
874
|
-
// on disk but the DB says the milestone is not complete, the DB is
|
|
875
|
-
// out of sync (e.g. journal reset, partial merge, crash recovery).
|
|
876
|
-
// Reconcile the DB status directly instead of re-dispatching the
|
|
877
|
-
// tool, which would overwrite the richer on-disk SUMMARY with a
|
|
878
|
-
// thinner regenerated version — causing silent data loss.
|
|
879
940
|
const existingSummary = resolveMilestoneFile(basePath, mid, "SUMMARY");
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
logWarning("dispatch", `Failed to reconcile milestone ${mid} status: ${err instanceof Error ? err.message : String(err)}`);
|
|
941
|
+
let summaryOutcome: "success" | "failure" | "unknown" = "unknown";
|
|
942
|
+
if (existingSummary) {
|
|
943
|
+
const summaryContent = await loadFile(existingSummary);
|
|
944
|
+
if (summaryContent) {
|
|
945
|
+
summaryOutcome = classifyMilestoneSummaryContent(summaryContent);
|
|
886
946
|
}
|
|
887
|
-
return { action: "skip" };
|
|
888
947
|
}
|
|
889
948
|
|
|
890
949
|
// Safety guard (#2675): block completion when VALIDATION verdict is
|
|
@@ -969,6 +1028,48 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
969
1028
|
logWarning("dispatch", `verification class check failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
970
1029
|
}
|
|
971
1030
|
|
|
1031
|
+
// Disk/DB mismatch handling (#4658): SUMMARY presence alone is not enough.
|
|
1032
|
+
// Apply post-gate policy:
|
|
1033
|
+
// - success summary: reconcile DB and skip re-dispatch
|
|
1034
|
+
// - failure summary: pause/fail-closed
|
|
1035
|
+
// - unknown summary: pause/fail-closed
|
|
1036
|
+
if (existingSummary) {
|
|
1037
|
+
const milestone = isDbAvailable() ? getMilestone(mid) : null;
|
|
1038
|
+
const status = milestone?.status ?? (isDbAvailable() ? "missing" : "unavailable");
|
|
1039
|
+
|
|
1040
|
+
if (summaryOutcome === "success") {
|
|
1041
|
+
if (!isDbAvailable()) {
|
|
1042
|
+
logWarning("dispatch", `Milestone ${mid} SUMMARY indicates completion while DB is unavailable — skipping duplicate complete-milestone dispatch`);
|
|
1043
|
+
return { action: "skip" };
|
|
1044
|
+
}
|
|
1045
|
+
try {
|
|
1046
|
+
updateMilestoneStatus(mid, "complete", new Date().toISOString());
|
|
1047
|
+
logWarning("dispatch", `Milestone ${mid} SUMMARY indicates completion while DB status was "${status}" — reconciled DB to complete (#4658)`);
|
|
1048
|
+
return { action: "skip" };
|
|
1049
|
+
} catch (err) {
|
|
1050
|
+
return {
|
|
1051
|
+
action: "stop",
|
|
1052
|
+
level: "warning",
|
|
1053
|
+
reason: `Milestone ${mid} SUMMARY indicates completion but DB reconciliation failed (${err instanceof Error ? err.message : String(err)}). Auto-mode paused for manual review.`,
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
if (summaryOutcome === "failure") {
|
|
1059
|
+
return {
|
|
1060
|
+
action: "stop",
|
|
1061
|
+
level: "warning",
|
|
1062
|
+
reason: `Milestone ${mid} has a failure-path SUMMARY while DB status is "${status}". Auto-mode will not promote completion from failure artifacts. Re-run complete-milestone only after blockers are resolved and verification passes.`,
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
return {
|
|
1067
|
+
action: "stop",
|
|
1068
|
+
level: "warning",
|
|
1069
|
+
reason: `Milestone ${mid} has an ambiguous SUMMARY while DB status is "${status}". Auto-mode paused instead of promoting completion from file presence alone.`,
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
|
|
972
1073
|
return {
|
|
973
1074
|
action: "dispatch",
|
|
974
1075
|
unitType: "complete-milestone",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
export { autoLoop, runUokKernelLoop, runLegacyAutoLoop } from "./auto/loop.js";
|
|
11
11
|
export { isInfrastructureError, INFRA_ERROR_CODES } from "./auto/infra-errors.js";
|
|
12
|
-
export { resolveAgentEnd, resolveAgentEndCancelled, isSessionSwitchInFlight, _resetPendingResolve, _setActiveSession } from "./auto/resolve.js";
|
|
12
|
+
export { resolveAgentEnd, resolveAgentEndCancelled, isSessionSwitchInFlight, _hasPendingResolveForTest, _resetPendingResolve, _setActiveSession } from "./auto/resolve.js";
|
|
13
13
|
export { detectStuck } from "./auto/detect-stuck.js";
|
|
14
14
|
export { runUnit } from "./auto/run-unit.js";
|
|
15
15
|
export type { LoopDeps } from "./auto/loop-deps.js";
|
|
@@ -395,7 +395,7 @@ export async function selectAndApplyModel(
|
|
|
395
395
|
// ADR-005: Adjust active tool set for the selected model's provider capabilities.
|
|
396
396
|
// Hard-filter incompatible tools, then let extensions override via adjust_tool_set hook.
|
|
397
397
|
const activeToolNames = pi.getActiveTools();
|
|
398
|
-
const { toolNames: compatibleTools, removedTools } = adjustToolSet(activeToolNames, model.api);
|
|
398
|
+
const { toolNames: compatibleTools, removedTools } = adjustToolSet(activeToolNames, model.api, model.provider);
|
|
399
399
|
let finalToolNames = compatibleTools;
|
|
400
400
|
|
|
401
401
|
// Fire adjust_tool_set hook — extensions can override the filtered tool set
|
|
@@ -55,7 +55,7 @@ import { hasPendingCaptures, loadPendingCaptures, revertExecutorResolvedCaptures
|
|
|
55
55
|
import { debugLog } from "./debug-logger.js";
|
|
56
56
|
import { runSafely } from "./auto-utils.js";
|
|
57
57
|
import type { AutoSession, SidecarItem } from "./auto/session.js";
|
|
58
|
-
import { getEvidence } from "./safety/evidence-collector.js";
|
|
58
|
+
import { getEvidence, clearEvidenceFromDisk } from "./safety/evidence-collector.js";
|
|
59
59
|
import { validateFileChanges } from "./safety/file-change-validator.js";
|
|
60
60
|
// crossReferenceEvidence available for future use when verification_evidence is stored in DB
|
|
61
61
|
// import { crossReferenceEvidence, type ClaimedEvidence } from "./safety/evidence-cross-ref.js";
|
|
@@ -70,9 +70,24 @@ import { ensureCodebaseMapFresh } from "./codebase-generator.js";
|
|
|
70
70
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
71
71
|
import { UokGateRunner } from "./uok/gate-runner.js";
|
|
72
72
|
import { writeTurnGitTransaction } from "./uok/gitops.js";
|
|
73
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
74
|
+
import { detectAbandonMilestone } from "./abandon-detect.js";
|
|
73
75
|
|
|
74
76
|
/** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
|
|
75
77
|
const MAX_VERIFICATION_RETRIES = 3;
|
|
78
|
+
const COMPLETE_MILESTONE_DB_SETTLE_MS = 1500;
|
|
79
|
+
const COMPLETE_MILESTONE_DB_SETTLE_POLL_MS = 100;
|
|
80
|
+
|
|
81
|
+
async function waitForMilestoneDbClose(mid: string): Promise<boolean> {
|
|
82
|
+
const deadline = Date.now() + COMPLETE_MILESTONE_DB_SETTLE_MS;
|
|
83
|
+
while (Date.now() < deadline) {
|
|
84
|
+
if (!isDbAvailable()) return false;
|
|
85
|
+
const milestone = getMilestone(mid);
|
|
86
|
+
if (milestone && isClosedStatus(milestone.status)) return true;
|
|
87
|
+
await new Promise((resolve) => setTimeout(resolve, COMPLETE_MILESTONE_DB_SETTLE_POLL_MS));
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
76
91
|
|
|
77
92
|
|
|
78
93
|
/** Enqueue a sidecar item (hook, triage, or quick-task) for the main loop to
|
|
@@ -107,7 +122,6 @@ import {
|
|
|
107
122
|
updateProgressWidget as _updateProgressWidget,
|
|
108
123
|
updateSliceProgressCache,
|
|
109
124
|
unitVerb,
|
|
110
|
-
hideFooter,
|
|
111
125
|
describeNextUnit,
|
|
112
126
|
} from "./auto-dashboard.js";
|
|
113
127
|
import { existsSync, unlinkSync } from "node:fs";
|
|
@@ -556,6 +570,35 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
556
570
|
// Rewrite-docs completion
|
|
557
571
|
if (s.currentUnit.type === "rewrite-docs") {
|
|
558
572
|
await runSafely("postUnit", "rewrite-docs-resolve", async () => {
|
|
573
|
+
// Detect abandon/descope overrides BEFORE resolving them (#3490).
|
|
574
|
+
// If an override is about abandoning the milestone, park it so the
|
|
575
|
+
// state engine skips it. Without this, rewrite-docs only edits
|
|
576
|
+
// markdown but the DB still has the milestone as active.
|
|
577
|
+
try {
|
|
578
|
+
const { loadActiveOverrides } = await import("./files.js");
|
|
579
|
+
const overrides = await loadActiveOverrides(s.basePath);
|
|
580
|
+
const decision = detectAbandonMilestone(overrides, s.currentMilestoneId);
|
|
581
|
+
if (decision.shouldPark && s.currentMilestoneId) {
|
|
582
|
+
const { parkMilestone } = await import("./milestone-actions.js");
|
|
583
|
+
const parked = parkMilestone(s.basePath, s.currentMilestoneId, decision.reason);
|
|
584
|
+
if (parked) {
|
|
585
|
+
ctx.ui.notify(`Milestone ${s.currentMilestoneId} parked: "${decision.reason}"`, "info");
|
|
586
|
+
} else {
|
|
587
|
+
// Park refused: milestone directory missing, milestone already
|
|
588
|
+
// completed (SUMMARY present), or PARKED.md already exists.
|
|
589
|
+
// resolveAllOverrides below will still consume the override —
|
|
590
|
+
// surface this loudly so the user notices state drift rather
|
|
591
|
+
// than silently losing the abandon directive.
|
|
592
|
+
const msg = `Abandon detected for ${s.currentMilestoneId} but park refused (milestone is completed, already parked, or missing). Override will be resolved anyway — verify state is correct.`;
|
|
593
|
+
logError("engine", msg);
|
|
594
|
+
ctx.ui.notify(msg, "warning");
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
} catch (err) {
|
|
598
|
+
logError("engine", `abandon-detect failed: ${(err as Error).message}`);
|
|
599
|
+
ctx.ui.notify(`Abandon detection failed — check logs. Overrides will still be resolved.`, "warning");
|
|
600
|
+
}
|
|
601
|
+
|
|
559
602
|
await resolveAllOverrides(s.basePath);
|
|
560
603
|
// Reset both disk and in-memory counters. Disk counter is authoritative
|
|
561
604
|
// (survives restarts); in-memory is kept in sync for the current session.
|
|
@@ -654,7 +697,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
654
697
|
if (taskRow) {
|
|
655
698
|
const expectedOutput = taskRow.expected_output ?? [];
|
|
656
699
|
const plannedFiles = taskRow.files ?? [];
|
|
657
|
-
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles);
|
|
700
|
+
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
|
|
658
701
|
if (audit && audit.violations.length > 0) {
|
|
659
702
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
660
703
|
for (const v of warnings) {
|
|
@@ -712,6 +755,16 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
712
755
|
debugLog("postUnit", { phase: "safety-content-validation", error: String(e) });
|
|
713
756
|
}
|
|
714
757
|
}
|
|
758
|
+
|
|
759
|
+
// Clear persisted evidence file now that post-unit processing is complete
|
|
760
|
+
// (Bug #4385 — prevents stale evidence from affecting retries of same unit ID).
|
|
761
|
+
if (safetyConfig.evidence_collection && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
|
|
762
|
+
try {
|
|
763
|
+
clearEvidenceFromDisk(s.basePath, sMid, sSid, sTid);
|
|
764
|
+
} catch (e) {
|
|
765
|
+
debugLog("postUnit", { phase: "safety-evidence-clear", error: String(e) });
|
|
766
|
+
}
|
|
767
|
+
}
|
|
715
768
|
}
|
|
716
769
|
} catch (e) {
|
|
717
770
|
debugLog("postUnit", { phase: "safety-harness", error: String(e) });
|
|
@@ -731,6 +784,25 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
731
784
|
|
|
732
785
|
// If verification failed, attempt to regenerate missing projection files
|
|
733
786
|
// from DB data before giving up (e.g. research-slice produces PLAN from engine).
|
|
787
|
+
if (!triggerArtifactVerified) {
|
|
788
|
+
if (s.currentUnit.type === "complete-milestone") {
|
|
789
|
+
try {
|
|
790
|
+
const { milestone: mid } = parseUnitId(s.currentUnit.id);
|
|
791
|
+
if (mid) {
|
|
792
|
+
const settled = await waitForMilestoneDbClose(mid);
|
|
793
|
+
if (settled) {
|
|
794
|
+
triggerArtifactVerified = verifyExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
795
|
+
if (triggerArtifactVerified) {
|
|
796
|
+
invalidateAllCaches();
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
} catch (e) {
|
|
801
|
+
debugLog("postUnit", { phase: "artifact-verify-settle-db", error: String(e) });
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
734
806
|
if (!triggerArtifactVerified) {
|
|
735
807
|
try {
|
|
736
808
|
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
|
@@ -1134,6 +1206,15 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1134
1206
|
`Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found\n${details}${suffix}${evidenceNote}`,
|
|
1135
1207
|
"error",
|
|
1136
1208
|
);
|
|
1209
|
+
// Persist failure context so the next plan-slice re-dispatch can inject
|
|
1210
|
+
// it into the prompt and break the infinite loop (#4551).
|
|
1211
|
+
s.lastPreExecFailure = {
|
|
1212
|
+
unitId: currentUnit.id,
|
|
1213
|
+
blockingFindings: blockingChecks.map(
|
|
1214
|
+
c => `[${c.category}] ${c.target}: ${c.message}`,
|
|
1215
|
+
),
|
|
1216
|
+
verdictExcerpt: `status=${result.status}; ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} detected`,
|
|
1217
|
+
};
|
|
1137
1218
|
preExecPauseNeeded = true;
|
|
1138
1219
|
} else if (result.status === "warn") {
|
|
1139
1220
|
ctx.ui.notify(
|
|
@@ -1142,6 +1223,14 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1142
1223
|
);
|
|
1143
1224
|
// Strict mode: treat warnings as blocking
|
|
1144
1225
|
if (prefs?.enhanced_verification_strict === true) {
|
|
1226
|
+
const warnChecks = result.checks.filter(c => !c.passed);
|
|
1227
|
+
s.lastPreExecFailure = {
|
|
1228
|
+
unitId: currentUnit.id,
|
|
1229
|
+
blockingFindings: warnChecks.map(
|
|
1230
|
+
c => `[${c.category}] ${c.target}: ${c.message}`,
|
|
1231
|
+
),
|
|
1232
|
+
verdictExcerpt: `status=${result.status} (strict mode); ${warnChecks.length} warning${warnChecks.length === 1 ? "" : "s"} treated as blocking`,
|
|
1233
|
+
};
|
|
1145
1234
|
preExecPauseNeeded = true;
|
|
1146
1235
|
}
|
|
1147
1236
|
}
|
|
@@ -1380,7 +1380,18 @@ async function renderSlicePrompt(options: {
|
|
|
1380
1380
|
|
|
1381
1381
|
export async function buildPlanSlicePrompt(
|
|
1382
1382
|
mid: string, _midTitle: string, sid: string, sTitle: string, base: string, level?: InlineLevel,
|
|
1383
|
-
options?: {
|
|
1383
|
+
options?: {
|
|
1384
|
+
softScopeHint?: string;
|
|
1385
|
+
sessionContextWindow?: number;
|
|
1386
|
+
modelRegistry?: MinimalModelRegistry;
|
|
1387
|
+
/** Failure context from a prior pre-exec gate run (#4551). When present, a
|
|
1388
|
+
* "Fix these specific issues" section is appended so the LLM addresses the
|
|
1389
|
+
* exact problems instead of producing an identical plan that fails again. */
|
|
1390
|
+
priorPreExecFailure?: {
|
|
1391
|
+
blockingFindings: string[];
|
|
1392
|
+
verdictExcerpt: string;
|
|
1393
|
+
};
|
|
1394
|
+
},
|
|
1384
1395
|
): Promise<string> {
|
|
1385
1396
|
const prependBlocks: string[] = [];
|
|
1386
1397
|
// ADR-011: when the refining-phase dispatch rule gracefully downgrades to
|
|
@@ -1393,6 +1404,22 @@ export async function buildPlanSlicePrompt(
|
|
|
1393
1404
|
`This scope was captured during an earlier progressive-planning pass that was later disabled. Treat it as context only — you may plan beyond it if the work genuinely requires more scope. Do NOT treat this as a hard boundary.`,
|
|
1394
1405
|
);
|
|
1395
1406
|
}
|
|
1407
|
+
// #4551: inject pre-exec failure context so the re-dispatched plan-slice
|
|
1408
|
+
// addresses the exact blocked references rather than reproducing the same plan.
|
|
1409
|
+
if (options?.priorPreExecFailure) {
|
|
1410
|
+
const { blockingFindings, verdictExcerpt } = options.priorPreExecFailure;
|
|
1411
|
+
const findingsList = blockingFindings.length > 0
|
|
1412
|
+
? blockingFindings.map(f => `- ${f}`).join("\n")
|
|
1413
|
+
: "- (no specific findings recorded)";
|
|
1414
|
+
prependBlocks.push(
|
|
1415
|
+
`## Fix these specific issues from the prior pre-exec check\n\n` +
|
|
1416
|
+
`The previous plan-slice attempt was blocked by pre-execution validation.\n` +
|
|
1417
|
+
`Gate verdict: ${verdictExcerpt}\n\n` +
|
|
1418
|
+
`Blocked references that must be resolved in this plan:\n${findingsList}\n\n` +
|
|
1419
|
+
`Revise the plan so that every reference listed above is satisfied before execution begins. ` +
|
|
1420
|
+
`Do not reproduce the same file paths, package names, or task ordering that caused these failures.`,
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1396
1423
|
return renderSlicePrompt({
|
|
1397
1424
|
mid, sid, sTitle, base,
|
|
1398
1425
|
level: level ?? resolveInlineLevel(),
|
|
@@ -13,10 +13,11 @@ import { appendEvent } from "./workflow-events.js";
|
|
|
13
13
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
14
14
|
import { clearParseCache } from "./files.js";
|
|
15
15
|
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
|
16
|
-
import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus } from "./gsd-db.js";
|
|
16
|
+
import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus, insertSlice, getMilestone } from "./gsd-db.js";
|
|
17
17
|
import { isValidationTerminal } from "./state.js";
|
|
18
18
|
import { getErrorMessage } from "./error-utils.js";
|
|
19
19
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
20
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
20
21
|
import {
|
|
21
22
|
nativeConflictFiles,
|
|
22
23
|
nativeCommit,
|
|
@@ -50,9 +51,14 @@ import {
|
|
|
50
51
|
resolveExpectedArtifactPath,
|
|
51
52
|
diagnoseExpectedArtifact,
|
|
52
53
|
} from "./auto-artifact-paths.js";
|
|
54
|
+
import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
|
|
53
55
|
|
|
54
56
|
// Re-export so existing consumers of auto-recovery.ts keep working.
|
|
55
57
|
export { resolveExpectedArtifactPath, diagnoseExpectedArtifact };
|
|
58
|
+
export {
|
|
59
|
+
classifyMilestoneSummaryContent,
|
|
60
|
+
type MilestoneSummaryOutcome,
|
|
61
|
+
} from "./milestone-summary-classifier.js";
|
|
56
62
|
|
|
57
63
|
// ─── Artifact Resolution & Verification ───────────────────────────────────────
|
|
58
64
|
|
|
@@ -268,11 +274,26 @@ export function verifyExpectedArtifact(
|
|
|
268
274
|
// RESEARCH file. Without this, resolveExpectedArtifactPath returns null and
|
|
269
275
|
// the retry/escalation machinery silently re-dispatches forever.
|
|
270
276
|
//
|
|
277
|
+
// #4068: Also treat a PARALLEL-BLOCKER placeholder as a terminal completion
|
|
278
|
+
// so that timeout-recovery can write the blocker, have verifyExpectedArtifact
|
|
279
|
+
// return true, and let the dispatch loop advance past this unit. Without
|
|
280
|
+
// this, the blocker is written but verification still returns false, the unit
|
|
281
|
+
// is never cleared from unitDispatchCount, and on the next iteration the
|
|
282
|
+
// dispatch rule (which correctly skips parallel-research when PARALLEL-BLOCKER
|
|
283
|
+
// exists) returns null — leaving the loop stuck re-deriving indefinitely.
|
|
284
|
+
//
|
|
271
285
|
// NOTE: this predicate mirrors the dispatch rule at
|
|
272
286
|
// auto-dispatch.ts parallel-research-slices — keep the two in sync.
|
|
273
287
|
if (unitType === "research-slice" && unitId.endsWith("/parallel-research")) {
|
|
274
288
|
const { milestone: mid } = parseUnitId(unitId);
|
|
275
289
|
if (!mid) return false;
|
|
290
|
+
|
|
291
|
+
// #4068: PARALLEL-BLOCKER written by timeout-recovery is a terminal state.
|
|
292
|
+
const blockerPath = resolveExpectedArtifactPath(unitType, unitId, base);
|
|
293
|
+
if (blockerPath && existsSync(blockerPath)) {
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
|
|
276
297
|
const roadmapFile = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
277
298
|
if (!roadmapFile || !existsSync(roadmapFile)) {
|
|
278
299
|
logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap missing`);
|
|
@@ -462,6 +483,14 @@ export function verifyExpectedArtifact(
|
|
|
462
483
|
// A milestone with only .gsd/ plan files and zero implementation code is
|
|
463
484
|
// not genuinely complete — the LLM wrote plan files but skipped actual work.
|
|
464
485
|
if (unitType === "complete-milestone") {
|
|
486
|
+
const summaryOutcome = classifyMilestoneSummaryContent(readFileSync(absPath, "utf-8"));
|
|
487
|
+
if (summaryOutcome === "failure") return false;
|
|
488
|
+
const { milestone: mid } = parseUnitId(unitId);
|
|
489
|
+
if (mid && isDbAvailable()) {
|
|
490
|
+
const dbMilestone = getMilestone(mid);
|
|
491
|
+
if (!dbMilestone) return false;
|
|
492
|
+
if (!isClosedStatus(dbMilestone.status) && summaryOutcome !== "success") return false;
|
|
493
|
+
}
|
|
465
494
|
if (hasImplementationArtifacts(base) === "absent") return false;
|
|
466
495
|
}
|
|
467
496
|
|
|
@@ -532,6 +561,16 @@ export function writeBlockerPlaceholder(
|
|
|
532
561
|
try { updateSliceStatus(mid, sid, "complete", ts); } catch (e) { logWarning("recovery", `updateSliceStatus failed during context exhaustion: ${e instanceof Error ? e.message : String(e)}`); }
|
|
533
562
|
try { appendEvent(base, { cmd: "complete-slice", params: { milestoneId: mid, sliceId: sid }, ts, actor: "system", trigger_reason: "blocker-placeholder-recovery" }); } catch (e) { logWarning("recovery", `appendEvent failed for slice recovery: ${e instanceof Error ? e.message : String(e)}`); }
|
|
534
563
|
}
|
|
564
|
+
// Insert a placeholder complete slice so deriveState sees activeMilestoneSlices.length > 0
|
|
565
|
+
// and exits the pre-planning phase. Without this, activeMilestoneSlices stays empty
|
|
566
|
+
// after the blocker ROADMAP.md is written, causing deriveState to return phase:'pre-planning'
|
|
567
|
+
// indefinitely and re-dispatching plan-milestone in an infinite loop (#4378).
|
|
568
|
+
if (unitType === "plan-milestone" && mid) {
|
|
569
|
+
try {
|
|
570
|
+
insertSlice({ id: "S00-blocker", milestoneId: mid, title: "Blocker placeholder — planning failed", status: "complete", sequence: 0 });
|
|
571
|
+
} catch (e) { logWarning("recovery", `insertSlice placeholder failed for plan-milestone recovery: ${e instanceof Error ? e.message : String(e)}`); }
|
|
572
|
+
try { appendEvent(base, { cmd: "plan-milestone", params: { milestoneId: mid }, ts, actor: "system", trigger_reason: "blocker-placeholder-recovery" }); } catch (e) { logWarning("recovery", `appendEvent failed for plan-milestone recovery: ${e instanceof Error ? e.message : String(e)}`); }
|
|
573
|
+
}
|
|
535
574
|
}
|
|
536
575
|
|
|
537
576
|
return diagnoseExpectedArtifact(unitType, unitId, base);
|