gsd-pi 2.57.0 → 2.58.0-dev.778d6ac
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 +1 -1
- package/dist/cli.js +49 -35
- package/dist/headless-ui.d.ts +17 -0
- package/dist/headless-ui.js +97 -3
- package/dist/headless.js +67 -6
- package/dist/help-text.js +1 -0
- package/dist/onboarding.js +44 -0
- package/dist/resource-loader.js +16 -1
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/ask-user-questions.js +16 -3
- package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
- package/dist/resources/extensions/context7/extension-manifest.json +1 -1
- package/dist/resources/extensions/get-secrets-from-user.js +8 -5
- package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
- package/dist/resources/extensions/google-search/index.js +2 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +4 -0
- package/dist/resources/extensions/gsd/auto/phases.js +25 -21
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
- package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
- package/dist/resources/extensions/gsd/auto-dispatch.js +20 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
- package/dist/resources/extensions/gsd/auto-start.js +35 -22
- package/dist/resources/extensions/gsd/auto-worktree.js +203 -14
- package/dist/resources/extensions/gsd/auto.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -9
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
- package/dist/resources/extensions/gsd/captures.js +56 -4
- package/dist/resources/extensions/gsd/db-writer.js +116 -8
- package/dist/resources/extensions/gsd/dispatch-guard.js +11 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
- package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
- package/dist/resources/extensions/gsd/doctor.js +3 -1
- package/dist/resources/extensions/gsd/error-classifier.js +13 -10
- package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
- package/dist/resources/extensions/gsd/forensics.js +123 -20
- package/dist/resources/extensions/gsd/git-service.js +23 -1
- package/dist/resources/extensions/gsd/gitignore.js +33 -0
- package/dist/resources/extensions/gsd/gsd-db.js +44 -10
- package/dist/resources/extensions/gsd/guided-flow.js +106 -44
- package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
- package/dist/resources/extensions/gsd/health-widget.js +17 -0
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
- package/dist/resources/extensions/gsd/migrate-external.js +8 -1
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
- package/dist/resources/extensions/gsd/model-router.js +35 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +17 -0
- package/dist/resources/extensions/gsd/notifications.js +16 -1
- package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
- package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +23 -6
- package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
- package/dist/resources/extensions/gsd/paths.js +43 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +2 -1
- package/dist/resources/extensions/gsd/preferences.js +42 -31
- package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/repo-identity.js +205 -11
- package/dist/resources/extensions/gsd/rethink.js +5 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
- package/dist/resources/extensions/gsd/state.js +85 -27
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +18 -3
- package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
- package/dist/resources/extensions/gsd/undo.js +2 -2
- package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
- package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
- package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
- package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
- package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
- package/dist/resources/extensions/gsd/workspace-index.js +24 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
- package/dist/resources/extensions/mcp-client/index.js +11 -7
- package/dist/resources/extensions/ollama/index.js +112 -0
- package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
- package/dist/resources/extensions/ollama/ollama-client.js +168 -0
- package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
- package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
- package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
- package/dist/resources/extensions/ollama/types.js +2 -0
- package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/dist/resources/extensions/shared/interview-ui.js +11 -1
- package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/startup-model-validation.d.ts +39 -0
- package/dist/startup-model-validation.js +50 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- 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/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 +4 -4
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-4332cbd5dd1be584.js → webpack-a1c1e452c6b32d04.js} +1 -1
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +2 -1
- package/package.json +2 -2
- package/packages/daemon/src/cli.ts +49 -0
- package/packages/daemon/src/daemon.test.ts +104 -1
- package/packages/daemon/src/daemon.ts +24 -1
- package/packages/daemon/src/discord-bot.ts +73 -3
- package/packages/daemon/src/event-bridge.ts +15 -9
- package/packages/daemon/src/event-formatter.ts +30 -2
- package/packages/daemon/src/index.ts +9 -0
- package/packages/daemon/src/launchd.test.ts +356 -0
- package/packages/daemon/src/launchd.ts +242 -0
- package/packages/daemon/src/message-batcher.test.ts +2 -2
- package/packages/daemon/src/message-batcher.ts +9 -3
- package/packages/daemon/src/orchestrator.test.ts +1 -0
- package/packages/daemon/src/orchestrator.ts +106 -2
- package/packages/native/dist/ast/index.js +9 -5
- package/packages/native/dist/ast/types.js +2 -1
- package/packages/native/dist/clipboard/index.js +12 -7
- package/packages/native/dist/clipboard/types.js +2 -1
- package/packages/native/dist/diff/index.js +12 -7
- package/packages/native/dist/diff/types.js +2 -1
- package/packages/native/dist/fd/index.js +6 -3
- package/packages/native/dist/fd/types.js +2 -1
- package/packages/native/dist/glob/index.js +9 -5
- package/packages/native/dist/glob/types.js +2 -1
- package/packages/native/dist/grep/index.js +9 -5
- package/packages/native/dist/grep/types.js +2 -1
- package/packages/native/dist/gsd-parser/index.js +18 -11
- package/packages/native/dist/gsd-parser/types.js +2 -1
- package/packages/native/dist/highlight/index.js +12 -7
- package/packages/native/dist/highlight/types.js +2 -1
- package/packages/native/dist/html/index.js +6 -3
- package/packages/native/dist/html/types.js +2 -1
- package/packages/native/dist/image/index.js +10 -5
- package/packages/native/dist/image/types.js +7 -4
- package/packages/native/dist/index.js +70 -17
- package/packages/native/dist/json-parse/index.js +13 -8
- package/packages/native/dist/native.js +47 -10
- package/packages/native/dist/ps/index.js +15 -9
- package/packages/native/dist/ps/types.js +2 -1
- package/packages/native/dist/stream-process/index.js +12 -7
- package/packages/native/dist/text/index.js +24 -14
- package/packages/native/dist/text/types.js +5 -2
- package/packages/native/dist/truncate/index.js +12 -7
- package/packages/native/dist/ttsr/index.js +12 -7
- package/packages/native/dist/ttsr/types.js +2 -1
- package/packages/native/dist/xxhash/index.js +9 -5
- package/packages/native/package.json +19 -19
- package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
- package/packages/native/src/native.ts +9 -8
- package/packages/pi-agent-core/dist/agent-loop.js +3 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/proxy.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
- package/packages/pi-agent-core/src/agent-loop.ts +3 -2
- package/packages/pi-agent-core/src/proxy.ts +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +1 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.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 +19 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +3 -3
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +24 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +1 -0
- package/packages/pi-ai/src/index.ts +1 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
- package/packages/pi-ai/src/types.ts +3 -2
- package/packages/pi-ai/src/utils/json-parse.ts +28 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -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 +31 -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 +17 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/exec.js +3 -1
- package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.js +31 -2
- package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +2 -2
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
- package/packages/pi-coding-agent/src/core/exec.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
- package/packages/pi-coding-agent/src/core/index.ts +6 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
- package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
- package/packages/pi-coding-agent/src/core/messages.ts +29 -2
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
- package/packages/pi-coding-agent/src/index.ts +6 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +9 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/terminal.ts +14 -0
- package/packages/pi-tui/src/tui.ts +8 -0
- package/pkg/package.json +1 -1
- package/scripts/ensure-workspace-builds.cjs +45 -14
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/ask-user-questions.ts +21 -3
- package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
- package/src/resources/extensions/context7/extension-manifest.json +1 -1
- package/src/resources/extensions/get-secrets-from-user.ts +8 -5
- package/src/resources/extensions/google-search/extension-manifest.json +1 -1
- package/src/resources/extensions/google-search/index.ts +2 -1
- package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/phases.ts +43 -34
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
- package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
- package/src/resources/extensions/gsd/auto-dispatch.ts +21 -5
- package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-start.ts +35 -26
- package/src/resources/extensions/gsd/auto-worktree.ts +197 -11
- package/src/resources/extensions/gsd/auto.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +87 -9
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
- package/src/resources/extensions/gsd/captures.ts +63 -3
- package/src/resources/extensions/gsd/db-writer.ts +140 -7
- package/src/resources/extensions/gsd/dispatch-guard.ts +12 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
- package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +14 -11
- package/src/resources/extensions/gsd/extension-manifest.json +16 -1
- package/src/resources/extensions/gsd/forensics.ts +144 -20
- package/src/resources/extensions/gsd/git-service.ts +26 -3
- package/src/resources/extensions/gsd/gitignore.ts +33 -0
- package/src/resources/extensions/gsd/gsd-db.ts +49 -8
- package/src/resources/extensions/gsd/guided-flow.ts +114 -45
- package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
- package/src/resources/extensions/gsd/health-widget.ts +17 -0
- package/src/resources/extensions/gsd/index.ts +1 -0
- package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
- package/src/resources/extensions/gsd/migrate-external.ts +9 -1
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
- package/src/resources/extensions/gsd/model-router.ts +35 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +17 -0
- package/src/resources/extensions/gsd/notifications.ts +16 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
- package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -6
- package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
- package/src/resources/extensions/gsd/paths.ts +42 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +2 -1
- package/src/resources/extensions/gsd/preferences.ts +45 -29
- package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/repo-identity.ts +186 -11
- package/src/resources/extensions/gsd/rethink.ts +6 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
- package/src/resources/extensions/gsd/state.ts +84 -32
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
- package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +9 -8
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
- package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
- package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +27 -2
- package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +44 -2
- package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -2
- package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
- package/src/resources/extensions/gsd/types.ts +4 -2
- package/src/resources/extensions/gsd/undo.ts +2 -2
- package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
- package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
- package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
- package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
- package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
- package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
- package/src/resources/extensions/gsd/workspace-index.ts +30 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
- package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
- package/src/resources/extensions/mcp-client/index.ts +13 -7
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
- package/src/resources/extensions/ollama/index.ts +130 -0
- package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
- package/src/resources/extensions/ollama/ollama-client.ts +196 -0
- package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
- package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
- package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
- package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
- package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
- package/src/resources/extensions/ollama/types.ts +130 -0
- package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/src/resources/extensions/shared/interview-ui.ts +12 -1
- package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/web/standalone/.next/static/chunks/6502.2305d0afd2385711.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* Extracted from handleAgentEnd() in auto.ts.
|
|
12
12
|
*/
|
|
13
13
|
import { deriveState } from "./state.js";
|
|
14
|
+
import { logWarning, logError } from "./workflow-logger.js";
|
|
14
15
|
import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
|
|
15
16
|
import { loadPrompt } from "./prompt-loader.js";
|
|
16
17
|
import { resolveSliceFile, resolveTaskFile, resolveMilestoneFile, resolveTasksDir, buildTaskFileName, } from "./paths.js";
|
|
@@ -319,18 +320,18 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
319
320
|
ctx.ui.notify(`Triage: ${triageResult.quickTasks.length} quick-task${triageResult.quickTasks.length === 1 ? "" : "s"} queued for execution.`, "info");
|
|
320
321
|
}
|
|
321
322
|
for (const action of triageResult.actions) {
|
|
322
|
-
|
|
323
|
+
logWarning("engine", `triage resolution: ${action}`);
|
|
323
324
|
}
|
|
324
325
|
}
|
|
325
326
|
catch (err) {
|
|
326
|
-
|
|
327
|
+
logError("engine", "triage resolution failed", { error: err.message });
|
|
327
328
|
}
|
|
328
329
|
}
|
|
329
330
|
// Rogue file detection — safety net for LLM bypassing completion tools (D003)
|
|
330
331
|
try {
|
|
331
332
|
const rogueFiles = detectRogueFileWrites(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
332
333
|
for (const rogue of rogueFiles) {
|
|
333
|
-
|
|
334
|
+
logWarning("engine", "rogue file write detected", { path: rogue.path, unitId: rogue.unitId });
|
|
334
335
|
ctx.ui.notify(`Rogue file write detected: ${rogue.path}`, "warning");
|
|
335
336
|
}
|
|
336
337
|
}
|
|
@@ -372,7 +373,18 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
372
373
|
// When artifact verification fails for a unit type that has a known expected
|
|
373
374
|
// artifact, return "retry" so the caller re-dispatches with failure context
|
|
374
375
|
// instead of blindly re-dispatching the same unit (#1571).
|
|
375
|
-
|
|
376
|
+
//
|
|
377
|
+
// HOWEVER, if the DB is unavailable (db_unavailable), the artifact was never
|
|
378
|
+
// written because the completion tool failed at the infra level. Retrying
|
|
379
|
+
// can never succeed and produces a costly re-dispatch loop (#2517).
|
|
380
|
+
if (!triggerArtifactVerified && !isDbAvailable()) {
|
|
381
|
+
// DB infra failure — do NOT retry; the completion tool returned
|
|
382
|
+
// db_unavailable so the artifact was never written. Retrying would
|
|
383
|
+
// produce an infinite re-dispatch loop (#2517).
|
|
384
|
+
debugLog("postUnit", { phase: "artifact-verify-skip-db-unavailable", unitType: s.currentUnit.type, unitId: s.currentUnit.id });
|
|
385
|
+
ctx.ui.notify(`Artifact missing for ${s.currentUnit.type} ${s.currentUnit.id} but DB is unavailable — skipping retry to avoid loop (#2517)`, "error");
|
|
386
|
+
}
|
|
387
|
+
else if (!triggerArtifactVerified) {
|
|
376
388
|
const hasExpectedArtifact = resolveExpectedArtifactPath(s.currentUnit.type, s.currentUnit.id, s.basePath) !== null;
|
|
377
389
|
if (hasExpectedArtifact) {
|
|
378
390
|
const retryKey = `${s.currentUnit.type}:${s.currentUnit.id}`;
|
|
@@ -1403,7 +1403,7 @@ export async function buildRunUatPrompt(mid, sliceId, uatPath, uatContent, base)
|
|
|
1403
1403
|
if (projectInline)
|
|
1404
1404
|
inlined.push(projectInline);
|
|
1405
1405
|
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
1406
|
-
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "
|
|
1406
|
+
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "ASSESSMENT"));
|
|
1407
1407
|
const uatType = getUatType(uatContent);
|
|
1408
1408
|
return loadPrompt("run-uat", {
|
|
1409
1409
|
workingDirectory: base,
|
|
@@ -11,6 +11,7 @@ import { clearParseCache } from "./files.js";
|
|
|
11
11
|
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
|
12
12
|
import { isDbAvailable, getTask, getSlice, getSliceTasks, updateTaskStatus } from "./gsd-db.js";
|
|
13
13
|
import { isValidationTerminal } from "./state.js";
|
|
14
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
14
15
|
import { nativeConflictFiles, nativeCommit, nativeCheckoutTheirs, nativeAddPaths, nativeMergeAbort, nativeResetHard, } from "./native-git-bridge.js";
|
|
15
16
|
import { resolveSlicePath, resolveSliceFile, resolveTasksDir, resolveTaskFiles, relMilestoneFile, relSliceFile, buildSliceFileName, resolveMilestoneFile, clearPathCache, resolveGsdRootFile, } from "./paths.js";
|
|
16
17
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, } from "node:fs";
|
|
@@ -425,12 +426,19 @@ export function reconcileMergeState(basePath, ctx) {
|
|
|
425
426
|
if (conflictedFiles.length === 0) {
|
|
426
427
|
// All conflicts resolved — finalize the merge/squash commit
|
|
427
428
|
try {
|
|
428
|
-
nativeCommit(basePath, ""); // --no-edit equivalent: use empty message placeholder
|
|
429
|
-
|
|
430
|
-
|
|
429
|
+
const commitSha = nativeCommit(basePath, ""); // --no-edit equivalent: use empty message placeholder
|
|
430
|
+
if (commitSha) {
|
|
431
|
+
const mode = hasMergeHead ? "merge" : "squash commit";
|
|
432
|
+
ctx.ui.notify(`Finalized leftover ${mode} from prior session.`, "info");
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
ctx.ui.notify("No new commit needed for leftover merge/squash state — already committed.", "info");
|
|
436
|
+
}
|
|
431
437
|
}
|
|
432
|
-
catch {
|
|
433
|
-
|
|
438
|
+
catch (err) {
|
|
439
|
+
const errorMessage = getErrorMessage(err);
|
|
440
|
+
ctx.ui.notify(`Failed to finalize leftover merge/squash commit: ${errorMessage}`, "error");
|
|
441
|
+
return false;
|
|
434
442
|
}
|
|
435
443
|
}
|
|
436
444
|
else {
|
|
@@ -30,15 +30,14 @@ import { initRoutingHistory } from "./routing-history.js";
|
|
|
30
30
|
import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
|
|
31
31
|
import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
|
|
32
32
|
import { snapshotSkills } from "./skill-discovery.js";
|
|
33
|
-
import { isDbAvailable, getMilestone
|
|
33
|
+
import { isDbAvailable, getMilestone } from "./gsd-db.js";
|
|
34
34
|
import { hideFooter } from "./auto-dashboard.js";
|
|
35
|
-
import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
|
|
36
35
|
import { debugLog, enableDebug, isDebugEnabled, getDebugLogPath, } from "./debug-logger.js";
|
|
37
36
|
import { parseUnitId } from "./unit-id.js";
|
|
38
|
-
import { setLogBasePath } from "./workflow-logger.js";
|
|
39
37
|
import { existsSync, mkdirSync, readdirSync, statSync, unlinkSync, } from "node:fs";
|
|
40
38
|
import { join } from "node:path";
|
|
41
39
|
import { sep as pathSep } from "node:path";
|
|
40
|
+
import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
|
|
42
41
|
/**
|
|
43
42
|
* Bootstrap a fresh auto-mode session. Handles everything from git init
|
|
44
43
|
* through secrets collection, returning when ready for the first
|
|
@@ -47,23 +46,33 @@ import { sep as pathSep } from "node:path";
|
|
|
47
46
|
* Returns false if the bootstrap aborted (e.g., guided flow returned,
|
|
48
47
|
* concurrent session detected). Returns true when ready to dispatch.
|
|
49
48
|
*/
|
|
50
|
-
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Open the project-root DB before the first deriveState call (#2841).
|
|
51
|
+
* When auto-mode starts cold (no prior DB handle), state derivation that
|
|
52
|
+
* touches DB-backed helpers (queue-order, task status) silently falls back
|
|
53
|
+
* to markdown-only data, producing stale or incomplete state. Opening the
|
|
54
|
+
* DB first ensures deriveState sees the full picture on its very first run.
|
|
55
|
+
*/
|
|
56
56
|
async function openProjectDbIfPresent(basePath) {
|
|
57
57
|
const gsdDbPath = resolveProjectRootDbPath(basePath);
|
|
58
|
-
if (!existsSync(gsdDbPath)
|
|
58
|
+
if (!existsSync(gsdDbPath))
|
|
59
|
+
return;
|
|
60
|
+
if (isDbAvailable())
|
|
59
61
|
return;
|
|
60
62
|
try {
|
|
63
|
+
const { openDatabase } = await import("./gsd-db.js");
|
|
61
64
|
openDatabase(gsdDbPath);
|
|
62
65
|
}
|
|
63
|
-
catch
|
|
64
|
-
|
|
66
|
+
catch {
|
|
67
|
+
/* non-fatal — DB lifecycle block below will retry */
|
|
65
68
|
}
|
|
66
69
|
}
|
|
70
|
+
/** Guard: tracks consecutive bootstrap attempts that found phase === "complete".
|
|
71
|
+
* Prevents the recursive dialog loop described in #1348 where
|
|
72
|
+
* bootstrapAutoSession → showSmartEntry → checkAutoStartAfterDiscuss → startAuto
|
|
73
|
+
* cycles indefinitely when the discuss workflow doesn't produce a milestone. */
|
|
74
|
+
let _consecutiveCompleteBootstraps = 0;
|
|
75
|
+
const MAX_CONSECUTIVE_COMPLETE_BOOTSTRAPS = 2;
|
|
67
76
|
export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, deps) {
|
|
68
77
|
const { shouldUseWorktreeIsolation, registerSigtermHandler, lockBase, buildResolver, } = deps;
|
|
69
78
|
const lockResult = acquireSessionLock(base);
|
|
@@ -120,10 +129,13 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
120
129
|
ensureGitignore(base, { manageGitignore });
|
|
121
130
|
if (manageGitignore !== false)
|
|
122
131
|
untrackRuntimeFiles(base);
|
|
123
|
-
// Bootstrap
|
|
132
|
+
// Bootstrap milestones/ if it doesn't exist.
|
|
133
|
+
// Check milestones/ directly — ensureGsdSymlink above already created .gsd/,
|
|
134
|
+
// so checking .gsd/ existence would be dead code (#2942).
|
|
124
135
|
const gsdDir = join(base, ".gsd");
|
|
125
|
-
|
|
126
|
-
|
|
136
|
+
const milestonesPath = join(gsdDir, "milestones");
|
|
137
|
+
if (!existsSync(milestonesPath)) {
|
|
138
|
+
mkdirSync(milestonesPath, { recursive: true });
|
|
127
139
|
try {
|
|
128
140
|
nativeAddAll(base);
|
|
129
141
|
nativeCommit(base, "chore: init gsd");
|
|
@@ -178,13 +190,13 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
178
190
|
});
|
|
179
191
|
ctx.ui.notify(`Debug logging enabled → ${getDebugLogPath()}`, "info");
|
|
180
192
|
}
|
|
181
|
-
// Open the project DB before the first derive so resume uses DB truth
|
|
182
|
-
// immediately on cold starts instead of falling back to markdown (#2841).
|
|
183
|
-
await openProjectDbIfPresent(base);
|
|
184
193
|
// Invalidate caches before initial state derivation
|
|
185
194
|
invalidateAllCaches();
|
|
186
195
|
// Clean stale runtime unit files for completed milestones (#887)
|
|
187
196
|
cleanStaleRuntimeUnits(gsdRoot(base), (mid) => !!resolveMilestoneFile(base, mid, "SUMMARY"));
|
|
197
|
+
// Open the project-root DB before deriveState so DB-backed state
|
|
198
|
+
// derivation (queue-order, task status) works on a cold start (#2841).
|
|
199
|
+
await openProjectDbIfPresent(base);
|
|
188
200
|
let state = await deriveState(base);
|
|
189
201
|
// Stale worktree state recovery (#654)
|
|
190
202
|
if (state.activeMilestone &&
|
|
@@ -336,7 +348,6 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
336
348
|
s.verbose = verboseMode;
|
|
337
349
|
s.cmdCtx = ctx;
|
|
338
350
|
s.basePath = base;
|
|
339
|
-
setLogBasePath(base);
|
|
340
351
|
s.unitDispatchCount.clear();
|
|
341
352
|
s.unitRecoveryCount.clear();
|
|
342
353
|
s.lastBudgetAlertLevel = 0;
|
|
@@ -392,14 +403,15 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
392
403
|
}
|
|
393
404
|
}
|
|
394
405
|
// ── DB lifecycle ──
|
|
395
|
-
const gsdDbPath =
|
|
406
|
+
const gsdDbPath = join(s.basePath, ".gsd", "gsd.db");
|
|
396
407
|
const gsdDirPath = join(s.basePath, ".gsd");
|
|
397
408
|
if (existsSync(gsdDirPath) && !existsSync(gsdDbPath)) {
|
|
398
409
|
const hasDecisions = existsSync(join(gsdDirPath, "DECISIONS.md"));
|
|
399
410
|
const hasRequirements = existsSync(join(gsdDirPath, "REQUIREMENTS.md"));
|
|
400
411
|
const hasMilestones = existsSync(join(gsdDirPath, "milestones"));
|
|
401
412
|
try {
|
|
402
|
-
openDatabase(
|
|
413
|
+
const { openDatabase: openDb } = await import("./gsd-db.js");
|
|
414
|
+
openDb(gsdDbPath);
|
|
403
415
|
if (hasDecisions || hasRequirements || hasMilestones) {
|
|
404
416
|
const { migrateFromMarkdown } = await import("./md-importer.js");
|
|
405
417
|
migrateFromMarkdown(s.basePath);
|
|
@@ -411,7 +423,8 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
411
423
|
}
|
|
412
424
|
if (existsSync(gsdDbPath) && !isDbAvailable()) {
|
|
413
425
|
try {
|
|
414
|
-
openDatabase(
|
|
426
|
+
const { openDatabase: openDb } = await import("./gsd-db.js");
|
|
427
|
+
openDb(gsdDbPath);
|
|
415
428
|
}
|
|
416
429
|
catch (err) {
|
|
417
430
|
process.stderr.write(`gsd-db: failed to open existing database: ${err.message}\n`);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* manual `/worktree` which uses `worktree/<name>` branches). This module
|
|
6
6
|
* manages create, enter, detect, and teardown for auto-mode worktrees.
|
|
7
7
|
*/
|
|
8
|
-
import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, lstatSync as lstatSyncFn, } from "node:fs";
|
|
8
|
+
import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, statSync, lstatSync as lstatSyncFn, } from "node:fs";
|
|
9
9
|
import { isAbsolute, join, sep as pathSep } from "node:path";
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
11
|
import { GSDError, GSD_IO_ERROR, GSD_GIT_ERROR } from "./errors.js";
|
|
@@ -20,7 +20,7 @@ import { MergeConflictError, readIntegrationBranch, RUNTIME_EXCLUSION_PATHS } fr
|
|
|
20
20
|
import { debugLog } from "./debug-logger.js";
|
|
21
21
|
import { logWarning } from "./workflow-logger.js";
|
|
22
22
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
23
|
-
import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, } from "./native-git-bridge.js";
|
|
23
|
+
import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, nativeMergeAbort, } from "./native-git-bridge.js";
|
|
24
24
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
25
25
|
const PROJECT_PREFERENCES_FILE = "PREFERENCES.md";
|
|
26
26
|
const LEGACY_PROJECT_PREFERENCES_FILE = "preferences.md";
|
|
@@ -39,6 +39,7 @@ const ROOT_STATE_FILES = [
|
|
|
39
39
|
"QUEUE.md",
|
|
40
40
|
"completed-units.json",
|
|
41
41
|
"metrics.json",
|
|
42
|
+
"mcp.json",
|
|
42
43
|
// NOTE: project preferences are intentionally NOT in ROOT_STATE_FILES.
|
|
43
44
|
// Forward-sync (main → worktree) is handled explicitly in syncGsdStateToWorktree().
|
|
44
45
|
// Back-sync (worktree → main) must NEVER overwrite the project root's copy
|
|
@@ -56,6 +57,65 @@ function isSamePath(a, b) {
|
|
|
56
57
|
return false;
|
|
57
58
|
}
|
|
58
59
|
}
|
|
60
|
+
// ─── ASSESSMENT Force-Sync Helper (#2821) ─────────────────────────────────
|
|
61
|
+
/** Regex matching YAML frontmatter `verdict:` field. */
|
|
62
|
+
const VERDICT_RE = /verdict:\s*[\w-]+/i;
|
|
63
|
+
/**
|
|
64
|
+
* Walk a milestone directory and force-overwrite ASSESSMENT files in the
|
|
65
|
+
* destination when the source copy contains a `verdict:` field.
|
|
66
|
+
*
|
|
67
|
+
* This is the targeted fix for the UAT stuck-loop (#2821): the main
|
|
68
|
+
* safeCopyRecursive uses force:false to protect worktree-authoritative
|
|
69
|
+
* files (#1886), but ASSESSMENT files written by run-uat must be
|
|
70
|
+
* forward-synced when the project root has a verdict. Without this,
|
|
71
|
+
* the worktree retains a stale FAIL or missing ASSESSMENT and
|
|
72
|
+
* checkNeedsRunUat re-dispatches run-uat indefinitely.
|
|
73
|
+
*
|
|
74
|
+
* Only overwrites when the source has a verdict — never clobbers a
|
|
75
|
+
* worktree ASSESSMENT with a verdictless project-root copy.
|
|
76
|
+
*/
|
|
77
|
+
function forceOverwriteAssessmentsWithVerdict(srcMilestoneDir, dstMilestoneDir) {
|
|
78
|
+
if (!existsSync(srcMilestoneDir))
|
|
79
|
+
return;
|
|
80
|
+
// Walk slices/<SID>/ looking for *-ASSESSMENT.md files
|
|
81
|
+
const slicesDir = join(srcMilestoneDir, "slices");
|
|
82
|
+
if (!existsSync(slicesDir))
|
|
83
|
+
return;
|
|
84
|
+
try {
|
|
85
|
+
for (const sliceEntry of readdirSync(slicesDir, { withFileTypes: true })) {
|
|
86
|
+
if (!sliceEntry.isDirectory())
|
|
87
|
+
continue;
|
|
88
|
+
const srcSliceDir = join(slicesDir, sliceEntry.name);
|
|
89
|
+
const dstSliceDir = join(dstMilestoneDir, "slices", sliceEntry.name);
|
|
90
|
+
try {
|
|
91
|
+
for (const fileEntry of readdirSync(srcSliceDir, { withFileTypes: true })) {
|
|
92
|
+
if (!fileEntry.isFile())
|
|
93
|
+
continue;
|
|
94
|
+
if (!fileEntry.name.endsWith("-ASSESSMENT.md"))
|
|
95
|
+
continue;
|
|
96
|
+
const srcFile = join(srcSliceDir, fileEntry.name);
|
|
97
|
+
try {
|
|
98
|
+
const srcContent = readFileSync(srcFile, "utf-8");
|
|
99
|
+
if (!VERDICT_RE.test(srcContent))
|
|
100
|
+
continue; // no verdict in source — skip
|
|
101
|
+
// Source has a verdict — force-copy into worktree
|
|
102
|
+
mkdirSync(dstSliceDir, { recursive: true });
|
|
103
|
+
safeCopy(srcFile, join(dstSliceDir, fileEntry.name), { force: true });
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
/* non-fatal per file */
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
/* non-fatal per slice */
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
/* non-fatal */
|
|
117
|
+
}
|
|
118
|
+
}
|
|
59
119
|
// ─── Module State ──────────────────────────────────────────────────────────
|
|
60
120
|
/** Original project root before chdir into auto-worktree. */
|
|
61
121
|
let originalBase = null;
|
|
@@ -147,16 +207,31 @@ export function syncProjectRootToWorktree(projectRoot, worktreePath_, milestoneI
|
|
|
147
207
|
// by validate-milestone) get clobbered by stale project root copies,
|
|
148
208
|
// causing an infinite re-validation loop (#1886).
|
|
149
209
|
safeCopyRecursive(join(prGsd, "milestones", milestoneId), join(wtGsd, "milestones", milestoneId), { force: false });
|
|
210
|
+
// Force-sync ASSESSMENT files that have a verdict from project root (#2821).
|
|
211
|
+
// The additive-only copy above preserves worktree-authoritative files, but
|
|
212
|
+
// ASSESSMENT files are special: after run-uat writes a verdict and post-unit
|
|
213
|
+
// syncs it to the project root, the worktree may retain a stale copy (e.g.
|
|
214
|
+
// verdict:fail while the project root has verdict:pass from a retry). On
|
|
215
|
+
// session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
|
|
216
|
+
// persists, checkNeedsRunUat finds no passing verdict → re-dispatches
|
|
217
|
+
// run-uat indefinitely (stuck-loop ×9).
|
|
218
|
+
forceOverwriteAssessmentsWithVerdict(join(prGsd, "milestones", milestoneId), join(wtGsd, "milestones", milestoneId));
|
|
150
219
|
// Forward-sync completed-units.json from project root to worktree.
|
|
151
220
|
// Project root is authoritative for completion state after crash recovery;
|
|
152
221
|
// without this, the worktree re-dispatches already-completed units (#1886).
|
|
153
222
|
safeCopy(join(prGsd, "completed-units.json"), join(wtGsd, "completed-units.json"), { force: true });
|
|
154
|
-
// Delete worktree gsd.db
|
|
155
|
-
//
|
|
223
|
+
// Delete worktree gsd.db ONLY if it is empty (0 bytes).
|
|
224
|
+
// An empty DB is stale/corrupt and should be rebuilt (#853).
|
|
225
|
+
// A non-empty DB was populated by gsd-migrate on respawn and must be
|
|
226
|
+
// preserved — deleting it truncates the file to 0 bytes when
|
|
227
|
+
// openDatabase re-creates it, causing "no such table" failures (#2815).
|
|
156
228
|
try {
|
|
157
229
|
const wtDb = join(wtGsd, "gsd.db");
|
|
158
230
|
if (existsSync(wtDb)) {
|
|
159
|
-
|
|
231
|
+
const size = statSync(wtDb).size;
|
|
232
|
+
if (size === 0) {
|
|
233
|
+
unlinkSync(wtDb);
|
|
234
|
+
}
|
|
160
235
|
}
|
|
161
236
|
}
|
|
162
237
|
catch {
|
|
@@ -855,6 +930,7 @@ function copyPlanningArtifacts(srcBase, wtPath) {
|
|
|
855
930
|
"STATE.md",
|
|
856
931
|
"KNOWLEDGE.md",
|
|
857
932
|
"OVERRIDES.md",
|
|
933
|
+
"mcp.json",
|
|
858
934
|
]) {
|
|
859
935
|
safeCopy(join(srcGsd, file), join(dstGsd, file), { force: true });
|
|
860
936
|
}
|
|
@@ -1060,12 +1136,17 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1060
1136
|
const milestoneBranch = autoWorktreeBranch(milestoneId);
|
|
1061
1137
|
// 1. Auto-commit dirty state in worktree before leaving
|
|
1062
1138
|
autoCommitDirtyState(worktreeCwd);
|
|
1063
|
-
// Reconcile worktree DB into main DB before leaving worktree context
|
|
1139
|
+
// Reconcile worktree DB into main DB before leaving worktree context.
|
|
1140
|
+
// Skip when both paths resolve to the same physical file (shared WAL /
|
|
1141
|
+
// symlink layout) — ATTACHing a WAL-mode file to itself corrupts the
|
|
1142
|
+
// database (#2823).
|
|
1064
1143
|
if (isDbAvailable()) {
|
|
1065
1144
|
try {
|
|
1066
1145
|
const worktreeDbPath = join(worktreeCwd, ".gsd", "gsd.db");
|
|
1067
1146
|
const mainDbPath = join(originalBasePath_, ".gsd", "gsd.db");
|
|
1068
|
-
|
|
1147
|
+
if (!isSamePath(worktreeDbPath, mainDbPath)) {
|
|
1148
|
+
reconcileWorktreeDb(mainDbPath, worktreeDbPath);
|
|
1149
|
+
}
|
|
1069
1150
|
}
|
|
1070
1151
|
catch {
|
|
1071
1152
|
/* non-fatal */
|
|
@@ -1190,7 +1271,17 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1190
1271
|
encoding: "utf-8",
|
|
1191
1272
|
}).trim();
|
|
1192
1273
|
if (status) {
|
|
1193
|
-
|
|
1274
|
+
// Use --include-untracked to stash untracked files that would block
|
|
1275
|
+
// the squash merge, but EXCLUDE .gsd/milestones/ (#2505).
|
|
1276
|
+
// --include-untracked without exclusion sweeps queued milestone
|
|
1277
|
+
// CONTEXT files into the stash. If stash pop later fails, those files
|
|
1278
|
+
// are permanently trapped in the stash entry and lost on the next
|
|
1279
|
+
// stash push or drop.
|
|
1280
|
+
execFileSync("git", [
|
|
1281
|
+
"stash", "push", "--include-untracked",
|
|
1282
|
+
"-m", `gsd: pre-merge stash for ${milestoneId}`,
|
|
1283
|
+
"--", ":(exclude).gsd/milestones",
|
|
1284
|
+
], { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
|
|
1194
1285
|
stashed = true;
|
|
1195
1286
|
}
|
|
1196
1287
|
}
|
|
@@ -1198,6 +1289,69 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1198
1289
|
// Stash failure is non-fatal — proceed without stash and let the merge
|
|
1199
1290
|
// report the dirty tree if it fails.
|
|
1200
1291
|
}
|
|
1292
|
+
// 7a. Shelter queued milestone directories before the squash merge (#2505).
|
|
1293
|
+
// The milestone branch may contain copies of queued milestone dirs (via
|
|
1294
|
+
// copyPlanningArtifacts), so `git merge --squash` rejects when those same
|
|
1295
|
+
// files exist as untracked in the working tree. Temporarily move them to
|
|
1296
|
+
// a backup location, then restore after the merge+commit.
|
|
1297
|
+
const milestonesDir = join(gsdRoot(originalBasePath_), "milestones");
|
|
1298
|
+
const shelterDir = join(gsdRoot(originalBasePath_), ".milestone-shelter");
|
|
1299
|
+
const shelteredDirs = [];
|
|
1300
|
+
// Helper: restore sheltered milestone directories (#2505).
|
|
1301
|
+
// Called on both success and error paths to ensure queued CONTEXT files
|
|
1302
|
+
// are never permanently lost.
|
|
1303
|
+
const restoreShelter = () => {
|
|
1304
|
+
if (shelteredDirs.length === 0)
|
|
1305
|
+
return;
|
|
1306
|
+
for (const dirName of shelteredDirs) {
|
|
1307
|
+
try {
|
|
1308
|
+
mkdirSync(milestonesDir, { recursive: true });
|
|
1309
|
+
cpSync(join(shelterDir, dirName), join(milestonesDir, dirName), { recursive: true, force: true });
|
|
1310
|
+
}
|
|
1311
|
+
catch { /* best-effort */ }
|
|
1312
|
+
}
|
|
1313
|
+
try {
|
|
1314
|
+
rmSync(shelterDir, { recursive: true, force: true });
|
|
1315
|
+
}
|
|
1316
|
+
catch { /* best-effort */ }
|
|
1317
|
+
};
|
|
1318
|
+
try {
|
|
1319
|
+
if (existsSync(milestonesDir)) {
|
|
1320
|
+
const entries = readdirSync(milestonesDir, { withFileTypes: true });
|
|
1321
|
+
for (const entry of entries) {
|
|
1322
|
+
if (!entry.isDirectory())
|
|
1323
|
+
continue;
|
|
1324
|
+
// Only shelter directories that do NOT belong to the milestone being merged
|
|
1325
|
+
if (entry.name === milestoneId)
|
|
1326
|
+
continue;
|
|
1327
|
+
const srcDir = join(milestonesDir, entry.name);
|
|
1328
|
+
const dstDir = join(shelterDir, entry.name);
|
|
1329
|
+
try {
|
|
1330
|
+
mkdirSync(shelterDir, { recursive: true });
|
|
1331
|
+
cpSync(srcDir, dstDir, { recursive: true, force: true });
|
|
1332
|
+
rmSync(srcDir, { recursive: true, force: true });
|
|
1333
|
+
shelteredDirs.push(entry.name);
|
|
1334
|
+
}
|
|
1335
|
+
catch {
|
|
1336
|
+
// Non-fatal — if shelter fails, the merge may still succeed
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
catch {
|
|
1342
|
+
// Non-fatal — proceed with merge; untracked files may block it
|
|
1343
|
+
}
|
|
1344
|
+
// 7c. Clean stale MERGE_HEAD before the squash merge (#2912).
|
|
1345
|
+
// The native (libgit2) merge path or a prior interrupted merge may leave
|
|
1346
|
+
// MERGE_HEAD in the git dir. `git merge --squash` refuses to run when
|
|
1347
|
+
// MERGE_HEAD exists, so remove it preemptively.
|
|
1348
|
+
try {
|
|
1349
|
+
const gitDirPre = resolveGitDir(originalBasePath_);
|
|
1350
|
+
const mergeHeadPre = join(gitDirPre, "MERGE_HEAD");
|
|
1351
|
+
if (existsSync(mergeHeadPre))
|
|
1352
|
+
unlinkSync(mergeHeadPre);
|
|
1353
|
+
}
|
|
1354
|
+
catch { /* best-effort */ }
|
|
1201
1355
|
// 8. Squash merge — auto-resolve .gsd/ state file conflicts (#530)
|
|
1202
1356
|
const mergeResult = nativeMergeSquash(originalBasePath_, milestoneBranch);
|
|
1203
1357
|
if (!mergeResult.success) {
|
|
@@ -1205,6 +1359,17 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1205
1359
|
// untracked .gsd/ files left by syncStateToProjectRoot). Preserve the
|
|
1206
1360
|
// milestone branch so commits are not lost.
|
|
1207
1361
|
if (mergeResult.conflicts.includes("__dirty_working_tree__")) {
|
|
1362
|
+
// Defensively clean merge state — the native path may leave MERGE_HEAD
|
|
1363
|
+
// even when the merge is rejected (#2912).
|
|
1364
|
+
try {
|
|
1365
|
+
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1366
|
+
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1367
|
+
const p = join(gitDir_, f);
|
|
1368
|
+
if (existsSync(p))
|
|
1369
|
+
unlinkSync(p);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
catch { /* best-effort */ }
|
|
1208
1373
|
// Pop stash before throwing so local work is not lost.
|
|
1209
1374
|
if (stashed) {
|
|
1210
1375
|
try {
|
|
@@ -1216,6 +1381,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1216
1381
|
}
|
|
1217
1382
|
catch { /* stash pop conflict is non-fatal */ }
|
|
1218
1383
|
}
|
|
1384
|
+
restoreShelter();
|
|
1219
1385
|
// Restore cwd so the caller is not stranded on the integration branch
|
|
1220
1386
|
process.chdir(previousCwd);
|
|
1221
1387
|
// Surface the actual dirty filenames from git stderr instead of
|
|
@@ -1253,6 +1419,22 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1253
1419
|
}
|
|
1254
1420
|
// If there are still real code conflicts, escalate
|
|
1255
1421
|
if (codeConflicts.length > 0) {
|
|
1422
|
+
// Abort merge state so MERGE_HEAD is not left on disk (#2912).
|
|
1423
|
+
// libgit2's merge creates MERGE_HEAD even for squash merges; if left
|
|
1424
|
+
// dangling, subsequent merges fail and doctor reports corrupt state.
|
|
1425
|
+
try {
|
|
1426
|
+
nativeMergeAbort(originalBasePath_);
|
|
1427
|
+
}
|
|
1428
|
+
catch { /* best-effort */ }
|
|
1429
|
+
try {
|
|
1430
|
+
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1431
|
+
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1432
|
+
const p = join(gitDir_, f);
|
|
1433
|
+
if (existsSync(p))
|
|
1434
|
+
unlinkSync(p);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
catch { /* best-effort */ }
|
|
1256
1438
|
// Pop stash before throwing so local work is not lost (#2151).
|
|
1257
1439
|
if (stashed) {
|
|
1258
1440
|
try {
|
|
@@ -1264,6 +1446,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1264
1446
|
}
|
|
1265
1447
|
catch { /* stash pop conflict is non-fatal */ }
|
|
1266
1448
|
}
|
|
1449
|
+
restoreShelter();
|
|
1267
1450
|
throw new MergeConflictError(codeConflicts, "squash", milestoneBranch, mainBranch);
|
|
1268
1451
|
}
|
|
1269
1452
|
}
|
|
@@ -1272,15 +1455,19 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1272
1455
|
// 9. Commit (handle nothing-to-commit gracefully)
|
|
1273
1456
|
const commitResult = nativeCommit(originalBasePath_, commitMessage);
|
|
1274
1457
|
const nothingToCommit = commitResult === null;
|
|
1275
|
-
// 9a. Clean up
|
|
1458
|
+
// 9a. Clean up merge state files left by git merge --squash (#1853, #2912).
|
|
1276
1459
|
// git only removes SQUASH_MSG when the commit reads it directly (plain
|
|
1277
1460
|
// `git commit`). nativeCommit uses `-F -` (stdin) or libgit2, neither
|
|
1278
|
-
// of which trigger git's SQUASH_MSG cleanup.
|
|
1279
|
-
//
|
|
1461
|
+
// of which trigger git's SQUASH_MSG cleanup. MERGE_HEAD is created by
|
|
1462
|
+
// libgit2's merge even in squash mode and is not removed by nativeCommit.
|
|
1463
|
+
// If left on disk, doctor reports `corrupt_merge_state` on every subsequent run.
|
|
1280
1464
|
try {
|
|
1281
|
-
const
|
|
1282
|
-
|
|
1283
|
-
|
|
1465
|
+
const gitDir_ = resolveGitDir(originalBasePath_);
|
|
1466
|
+
for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
|
|
1467
|
+
const p = join(gitDir_, f);
|
|
1468
|
+
if (existsSync(p))
|
|
1469
|
+
unlinkSync(p);
|
|
1470
|
+
}
|
|
1284
1471
|
}
|
|
1285
1472
|
catch { /* best-effort */ }
|
|
1286
1473
|
// 9a-ii. Restore stashed files now that the merge+commit is complete (#2151).
|
|
@@ -1340,6 +1527,8 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1340
1527
|
}
|
|
1341
1528
|
}
|
|
1342
1529
|
}
|
|
1530
|
+
// 9a-iii. Restore sheltered queued milestone directories (#2505).
|
|
1531
|
+
restoreShelter();
|
|
1343
1532
|
// 9b. Safety check (#1792): if nothing was committed, verify the milestone
|
|
1344
1533
|
// work is already on the integration branch before allowing teardown.
|
|
1345
1534
|
// Compare only non-.gsd/ paths — .gsd/ state files diverge normally and
|
|
@@ -774,6 +774,10 @@ function buildLoopDeps() {
|
|
|
774
774
|
};
|
|
775
775
|
}
|
|
776
776
|
export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
777
|
+
if (s.active) {
|
|
778
|
+
debugLog("startAuto", { phase: "already-active", skipping: true });
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
777
781
|
const requestedStepMode = options?.step ?? false;
|
|
778
782
|
// Escape stale worktree cwd from a previous milestone (#608).
|
|
779
783
|
base = escapeStaleWorktree(base);
|
|
@@ -48,6 +48,30 @@ export async function handleAgentEnd(pi, event, ctx) {
|
|
|
48
48
|
return;
|
|
49
49
|
const lastMsg = event.messages[event.messages.length - 1];
|
|
50
50
|
if (lastMsg && "stopReason" in lastMsg && lastMsg.stopReason === "aborted") {
|
|
51
|
+
// Empty content with aborted stopReason is a non-fatal agent stop (the LLM
|
|
52
|
+
// chose to end without producing output). Only pause on genuine fatal aborts
|
|
53
|
+
// that carry error context — e.g. errorMessage field or non-empty content
|
|
54
|
+
// indicating a mid-stream failure. (#2695)
|
|
55
|
+
const content = "content" in lastMsg ? lastMsg.content : undefined;
|
|
56
|
+
const hasEmptyContent = Array.isArray(content) && content.length === 0;
|
|
57
|
+
const hasErrorMessage = "errorMessage" in lastMsg && !!lastMsg.errorMessage;
|
|
58
|
+
if (hasEmptyContent && !hasErrorMessage) {
|
|
59
|
+
// Non-fatal: treat as a normal agent end so the loop can continue
|
|
60
|
+
// instead of entering a stuck re-dispatch cycle.
|
|
61
|
+
try {
|
|
62
|
+
resetRetryState(retryState);
|
|
63
|
+
resolveAgentEnd(event);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
67
|
+
ctx.ui.notify(`Auto-mode error after empty-content abort: ${message}. Stopping auto-mode.`, "error");
|
|
68
|
+
try {
|
|
69
|
+
await pauseAuto(ctx, pi);
|
|
70
|
+
}
|
|
71
|
+
catch { /* best-effort */ }
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
51
75
|
await pauseAuto(ctx, pi);
|
|
52
76
|
return;
|
|
53
77
|
}
|
|
@@ -57,6 +81,14 @@ export async function handleAgentEnd(pi, event, ctx) {
|
|
|
57
81
|
const explicitRetryAfterMs = ("retryAfterMs" in lastMsg && typeof lastMsg.retryAfterMs === "number") ? lastMsg.retryAfterMs : undefined;
|
|
58
82
|
// ── 1. Classify ──────────────────────────────────────────────────────
|
|
59
83
|
const cls = classifyError(errorMsg, explicitRetryAfterMs);
|
|
84
|
+
// Cap rate-limit backoff for CLI-style providers (openai-codex, google-gemini-cli)
|
|
85
|
+
// which use per-user quotas with shorter windows (#2922).
|
|
86
|
+
if (cls.kind === "rate-limit") {
|
|
87
|
+
const currentProvider = ctx.model?.provider;
|
|
88
|
+
if (currentProvider === "openai-codex" || currentProvider === "google-gemini-cli") {
|
|
89
|
+
cls.retryAfterMs = Math.min(cls.retryAfterMs, 30_000);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
60
92
|
// ── 2. Decide & Act ──────────────────────────────────────────────────
|
|
61
93
|
// --- Network errors: same-model retry with backoff ---
|
|
62
94
|
if (cls.kind === "network") {
|