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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
|
|
@@ -6,6 +6,7 @@ import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
|
|
6
6
|
|
|
7
7
|
import { debugTime } from "../debug-logger.js";
|
|
8
8
|
import { loadPrompt } from "../prompt-loader.js";
|
|
9
|
+
import { readForensicsMarker } from "../forensics.js";
|
|
9
10
|
import { resolveAllSkillReferences, renderPreferencesForSystemPrompt, loadEffectiveGSDPreferences } from "../preferences.js";
|
|
10
11
|
import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
|
|
11
12
|
import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
|
|
@@ -97,27 +98,30 @@ export async function buildBeforeAgentStartResult(
|
|
|
97
98
|
warnDeprecatedAgentInstructions();
|
|
98
99
|
|
|
99
100
|
const injection = await buildGuidedExecuteContextInjection(event.prompt, process.cwd());
|
|
101
|
+
|
|
102
|
+
// Re-inject forensics context on follow-up turns (#2941)
|
|
103
|
+
const forensicsInjection = !injection ? buildForensicsContextInjection(process.cwd()) : null;
|
|
104
|
+
|
|
100
105
|
const worktreeBlock = buildWorktreeContextBlock();
|
|
101
106
|
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}`;
|
|
102
107
|
|
|
103
108
|
stopContextTimer({
|
|
104
109
|
systemPromptSize: fullSystem.length,
|
|
105
|
-
injectionSize: injection?.length ?? 0,
|
|
110
|
+
injectionSize: injection?.length ?? forensicsInjection?.length ?? 0,
|
|
106
111
|
hasPreferences: preferenceBlock.length > 0,
|
|
107
112
|
hasNewSkills: newSkillsBlock.length > 0,
|
|
108
113
|
});
|
|
109
114
|
|
|
115
|
+
// Determine which context message to inject (guided execute takes priority)
|
|
116
|
+
const contextMessage = injection
|
|
117
|
+
? { customType: "gsd-guided-context", content: injection, display: false as const }
|
|
118
|
+
: forensicsInjection
|
|
119
|
+
? { customType: "gsd-forensics", content: forensicsInjection, display: false as const }
|
|
120
|
+
: null;
|
|
121
|
+
|
|
110
122
|
return {
|
|
111
123
|
systemPrompt: fullSystem,
|
|
112
|
-
...(
|
|
113
|
-
? {
|
|
114
|
-
message: {
|
|
115
|
-
customType: "gsd-guided-context",
|
|
116
|
-
content: injection,
|
|
117
|
-
display: false as const,
|
|
118
|
-
},
|
|
119
|
-
}
|
|
120
|
-
: {}),
|
|
124
|
+
...(contextMessage ? { message: contextMessage } : {}),
|
|
121
125
|
};
|
|
122
126
|
}
|
|
123
127
|
|
|
@@ -375,3 +379,38 @@ function oneLine(text: string): string {
|
|
|
375
379
|
return text.replace(/\s+/g, " ").trim();
|
|
376
380
|
}
|
|
377
381
|
|
|
382
|
+
// ─── Forensics Context Re-injection (#2941) ──────────────────────────────────
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Check for an active forensics session and return the prompt content
|
|
386
|
+
* so it can be re-injected on follow-up turns.
|
|
387
|
+
*/
|
|
388
|
+
function buildForensicsContextInjection(basePath: string): string | null {
|
|
389
|
+
const marker = readForensicsMarker(basePath);
|
|
390
|
+
if (!marker) return null;
|
|
391
|
+
|
|
392
|
+
// Expire markers older than 2 hours to avoid stale context
|
|
393
|
+
const age = Date.now() - new Date(marker.createdAt).getTime();
|
|
394
|
+
if (age > 2 * 60 * 60 * 1000) {
|
|
395
|
+
clearForensicsMarker(basePath);
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return marker.promptContent;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Remove the active forensics marker file, e.g. when the investigation
|
|
404
|
+
* is complete or the session expires.
|
|
405
|
+
*/
|
|
406
|
+
export function clearForensicsMarker(basePath: string): void {
|
|
407
|
+
const markerPath = join(basePath, ".gsd", "runtime", "active-forensics.json");
|
|
408
|
+
if (existsSync(markerPath)) {
|
|
409
|
+
try {
|
|
410
|
+
unlinkSync(markerPath);
|
|
411
|
+
} catch {
|
|
412
|
+
// non-fatal
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
const MILESTONE_CONTEXT_RE = /M\d+(?:-[a-z0-9]{6})?-CONTEXT\.md$/;
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Path segment that identifies .gsd/ planning artifacts.
|
|
5
|
+
* Writes to these paths are allowed during queue mode.
|
|
6
|
+
*/
|
|
7
|
+
const GSD_DIR_RE = /(^|[/\\])\.gsd([/\\]|$)/;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Read-only tool names that are always safe during queue mode.
|
|
11
|
+
*/
|
|
12
|
+
const QUEUE_SAFE_TOOLS = new Set([
|
|
13
|
+
"read", "grep", "find", "ls", "glob",
|
|
14
|
+
// Discussion & planning tools
|
|
15
|
+
"ask_user_questions",
|
|
16
|
+
"gsd_milestone_generate_id",
|
|
17
|
+
"gsd_summary_save",
|
|
18
|
+
// Web research tools used during queue discussion
|
|
19
|
+
"search-the-web", "resolve_library", "get_library_docs", "fetch_page",
|
|
20
|
+
"search_and_read",
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Bash commands that are read-only / investigative — safe during queue mode.
|
|
25
|
+
* Matches the leading command in a bash invocation.
|
|
26
|
+
*/
|
|
27
|
+
const BASH_READ_ONLY_RE = /^\s*(cat|head|tail|less|more|wc|file|stat|du|df|which|type|echo|printf|ls|find|grep|rg|awk|sed\b(?!.*-i)|sort|uniq|diff|comm|tr|cut|tee\s+-a\s+\/dev\/null|git\s+(log|show|diff|status|branch|tag|remote|rev-parse|ls-files|blame|shortlog|describe|stash\s+list|config\s+--get|cat-file)|gh\s+(issue|pr|api|repo|release)\s+(view|list|diff|status|checks)|mkdir\s+-p\s+\.gsd|rtk\s)/;
|
|
28
|
+
|
|
3
29
|
let depthVerificationDone = false;
|
|
4
30
|
let activeQueuePhase = false;
|
|
5
31
|
|
|
@@ -49,3 +75,52 @@ export function shouldBlockContextWrite(
|
|
|
49
75
|
};
|
|
50
76
|
}
|
|
51
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Queue-mode execution guard (#2545).
|
|
80
|
+
*
|
|
81
|
+
* When the queue phase is active, the agent should only create planning
|
|
82
|
+
* artifacts (milestones, CONTEXT.md, QUEUE.md, etc.) — never execute work.
|
|
83
|
+
* This function blocks write/edit/bash tool calls that would modify source
|
|
84
|
+
* code outside of .gsd/.
|
|
85
|
+
*
|
|
86
|
+
* @param toolName The tool being called (write, edit, bash, etc.)
|
|
87
|
+
* @param input For write/edit: the file path. For bash: the command string.
|
|
88
|
+
* @param queuePhaseActive Whether the queue phase is currently active.
|
|
89
|
+
* @returns { block, reason } — block=true if the call should be rejected.
|
|
90
|
+
*/
|
|
91
|
+
export function shouldBlockQueueExecution(
|
|
92
|
+
toolName: string,
|
|
93
|
+
input: string,
|
|
94
|
+
queuePhaseActive: boolean,
|
|
95
|
+
): { block: boolean; reason?: string } {
|
|
96
|
+
if (!queuePhaseActive) return { block: false };
|
|
97
|
+
|
|
98
|
+
// Always-safe tools (read-only, discussion, planning)
|
|
99
|
+
if (QUEUE_SAFE_TOOLS.has(toolName)) return { block: false };
|
|
100
|
+
|
|
101
|
+
// write/edit — allow if targeting .gsd/ planning artifacts
|
|
102
|
+
if (toolName === "write" || toolName === "edit") {
|
|
103
|
+
if (GSD_DIR_RE.test(input)) return { block: false };
|
|
104
|
+
return {
|
|
105
|
+
block: true,
|
|
106
|
+
reason: `Blocked: /gsd queue is a planning tool — it creates milestones, not executes work. ` +
|
|
107
|
+
`Cannot ${toolName} to "${input}" during queue mode. ` +
|
|
108
|
+
`Write CONTEXT.md files and update PROJECT.md/QUEUE.md instead.`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// bash — allow read-only/investigative commands, block everything else
|
|
113
|
+
if (toolName === "bash") {
|
|
114
|
+
if (BASH_READ_ONLY_RE.test(input)) return { block: false };
|
|
115
|
+
return {
|
|
116
|
+
block: true,
|
|
117
|
+
reason: `Blocked: /gsd queue is a planning tool — it creates milestones, not executes work. ` +
|
|
118
|
+
`Cannot run "${input.slice(0, 80)}${input.length > 80 ? "…" : ""}" during queue mode. ` +
|
|
119
|
+
`Use read-only commands (cat, grep, git log, etc.) to investigate, then write planning artifacts.`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Unknown tools — allow by default (custom extension tools, etc.)
|
|
124
|
+
return { block: false };
|
|
125
|
+
}
|
|
126
|
+
|
|
@@ -26,6 +26,7 @@ export interface CaptureEntry {
|
|
|
26
26
|
resolution?: string;
|
|
27
27
|
rationale?: string;
|
|
28
28
|
resolvedAt?: string;
|
|
29
|
+
resolvedInMilestone?: string;
|
|
29
30
|
executed?: boolean;
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -176,6 +177,7 @@ export function markCaptureResolved(
|
|
|
176
177
|
classification: Classification,
|
|
177
178
|
resolution: string,
|
|
178
179
|
rationale: string,
|
|
180
|
+
milestoneId?: string,
|
|
179
181
|
): void {
|
|
180
182
|
const filePath = resolveCapturesPath(basePath);
|
|
181
183
|
if (!existsSync(filePath)) return;
|
|
@@ -206,13 +208,17 @@ export function markCaptureResolved(
|
|
|
206
208
|
`**Rationale:** ${rationale}`,
|
|
207
209
|
`**Resolved:** ${resolvedAt}`,
|
|
208
210
|
];
|
|
211
|
+
if (milestoneId) {
|
|
212
|
+
newFields.push(`**Milestone:** ${milestoneId}`);
|
|
213
|
+
}
|
|
209
214
|
|
|
210
|
-
// Remove any existing classification/resolution/rationale/resolved fields
|
|
215
|
+
// Remove any existing classification/resolution/rationale/resolved/milestone fields
|
|
211
216
|
// (in case of re-triage)
|
|
212
217
|
section = section.replace(/\*\*Classification:\*\*\s*.+\n?/g, "");
|
|
213
218
|
section = section.replace(/\*\*Resolution:\*\*\s*.+\n?/g, "");
|
|
214
219
|
section = section.replace(/\*\*Rationale:\*\*\s*.+\n?/g, "");
|
|
215
220
|
section = section.replace(/\*\*Resolved:\*\*\s*.+\n?/g, "");
|
|
221
|
+
section = section.replace(/\*\*Milestone:\*\*\s*.+\n?/g, "");
|
|
216
222
|
|
|
217
223
|
// Add new fields after Status line
|
|
218
224
|
section = section.trimEnd() + "\n" + newFields.join("\n") + "\n";
|
|
@@ -255,16 +261,68 @@ export function markCaptureExecuted(basePath: string, captureId: string): void {
|
|
|
255
261
|
* Load resolved captures that have actionable classifications (inject, replan,
|
|
256
262
|
* quick-task) but have NOT yet been executed.
|
|
257
263
|
* These are captures whose resolutions need to be carried out.
|
|
264
|
+
*
|
|
265
|
+
* When `currentMilestoneId` is provided, captures resolved in a *different*
|
|
266
|
+
* milestone are treated as stale and excluded. This prevents quick-task
|
|
267
|
+
* captures from a prior milestone re-executing after the underlying issues
|
|
268
|
+
* were already fixed by planned milestone work (#2872).
|
|
269
|
+
*
|
|
270
|
+
* Captures that have no `resolvedInMilestone` (legacy captures resolved before
|
|
271
|
+
* this field was introduced) are always included for backward compatibility.
|
|
258
272
|
*/
|
|
259
|
-
export function loadActionableCaptures(basePath: string): CaptureEntry[] {
|
|
273
|
+
export function loadActionableCaptures(basePath: string, currentMilestoneId?: string): CaptureEntry[] {
|
|
260
274
|
return loadAllCaptures(basePath).filter(
|
|
261
275
|
c =>
|
|
262
276
|
c.status === "resolved" &&
|
|
263
277
|
!c.executed &&
|
|
264
278
|
(c.classification === "inject" ||
|
|
265
279
|
c.classification === "replan" ||
|
|
266
|
-
c.classification === "quick-task")
|
|
280
|
+
c.classification === "quick-task") &&
|
|
281
|
+
// Staleness gate: exclude captures resolved in a different milestone (#2872)
|
|
282
|
+
(!currentMilestoneId ||
|
|
283
|
+
!c.resolvedInMilestone ||
|
|
284
|
+
c.resolvedInMilestone === currentMilestoneId),
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Retroactively stamp a capture with a milestone ID.
|
|
290
|
+
*
|
|
291
|
+
* Used by executeTriageResolutions() as a safety net when the triage LLM
|
|
292
|
+
* resolves a capture without writing the **Milestone:** field. This ensures
|
|
293
|
+
* the staleness gate in loadActionableCaptures() works correctly even for
|
|
294
|
+
* captures resolved before the prompt was updated (#2872).
|
|
295
|
+
*/
|
|
296
|
+
export function stampCaptureMilestone(basePath: string, captureId: string, milestoneId: string): void {
|
|
297
|
+
const filePath = resolveCapturesPath(basePath);
|
|
298
|
+
if (!existsSync(filePath)) return;
|
|
299
|
+
|
|
300
|
+
const content = readFileSync(filePath, "utf-8");
|
|
301
|
+
|
|
302
|
+
const sectionRegex = new RegExp(
|
|
303
|
+
`(### ${escapeRegex(captureId)}\\n(?:(?!### ).)*?)(?=### |$)`,
|
|
304
|
+
"s",
|
|
267
305
|
);
|
|
306
|
+
const match = sectionRegex.exec(content);
|
|
307
|
+
if (!match) return;
|
|
308
|
+
|
|
309
|
+
let section = match[1];
|
|
310
|
+
|
|
311
|
+
// Only stamp if not already present
|
|
312
|
+
if (/\*\*Milestone:\*\*/.test(section)) return;
|
|
313
|
+
|
|
314
|
+
// Insert after the Resolved field (or at end of section)
|
|
315
|
+
const resolvedFieldEnd = section.search(/\*\*Resolved:\*\*\s*.+\n?/);
|
|
316
|
+
if (resolvedFieldEnd !== -1) {
|
|
317
|
+
const resolvedMatch = section.match(/\*\*Resolved:\*\*\s*.+\n?/);
|
|
318
|
+
const insertPos = resolvedFieldEnd + (resolvedMatch?.[0]?.length ?? 0);
|
|
319
|
+
section = section.slice(0, insertPos) + `**Milestone:** ${milestoneId}\n` + section.slice(insertPos);
|
|
320
|
+
} else {
|
|
321
|
+
section = section.trimEnd() + "\n" + `**Milestone:** ${milestoneId}` + "\n";
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const updated = content.replace(sectionRegex, section);
|
|
325
|
+
writeFileSync(filePath, updated, "utf-8");
|
|
268
326
|
}
|
|
269
327
|
|
|
270
328
|
// ─── Parser ───────────────────────────────────────────────────────────────────
|
|
@@ -291,6 +349,7 @@ function parseCapturesContent(content: string): CaptureEntry[] {
|
|
|
291
349
|
const resolution = extractBoldField(body, "Resolution");
|
|
292
350
|
const rationale = extractBoldField(body, "Rationale");
|
|
293
351
|
const resolvedAt = extractBoldField(body, "Resolved");
|
|
352
|
+
const milestoneId = extractBoldField(body, "Milestone");
|
|
294
353
|
const executedAt = extractBoldField(body, "Executed");
|
|
295
354
|
|
|
296
355
|
if (!text || !timestamp) continue;
|
|
@@ -308,6 +367,7 @@ function parseCapturesContent(content: string): CaptureEntry[] {
|
|
|
308
367
|
...(resolution ? { resolution } : {}),
|
|
309
368
|
...(rationale ? { rationale } : {}),
|
|
310
369
|
...(resolvedAt ? { resolvedAt } : {}),
|
|
370
|
+
...(milestoneId ? { resolvedInMilestone: milestoneId } : {}),
|
|
311
371
|
...(executedAt ? { executed: true } : {}),
|
|
312
372
|
});
|
|
313
373
|
}
|
|
@@ -227,6 +227,122 @@ export async function nextDecisionId(): Promise<string> {
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
// ─── Next Requirement ID ─────────────────────────────────────────────────
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Compute the next requirement ID from the current DB state.
|
|
234
|
+
* Queries MAX(CAST(SUBSTR(id, 2) AS INTEGER)) from requirements table.
|
|
235
|
+
* Returns R001 if no requirements exist. Zero-pads to 3 digits.
|
|
236
|
+
*/
|
|
237
|
+
export async function nextRequirementId(): Promise<string> {
|
|
238
|
+
try {
|
|
239
|
+
const db = await import('./gsd-db.js');
|
|
240
|
+
const adapter = db._getAdapter();
|
|
241
|
+
if (!adapter) return 'R001';
|
|
242
|
+
|
|
243
|
+
const row = adapter
|
|
244
|
+
.prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM requirements')
|
|
245
|
+
.get();
|
|
246
|
+
|
|
247
|
+
const maxNum = row ? (row['max_num'] as number | null) : null;
|
|
248
|
+
if (maxNum == null || isNaN(maxNum)) return 'R001';
|
|
249
|
+
|
|
250
|
+
const next = maxNum + 1;
|
|
251
|
+
return `R${String(next).padStart(3, '0')}`;
|
|
252
|
+
} catch (err) {
|
|
253
|
+
logError('manifest', 'nextRequirementId failed', { fn: 'nextRequirementId', error: String((err as Error).message) });
|
|
254
|
+
return 'R001';
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ─── Save Requirement to DB + Regenerate Markdown ────────────────────────
|
|
259
|
+
|
|
260
|
+
export interface SaveRequirementFields {
|
|
261
|
+
class: string;
|
|
262
|
+
status?: string;
|
|
263
|
+
description: string;
|
|
264
|
+
why: string;
|
|
265
|
+
source: string;
|
|
266
|
+
primary_owner?: string;
|
|
267
|
+
supporting_slices?: string;
|
|
268
|
+
validation?: string;
|
|
269
|
+
notes?: string;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Save a new requirement to DB and regenerate REQUIREMENTS.md.
|
|
274
|
+
* Auto-assigns the next ID via nextRequirementId().
|
|
275
|
+
* Returns the assigned ID.
|
|
276
|
+
*/
|
|
277
|
+
export async function saveRequirementToDb(
|
|
278
|
+
fields: SaveRequirementFields,
|
|
279
|
+
basePath: string,
|
|
280
|
+
): Promise<{ id: string }> {
|
|
281
|
+
try {
|
|
282
|
+
const db = await import('./gsd-db.js');
|
|
283
|
+
|
|
284
|
+
const id = await nextRequirementId();
|
|
285
|
+
|
|
286
|
+
const requirement: Requirement = {
|
|
287
|
+
id,
|
|
288
|
+
class: fields.class,
|
|
289
|
+
status: fields.status ?? 'active',
|
|
290
|
+
description: fields.description,
|
|
291
|
+
why: fields.why,
|
|
292
|
+
source: fields.source,
|
|
293
|
+
primary_owner: fields.primary_owner ?? '',
|
|
294
|
+
supporting_slices: fields.supporting_slices ?? '',
|
|
295
|
+
validation: fields.validation ?? '',
|
|
296
|
+
notes: fields.notes ?? '',
|
|
297
|
+
full_content: '',
|
|
298
|
+
superseded_by: null,
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
db.upsertRequirement(requirement);
|
|
302
|
+
|
|
303
|
+
// Fetch all requirements for full file regeneration
|
|
304
|
+
const adapter = db._getAdapter();
|
|
305
|
+
let allRequirements: Requirement[] = [];
|
|
306
|
+
if (adapter) {
|
|
307
|
+
const rows = adapter.prepare('SELECT * FROM requirements ORDER BY id').all();
|
|
308
|
+
allRequirements = rows.map(row => ({
|
|
309
|
+
id: row['id'] as string,
|
|
310
|
+
class: row['class'] as string,
|
|
311
|
+
status: row['status'] as string,
|
|
312
|
+
description: row['description'] as string,
|
|
313
|
+
why: row['why'] as string,
|
|
314
|
+
source: row['source'] as string,
|
|
315
|
+
primary_owner: row['primary_owner'] as string,
|
|
316
|
+
supporting_slices: row['supporting_slices'] as string,
|
|
317
|
+
validation: row['validation'] as string,
|
|
318
|
+
notes: row['notes'] as string,
|
|
319
|
+
full_content: row['full_content'] as string,
|
|
320
|
+
superseded_by: (row['superseded_by'] as string) ?? null,
|
|
321
|
+
}));
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const nonSuperseded = allRequirements.filter(r => r.superseded_by == null);
|
|
325
|
+
const md = generateRequirementsMd(nonSuperseded);
|
|
326
|
+
const filePath = resolveGsdRootFile(basePath, 'REQUIREMENTS');
|
|
327
|
+
try {
|
|
328
|
+
await saveFile(filePath, md);
|
|
329
|
+
} catch (diskErr) {
|
|
330
|
+
logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveRequirementToDb', error: String((diskErr as Error).message) });
|
|
331
|
+
const rollbackAdapter = db._getAdapter();
|
|
332
|
+
rollbackAdapter?.prepare('DELETE FROM requirements WHERE id = :id').run({ ':id': id });
|
|
333
|
+
throw diskErr;
|
|
334
|
+
}
|
|
335
|
+
invalidateStateCache();
|
|
336
|
+
clearPathCache();
|
|
337
|
+
clearParseCache();
|
|
338
|
+
|
|
339
|
+
return { id };
|
|
340
|
+
} catch (err) {
|
|
341
|
+
logError('manifest', 'saveRequirementToDb failed', { fn: 'saveRequirementToDb', error: String((err as Error).message) });
|
|
342
|
+
throw err;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
230
346
|
// ─── Save Decision to DB + Regenerate Markdown ────────────────────────────
|
|
231
347
|
|
|
232
348
|
export interface SaveDecisionFields {
|
|
@@ -344,15 +460,30 @@ export async function updateRequirementInDb(
|
|
|
344
460
|
const db = await import('./gsd-db.js');
|
|
345
461
|
|
|
346
462
|
const existing = db.getRequirementById(id);
|
|
347
|
-
if (!existing) {
|
|
348
|
-
throw new GSDError(GSD_STALE_STATE, `Requirement ${id} not found`);
|
|
349
|
-
}
|
|
350
463
|
|
|
351
|
-
//
|
|
464
|
+
// If requirement doesn't exist in DB, create a skeleton and merge updates.
|
|
465
|
+
// This handles the case where requirements were written to REQUIREMENTS.md
|
|
466
|
+
// but never imported into the database (see #2919).
|
|
467
|
+
const base: Requirement = existing ?? {
|
|
468
|
+
id,
|
|
469
|
+
class: '',
|
|
470
|
+
status: 'active',
|
|
471
|
+
description: '',
|
|
472
|
+
why: '',
|
|
473
|
+
source: '',
|
|
474
|
+
primary_owner: '',
|
|
475
|
+
supporting_slices: '',
|
|
476
|
+
validation: '',
|
|
477
|
+
notes: '',
|
|
478
|
+
full_content: '',
|
|
479
|
+
superseded_by: null,
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
// Merge updates into existing (or skeleton)
|
|
352
483
|
const merged: Requirement = {
|
|
353
|
-
...
|
|
484
|
+
...base,
|
|
354
485
|
...updates,
|
|
355
|
-
id:
|
|
486
|
+
id: base.id, // ID cannot be changed
|
|
356
487
|
};
|
|
357
488
|
|
|
358
489
|
db.upsertRequirement(merged);
|
|
@@ -388,7 +519,9 @@ export async function updateRequirementInDb(
|
|
|
388
519
|
await saveFile(filePath, md);
|
|
389
520
|
} catch (diskErr) {
|
|
390
521
|
logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String((diskErr as Error).message) });
|
|
391
|
-
|
|
522
|
+
if (existing) {
|
|
523
|
+
db.upsertRequirement(existing);
|
|
524
|
+
}
|
|
392
525
|
throw diskErr;
|
|
393
526
|
}
|
|
394
527
|
// Invalidate file-read caches so deriveState() sees the updated markdown.
|
|
@@ -26,9 +26,20 @@ export function getPriorSliceCompletionBlocker(
|
|
|
26
26
|
const { milestone: targetMid, slice: targetSid } = parseUnitId(unitId);
|
|
27
27
|
if (!targetMid || !targetSid) return null;
|
|
28
28
|
|
|
29
|
+
// Parallel worker isolation: when GSD_MILESTONE_LOCK is set, this worker
|
|
30
|
+
// is scoped to a single milestone. Skip the cross-milestone dependency
|
|
31
|
+
// check — other milestones are being handled by their own workers.
|
|
32
|
+
// Without this, the dispatch guard sees incomplete slices in M010/M011
|
|
33
|
+
// (cloned into the worktree DB) and blocks M012 from ever starting. #2797
|
|
34
|
+
const milestoneLock = process.env.GSD_MILESTONE_LOCK;
|
|
35
|
+
|
|
29
36
|
// Use findMilestoneIds to respect custom queue order.
|
|
30
37
|
// Only check milestones that come BEFORE the target in queue order.
|
|
31
|
-
|
|
38
|
+
// When locked to a specific milestone, only check that milestone's
|
|
39
|
+
// intra-slice dependencies — skip all cross-milestone checks.
|
|
40
|
+
const allIds = milestoneLock && targetMid === milestoneLock
|
|
41
|
+
? [targetMid]
|
|
42
|
+
: findMilestoneIds(base);
|
|
32
43
|
const targetIdx = allIds.indexOf(targetMid);
|
|
33
44
|
if (targetIdx < 0) return null;
|
|
34
45
|
const milestoneIds = allIds.slice(0, targetIdx + 1);
|
|
@@ -14,6 +14,28 @@ import { nativeIsRepo, nativeWorktreeList, nativeWorktreeRemove, nativeBranchLis
|
|
|
14
14
|
import { getAllWorktreeHealth } from "./worktree-health.js";
|
|
15
15
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Returns true if the directory contains only doctor artifacts
|
|
19
|
+
* (e.g. `.gsd/doctor-history.jsonl`). These dirs are created by
|
|
20
|
+
* appendDoctorHistory() writing to worktree-scoped paths during the audit
|
|
21
|
+
* and should not be flagged as orphaned worktrees (#3105).
|
|
22
|
+
*/
|
|
23
|
+
function isDoctorArtifactOnly(dirPath: string): boolean {
|
|
24
|
+
try {
|
|
25
|
+
const entries = readdirSync(dirPath);
|
|
26
|
+
// Empty dir — not a doctor artifact, still orphaned
|
|
27
|
+
if (entries.length === 0) return false;
|
|
28
|
+
// Only a .gsd subdirectory
|
|
29
|
+
if (entries.length === 1 && entries[0] === ".gsd") {
|
|
30
|
+
const gsdEntries = readdirSync(join(dirPath, ".gsd"));
|
|
31
|
+
return gsdEntries.length <= 1 && gsdEntries.every(e => e === "doctor-history.jsonl");
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
export async function checkGitHealth(
|
|
18
40
|
basePath: string,
|
|
19
41
|
issues: DoctorIssue[],
|
|
@@ -314,6 +336,10 @@ export async function checkGitHealth(
|
|
|
314
336
|
} catch { continue; }
|
|
315
337
|
const normalizedFullPath = normalizePath(fullPath);
|
|
316
338
|
if (!registeredPaths.has(normalizedFullPath)) {
|
|
339
|
+
// Skip directories that only contain doctor artifacts (.gsd/doctor-history.jsonl).
|
|
340
|
+
// appendDoctorHistory() can recreate these dirs during the audit itself,
|
|
341
|
+
// causing a circular false positive (#3105 Bug 1).
|
|
342
|
+
if (isDoctorArtifactOnly(fullPath)) continue;
|
|
317
343
|
issues.push({
|
|
318
344
|
severity: "warning",
|
|
319
345
|
code: "worktree_directory_orphaned",
|
|
@@ -181,7 +181,8 @@ function resolveKey(providerId: string): KeyLookup {
|
|
|
181
181
|
*/
|
|
182
182
|
const PROVIDER_ROUTES: Record<string, string[]> = {
|
|
183
183
|
anthropic: ["github-copilot"],
|
|
184
|
-
openai: ["github-copilot"],
|
|
184
|
+
openai: ["github-copilot", "openai-codex"],
|
|
185
|
+
google: ["google-gemini-cli"],
|
|
185
186
|
};
|
|
186
187
|
|
|
187
188
|
function checkLlmProviders(): ProviderCheckResult[] {
|
|
@@ -119,10 +119,11 @@ export async function checkRuntimeHealth(
|
|
|
119
119
|
|
|
120
120
|
for (const key of keys) {
|
|
121
121
|
// Key format: "unitType/unitId" e.g. "execute-task/M001/S01/T01"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
122
|
+
// Hook units have compound types: "hook/<hookName>/unitId"
|
|
123
|
+
const { splitCompletedKey } = await import("./forensics.js");
|
|
124
|
+
const parsed = splitCompletedKey(key);
|
|
125
|
+
if (!parsed) continue;
|
|
126
|
+
const { unitType, unitId } = parsed;
|
|
126
127
|
|
|
127
128
|
// Only validate artifact-producing unit types
|
|
128
129
|
const { verifyExpectedArtifact } = await import("./auto-recovery.js");
|
|
@@ -729,8 +729,10 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|
|
729
729
|
}
|
|
730
730
|
|
|
731
731
|
// Blocker-without-replan detection
|
|
732
|
+
// Skip when all tasks are done — the blocker was implicitly resolved
|
|
733
|
+
// within the task and the slice is not stuck (#3105 Bug 2).
|
|
732
734
|
const replanPath = resolveSliceFile(basePath, milestoneId, slice.id, "REPLAN");
|
|
733
|
-
if (!replanPath) {
|
|
735
|
+
if (!replanPath && !allTasksDone) {
|
|
734
736
|
for (const task of plan.tasks) {
|
|
735
737
|
if (!task.done) continue;
|
|
736
738
|
const summaryPath = resolveTaskFile(basePath, milestoneId, slice.id, task.id, "SUMMARY");
|
|
@@ -48,7 +48,7 @@ const NETWORK_RE = /network|ECONNRESET|ETIMEDOUT|ECONNREFUSED|socket hang up|fet
|
|
|
48
48
|
const SERVER_RE = /internal server error|500|502|503|overloaded|server_error|api_error|service.?unavailable/i;
|
|
49
49
|
// ECONNRESET/ECONNREFUSED are in NETWORK_RE (same-model retry first).
|
|
50
50
|
const CONNECTION_RE = /terminated|connection.?refused|other side closed|EPIPE|network.?(?:is\s+)?unavailable|stream_exhausted(?:_without_result)?/i;
|
|
51
|
-
const STREAM_RE = /Unexpected end of JSON|Unexpected token.*JSON|Expected
|
|
51
|
+
const STREAM_RE = /Unexpected end of JSON|Unexpected token.*JSON|Expected.*in JSON|Unterminated.*in JSON|SyntaxError.*JSON/i;
|
|
52
52
|
const RESET_DELAY_RE = /reset in (\d+)s/i;
|
|
53
53
|
|
|
54
54
|
/**
|
|
@@ -58,9 +58,9 @@ const RESET_DELAY_RE = /reset in (\d+)s/i;
|
|
|
58
58
|
* 1. Permanent (auth/billing/quota) — unless also rate-limited
|
|
59
59
|
* 2. Rate limit (429, rate.?limit, too many requests)
|
|
60
60
|
* 3. Network (ECONNRESET, ETIMEDOUT, socket hang up, fetch failed, dns)
|
|
61
|
-
* 4.
|
|
62
|
-
* 5.
|
|
63
|
-
* 6.
|
|
61
|
+
* 4. Stream truncation (malformed JSON from mid-stream cut)
|
|
62
|
+
* 5. Server (500/502/503, overloaded, server_error)
|
|
63
|
+
* 6. Connection (terminated, ECONNREFUSED, EPIPE, other side closed)
|
|
64
64
|
* 7. Unknown
|
|
65
65
|
*/
|
|
66
66
|
export function classifyError(errorMsg: string, retryAfterMs?: number): ErrorClass {
|
|
@@ -90,21 +90,24 @@ export function classifyError(errorMsg: string, retryAfterMs?: number): ErrorCla
|
|
|
90
90
|
return { kind: "network", retryAfterMs: retryAfterMs ?? 3_000 };
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
// 4.
|
|
93
|
+
// 4. Stream truncation — downstream symptom of connection drop
|
|
94
|
+
// Checked before server/connection because JSON parse errors can contain
|
|
95
|
+
// substrings like "position 500" (matches SERVER_RE) or "Unterminated"
|
|
96
|
+
// (matches CONNECTION_RE's "terminated" pattern).
|
|
97
|
+
if (STREAM_RE.test(errorMsg)) {
|
|
98
|
+
return { kind: "stream", retryAfterMs: retryAfterMs ?? 15_000 };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 5. Server errors — try fallback model
|
|
94
102
|
if (SERVER_RE.test(errorMsg)) {
|
|
95
103
|
return { kind: "server", retryAfterMs: retryAfterMs ?? 30_000 };
|
|
96
104
|
}
|
|
97
105
|
|
|
98
|
-
//
|
|
106
|
+
// 6. Connection errors — try fallback model
|
|
99
107
|
if (CONNECTION_RE.test(errorMsg)) {
|
|
100
108
|
return { kind: "connection", retryAfterMs: retryAfterMs ?? 15_000 };
|
|
101
109
|
}
|
|
102
110
|
|
|
103
|
-
// 6. Stream truncation — downstream symptom of connection drop
|
|
104
|
-
if (STREAM_RE.test(errorMsg)) {
|
|
105
|
-
return { kind: "stream", retryAfterMs: retryAfterMs ?? 15_000 };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
111
|
// 7. Unknown
|
|
109
112
|
return { kind: "unknown" };
|
|
110
113
|
}
|
|
@@ -12,7 +12,22 @@
|
|
|
12
12
|
"gsd_requirement_update", "gsd_milestone_generate_id"
|
|
13
13
|
],
|
|
14
14
|
"commands": ["gsd", "kill", "worktree", "exit"],
|
|
15
|
-
"hooks": [
|
|
15
|
+
"hooks": [
|
|
16
|
+
"session_start",
|
|
17
|
+
"session_switch",
|
|
18
|
+
"bash_transform",
|
|
19
|
+
"session_fork",
|
|
20
|
+
"before_agent_start",
|
|
21
|
+
"agent_end",
|
|
22
|
+
"session_before_compact",
|
|
23
|
+
"session_shutdown",
|
|
24
|
+
"tool_call",
|
|
25
|
+
"tool_result",
|
|
26
|
+
"tool_execution_start",
|
|
27
|
+
"tool_execution_end",
|
|
28
|
+
"model_select",
|
|
29
|
+
"before_provider_request"
|
|
30
|
+
],
|
|
16
31
|
"shortcuts": ["Ctrl+Alt+G"]
|
|
17
32
|
}
|
|
18
33
|
}
|