gsd-pi 2.58.0 → 2.59.0-dev.023bd39
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 +60 -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/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 +17 -2
- 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 +199 -12
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +42 -34
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +66 -12
- 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/codebase-generator.js +279 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-codebase.js +115 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +41 -4
- package/dist/resources/extensions/gsd/complexity-classifier.js +8 -6
- package/dist/resources/extensions/gsd/db-writer.js +116 -8
- package/dist/resources/extensions/gsd/doctor-git-checks.js +76 -1
- package/dist/resources/extensions/gsd/doctor-proactive.js +34 -1
- 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 +12 -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 +105 -2
- package/dist/resources/extensions/gsd/gitignore.js +33 -0
- package/dist/resources/extensions/gsd/gsd-db.js +36 -9
- 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 +39 -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/parsers-legacy.js +20 -3
- package/dist/resources/extensions/gsd/paths.js +45 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +3 -1
- package/dist/resources/extensions/gsd/preferences.js +13 -16
- 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/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 +14 -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/watch/header-renderer.js +241 -0
- 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/search-the-web/url-utils.js +17 -0
- package/dist/resources/extensions/shared/interview-ui.js +11 -1
- package/dist/resources/skills/btw/SKILL.md +42 -0
- 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/security-overrides.d.ts +11 -0
- package/dist/security-overrides.js +41 -0
- 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 +14 -14
- 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 +4 -4
- 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 +14 -14
- 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-61d3afac6d0f0ce7.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/dist/welcome-screen.d.ts +1 -0
- package/dist/welcome-screen.js +32 -6
- package/package.json +2 -2
- package/packages/daemon/src/daemon.ts +1 -1
- package/packages/daemon/src/discord-bot.ts +11 -0
- package/packages/daemon/src/event-bridge.ts +15 -9
- package/packages/daemon/src/event-formatter.ts +30 -2
- 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/resolve-config-value.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.js +23 -2
- package/packages/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +89 -2
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.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/settings-manager-security.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js +83 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +14 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +36 -3
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- 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 +3 -2
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +2 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js +9 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +0 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +26 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +46 -14
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.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 +19 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +22 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +122 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +57 -4
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.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/resolve-config-value.test.ts +111 -1
- package/packages/pi-coding-agent/src/core/resolve-config-value.ts +26 -2
- 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/settings-manager-security.test.ts +102 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +44 -3
- 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 +11 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/armin.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/bordered-loader.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/config-selector.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/countdown-timer.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/custom-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/daxnuts.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-selector.ts +4 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +27 -13
- package/packages/pi-coding-agent/src/modes/interactive/components/oauth-selector.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +45 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +8 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message-selector.ts +3 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +156 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +21 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +73 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
- 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/dist/modes/interactive/theme/themes.js +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- 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/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 +18 -2
- 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 +193 -9
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -35
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +72 -12
- 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/codebase-generator.ts +351 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-codebase.ts +164 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +46 -4
- package/src/resources/extensions/gsd/complexity-classifier.ts +8 -6
- package/src/resources/extensions/gsd/db-writer.ts +140 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +75 -1
- package/src/resources/extensions/gsd/doctor-proactive.ts +35 -1
- 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-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +13 -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 +119 -3
- package/src/resources/extensions/gsd/gitignore.ts +33 -0
- package/src/resources/extensions/gsd/gsd-db.ts +43 -7
- 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 +41 -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/parsers-legacy.ts +22 -3
- package/src/resources/extensions/gsd/paths.ts +44 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +10 -1
- package/src/resources/extensions/gsd/preferences.ts +13 -15
- 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/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 +29 -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/codebase-generator.test.ts +488 -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/complexity-classifier.test.ts +4 -4
- 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/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 +134 -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/doctor-git.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +68 -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/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/project-relocation-recovery.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -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/terminated-transient.test.ts +44 -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 +4 -1
- 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-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 +20 -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/watch/header-renderer.ts +275 -0
- 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/search-the-web/url-utils.ts +19 -0
- 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/btw/SKILL.md +42 -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.8b732f67a11b11b4.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/{IoheXIe-5DH7ieX8AUo8U → QlWL-8CXgQpzV3ehkNMzh}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{IoheXIe-5DH7ieX8AUo8U → QlWL-8CXgQpzV3ehkNMzh}/_ssgManifest.js +0 -0
|
@@ -11,7 +11,7 @@ import { resolve } from 'node:path';
|
|
|
11
11
|
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
12
12
|
import { resolveGsdRootFile } from './paths.js';
|
|
13
13
|
import { saveFile } from './files.js';
|
|
14
|
-
import { GSDError,
|
|
14
|
+
import { GSDError, GSD_IO_ERROR } from './errors.js';
|
|
15
15
|
import { logWarning, logError } from './workflow-logger.js';
|
|
16
16
|
import { invalidateStateCache } from './state.js';
|
|
17
17
|
import { clearPathCache } from './paths.js';
|
|
@@ -205,6 +205,98 @@ export async function nextDecisionId() {
|
|
|
205
205
|
return 'D001';
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
+
// ─── Next Requirement ID ─────────────────────────────────────────────────
|
|
209
|
+
/**
|
|
210
|
+
* Compute the next requirement ID from the current DB state.
|
|
211
|
+
* Queries MAX(CAST(SUBSTR(id, 2) AS INTEGER)) from requirements table.
|
|
212
|
+
* Returns R001 if no requirements exist. Zero-pads to 3 digits.
|
|
213
|
+
*/
|
|
214
|
+
export async function nextRequirementId() {
|
|
215
|
+
try {
|
|
216
|
+
const db = await import('./gsd-db.js');
|
|
217
|
+
const adapter = db._getAdapter();
|
|
218
|
+
if (!adapter)
|
|
219
|
+
return 'R001';
|
|
220
|
+
const row = adapter
|
|
221
|
+
.prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM requirements')
|
|
222
|
+
.get();
|
|
223
|
+
const maxNum = row ? row['max_num'] : null;
|
|
224
|
+
if (maxNum == null || isNaN(maxNum))
|
|
225
|
+
return 'R001';
|
|
226
|
+
const next = maxNum + 1;
|
|
227
|
+
return `R${String(next).padStart(3, '0')}`;
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
logError('manifest', 'nextRequirementId failed', { fn: 'nextRequirementId', error: String(err.message) });
|
|
231
|
+
return 'R001';
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Save a new requirement to DB and regenerate REQUIREMENTS.md.
|
|
236
|
+
* Auto-assigns the next ID via nextRequirementId().
|
|
237
|
+
* Returns the assigned ID.
|
|
238
|
+
*/
|
|
239
|
+
export async function saveRequirementToDb(fields, basePath) {
|
|
240
|
+
try {
|
|
241
|
+
const db = await import('./gsd-db.js');
|
|
242
|
+
const id = await nextRequirementId();
|
|
243
|
+
const requirement = {
|
|
244
|
+
id,
|
|
245
|
+
class: fields.class,
|
|
246
|
+
status: fields.status ?? 'active',
|
|
247
|
+
description: fields.description,
|
|
248
|
+
why: fields.why,
|
|
249
|
+
source: fields.source,
|
|
250
|
+
primary_owner: fields.primary_owner ?? '',
|
|
251
|
+
supporting_slices: fields.supporting_slices ?? '',
|
|
252
|
+
validation: fields.validation ?? '',
|
|
253
|
+
notes: fields.notes ?? '',
|
|
254
|
+
full_content: '',
|
|
255
|
+
superseded_by: null,
|
|
256
|
+
};
|
|
257
|
+
db.upsertRequirement(requirement);
|
|
258
|
+
// Fetch all requirements for full file regeneration
|
|
259
|
+
const adapter = db._getAdapter();
|
|
260
|
+
let allRequirements = [];
|
|
261
|
+
if (adapter) {
|
|
262
|
+
const rows = adapter.prepare('SELECT * FROM requirements ORDER BY id').all();
|
|
263
|
+
allRequirements = rows.map(row => ({
|
|
264
|
+
id: row['id'],
|
|
265
|
+
class: row['class'],
|
|
266
|
+
status: row['status'],
|
|
267
|
+
description: row['description'],
|
|
268
|
+
why: row['why'],
|
|
269
|
+
source: row['source'],
|
|
270
|
+
primary_owner: row['primary_owner'],
|
|
271
|
+
supporting_slices: row['supporting_slices'],
|
|
272
|
+
validation: row['validation'],
|
|
273
|
+
notes: row['notes'],
|
|
274
|
+
full_content: row['full_content'],
|
|
275
|
+
superseded_by: row['superseded_by'] ?? null,
|
|
276
|
+
}));
|
|
277
|
+
}
|
|
278
|
+
const nonSuperseded = allRequirements.filter(r => r.superseded_by == null);
|
|
279
|
+
const md = generateRequirementsMd(nonSuperseded);
|
|
280
|
+
const filePath = resolveGsdRootFile(basePath, 'REQUIREMENTS');
|
|
281
|
+
try {
|
|
282
|
+
await saveFile(filePath, md);
|
|
283
|
+
}
|
|
284
|
+
catch (diskErr) {
|
|
285
|
+
logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveRequirementToDb', error: String(diskErr.message) });
|
|
286
|
+
const rollbackAdapter = db._getAdapter();
|
|
287
|
+
rollbackAdapter?.prepare('DELETE FROM requirements WHERE id = :id').run({ ':id': id });
|
|
288
|
+
throw diskErr;
|
|
289
|
+
}
|
|
290
|
+
invalidateStateCache();
|
|
291
|
+
clearPathCache();
|
|
292
|
+
clearParseCache();
|
|
293
|
+
return { id };
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
logError('manifest', 'saveRequirementToDb failed', { fn: 'saveRequirementToDb', error: String(err.message) });
|
|
297
|
+
throw err;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
208
300
|
/**
|
|
209
301
|
* Save a new decision to DB and regenerate DECISIONS.md.
|
|
210
302
|
* Auto-assigns the next ID via nextDecisionId().
|
|
@@ -295,14 +387,28 @@ export async function updateRequirementInDb(id, updates, basePath) {
|
|
|
295
387
|
try {
|
|
296
388
|
const db = await import('./gsd-db.js');
|
|
297
389
|
const existing = db.getRequirementById(id);
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
390
|
+
// If requirement doesn't exist in DB, create a skeleton and merge updates.
|
|
391
|
+
// This handles the case where requirements were written to REQUIREMENTS.md
|
|
392
|
+
// but never imported into the database (see #2919).
|
|
393
|
+
const base = existing ?? {
|
|
394
|
+
id,
|
|
395
|
+
class: '',
|
|
396
|
+
status: 'active',
|
|
397
|
+
description: '',
|
|
398
|
+
why: '',
|
|
399
|
+
source: '',
|
|
400
|
+
primary_owner: '',
|
|
401
|
+
supporting_slices: '',
|
|
402
|
+
validation: '',
|
|
403
|
+
notes: '',
|
|
404
|
+
full_content: '',
|
|
405
|
+
superseded_by: null,
|
|
406
|
+
};
|
|
407
|
+
// Merge updates into existing (or skeleton)
|
|
302
408
|
const merged = {
|
|
303
|
-
...
|
|
409
|
+
...base,
|
|
304
410
|
...updates,
|
|
305
|
-
id:
|
|
411
|
+
id: base.id, // ID cannot be changed
|
|
306
412
|
};
|
|
307
413
|
db.upsertRequirement(merged);
|
|
308
414
|
// Fetch ALL requirements (including superseded) for full file regeneration
|
|
@@ -335,7 +441,9 @@ export async function updateRequirementInDb(id, updates, basePath) {
|
|
|
335
441
|
}
|
|
336
442
|
catch (diskErr) {
|
|
337
443
|
logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String(diskErr.message) });
|
|
338
|
-
|
|
444
|
+
if (existing) {
|
|
445
|
+
db.upsertRequirement(existing);
|
|
446
|
+
}
|
|
339
447
|
throw diskErr;
|
|
340
448
|
}
|
|
341
449
|
// Invalidate file-read caches so deriveState() sees the updated markdown.
|
|
@@ -8,9 +8,32 @@ import { deriveState, isMilestoneComplete } from "./state.js";
|
|
|
8
8
|
import { listWorktrees, resolveGitDir, worktreesDir } from "./worktree-manager.js";
|
|
9
9
|
import { abortAndReset } from "./git-self-heal.js";
|
|
10
10
|
import { RUNTIME_EXCLUSION_PATHS, resolveMilestoneIntegrationBranch, writeIntegrationBranch } from "./git-service.js";
|
|
11
|
-
import { nativeIsRepo, nativeWorktreeList, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached } from "./native-git-bridge.js";
|
|
11
|
+
import { nativeIsRepo, nativeWorktreeList, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached, nativeHasChanges, nativeLastCommitEpoch, nativeGetCurrentBranch, nativeAddTracked, nativeCommit } from "./native-git-bridge.js";
|
|
12
12
|
import { getAllWorktreeHealth } from "./worktree-health.js";
|
|
13
13
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
14
|
+
/**
|
|
15
|
+
* Returns true if the directory contains only doctor artifacts
|
|
16
|
+
* (e.g. `.gsd/doctor-history.jsonl`). These dirs are created by
|
|
17
|
+
* appendDoctorHistory() writing to worktree-scoped paths during the audit
|
|
18
|
+
* and should not be flagged as orphaned worktrees (#3105).
|
|
19
|
+
*/
|
|
20
|
+
function isDoctorArtifactOnly(dirPath) {
|
|
21
|
+
try {
|
|
22
|
+
const entries = readdirSync(dirPath);
|
|
23
|
+
// Empty dir — not a doctor artifact, still orphaned
|
|
24
|
+
if (entries.length === 0)
|
|
25
|
+
return false;
|
|
26
|
+
// Only a .gsd subdirectory
|
|
27
|
+
if (entries.length === 1 && entries[0] === ".gsd") {
|
|
28
|
+
const gsdEntries = readdirSync(join(dirPath, ".gsd"));
|
|
29
|
+
return gsdEntries.length <= 1 && gsdEntries.every(e => e === "doctor-history.jsonl");
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
14
37
|
export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode = "none") {
|
|
15
38
|
// Degrade gracefully if not a git repo
|
|
16
39
|
if (!nativeIsRepo(basePath)) {
|
|
@@ -307,6 +330,11 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
|
|
|
307
330
|
}
|
|
308
331
|
const normalizedFullPath = normalizePath(fullPath);
|
|
309
332
|
if (!registeredPaths.has(normalizedFullPath)) {
|
|
333
|
+
// Skip directories that only contain doctor artifacts (.gsd/doctor-history.jsonl).
|
|
334
|
+
// appendDoctorHistory() can recreate these dirs during the audit itself,
|
|
335
|
+
// causing a circular false positive (#3105 Bug 1).
|
|
336
|
+
if (isDoctorArtifactOnly(fullPath))
|
|
337
|
+
continue;
|
|
310
338
|
issues.push({
|
|
311
339
|
severity: "warning",
|
|
312
340
|
code: "worktree_directory_orphaned",
|
|
@@ -331,6 +359,53 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
|
|
|
331
359
|
catch {
|
|
332
360
|
// Non-fatal — orphaned worktree directory check failed
|
|
333
361
|
}
|
|
362
|
+
// ── Stale uncommitted changes ────────────────────────────────────────────
|
|
363
|
+
// If the working tree has uncommitted changes and the last commit was
|
|
364
|
+
// longer ago than the configured threshold, flag it and optionally
|
|
365
|
+
// auto-commit a safety snapshot so work isn't lost.
|
|
366
|
+
try {
|
|
367
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences ?? {};
|
|
368
|
+
const thresholdMinutes = prefs.stale_commit_threshold_minutes ?? 30;
|
|
369
|
+
if (thresholdMinutes > 0) {
|
|
370
|
+
const dirty = nativeHasChanges(basePath);
|
|
371
|
+
if (dirty) {
|
|
372
|
+
const branch = nativeGetCurrentBranch(basePath);
|
|
373
|
+
const lastEpoch = nativeLastCommitEpoch(basePath, branch || "HEAD");
|
|
374
|
+
const nowEpoch = Math.floor(Date.now() / 1000);
|
|
375
|
+
const minutesSinceCommit = lastEpoch > 0 ? (nowEpoch - lastEpoch) / 60 : Infinity;
|
|
376
|
+
if (minutesSinceCommit >= thresholdMinutes) {
|
|
377
|
+
const mins = Math.floor(minutesSinceCommit);
|
|
378
|
+
issues.push({
|
|
379
|
+
severity: "warning",
|
|
380
|
+
code: "stale_uncommitted_changes",
|
|
381
|
+
scope: "project",
|
|
382
|
+
unitId: "project",
|
|
383
|
+
message: `Uncommitted changes detected with no commit in ${mins} minute${mins === 1 ? "" : "s"} (threshold: ${thresholdMinutes}m). Snapshotting tracked files.`,
|
|
384
|
+
fixable: true,
|
|
385
|
+
});
|
|
386
|
+
if (shouldFix("stale_uncommitted_changes")) {
|
|
387
|
+
try {
|
|
388
|
+
nativeAddTracked(basePath);
|
|
389
|
+
const commitMsg = `gsd snapshot: uncommitted changes after ${mins}m inactivity`;
|
|
390
|
+
const result = nativeCommit(basePath, commitMsg);
|
|
391
|
+
if (result) {
|
|
392
|
+
fixesApplied.push(`created gsd snapshot after ${mins}m of uncommitted changes`);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
fixesApplied.push("gsd snapshot skipped — nothing to commit after staging tracked files");
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
fixesApplied.push("failed to create gsd snapshot commit");
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
// Non-fatal — stale commit check failed
|
|
408
|
+
}
|
|
334
409
|
// ── Worktree lifecycle checks ──────────────────────────────────────────
|
|
335
410
|
// Check GSD-managed worktrees for: merged branches, stale work, dirty
|
|
336
411
|
// state, and unpushed commits. Only worktrees under .gsd/worktrees/.
|
|
@@ -21,7 +21,7 @@ import { abortAndReset } from "./git-self-heal.js";
|
|
|
21
21
|
import { rebuildState } from "./doctor.js";
|
|
22
22
|
import { deriveState } from "./state.js";
|
|
23
23
|
import { resolveMilestoneIntegrationBranch } from "./git-service.js";
|
|
24
|
-
import { nativeIsRepo } from "./native-git-bridge.js";
|
|
24
|
+
import { nativeIsRepo, nativeHasChanges, nativeLastCommitEpoch, nativeGetCurrentBranch, nativeAddTracked, nativeCommit } from "./native-git-bridge.js";
|
|
25
25
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
26
26
|
import { runEnvironmentChecks } from "./doctor-environment.js";
|
|
27
27
|
/** In-memory health history for the current auto-mode session. */
|
|
@@ -232,6 +232,39 @@ export async function preDispatchHealthGate(basePath) {
|
|
|
232
232
|
catch {
|
|
233
233
|
// Non-fatal — dispatch continues if state/branch check fails
|
|
234
234
|
}
|
|
235
|
+
// ── Stale uncommitted changes — auto-snapshot before dispatch ──
|
|
236
|
+
// If the working tree is dirty and no commit has happened recently,
|
|
237
|
+
// create a safety snapshot so work isn't lost if the next unit crashes.
|
|
238
|
+
try {
|
|
239
|
+
if (nativeIsRepo(basePath)) {
|
|
240
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences ?? {};
|
|
241
|
+
const thresholdMinutes = prefs.stale_commit_threshold_minutes ?? 30;
|
|
242
|
+
if (thresholdMinutes > 0 && nativeHasChanges(basePath)) {
|
|
243
|
+
const branch = nativeGetCurrentBranch(basePath);
|
|
244
|
+
const lastEpoch = nativeLastCommitEpoch(basePath, branch || "HEAD");
|
|
245
|
+
const nowEpoch = Math.floor(Date.now() / 1000);
|
|
246
|
+
const minutesSinceCommit = lastEpoch > 0 ? (nowEpoch - lastEpoch) / 60 : Infinity;
|
|
247
|
+
if (minutesSinceCommit >= thresholdMinutes) {
|
|
248
|
+
const mins = Math.floor(minutesSinceCommit);
|
|
249
|
+
try {
|
|
250
|
+
nativeAddTracked(basePath);
|
|
251
|
+
const commitMsg = `gsd snapshot: pre-dispatch, uncommitted changes after ${mins}m inactivity`;
|
|
252
|
+
const result = nativeCommit(basePath, commitMsg);
|
|
253
|
+
if (result) {
|
|
254
|
+
fixesApplied.push(`pre-dispatch: created gsd snapshot after ${mins}m of uncommitted changes`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// Non-blocking — snapshot failed but dispatch can continue
|
|
259
|
+
fixesApplied.push("pre-dispatch: gsd snapshot failed");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
// Non-fatal
|
|
267
|
+
}
|
|
235
268
|
// ── Disk space check ──
|
|
236
269
|
// Catches low-disk conditions before dispatch rather than letting the unit
|
|
237
270
|
// fail mid-execution with ENOSPC (which wastes a full LLM turn).
|
|
@@ -144,7 +144,8 @@ function resolveKey(providerId) {
|
|
|
144
144
|
*/
|
|
145
145
|
const PROVIDER_ROUTES = {
|
|
146
146
|
anthropic: ["github-copilot"],
|
|
147
|
-
openai: ["github-copilot"],
|
|
147
|
+
openai: ["github-copilot", "openai-codex"],
|
|
148
|
+
google: ["google-gemini-cli"],
|
|
148
149
|
};
|
|
149
150
|
function checkLlmProviders() {
|
|
150
151
|
const required = collectConfiguredModelProviders();
|
|
@@ -108,11 +108,12 @@ export async function checkRuntimeHealth(basePath, issues, fixesApplied, shouldF
|
|
|
108
108
|
const orphaned = [];
|
|
109
109
|
for (const key of keys) {
|
|
110
110
|
// Key format: "unitType/unitId" e.g. "execute-task/M001/S01/T01"
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
// Hook units have compound types: "hook/<hookName>/unitId"
|
|
112
|
+
const { splitCompletedKey } = await import("./forensics.js");
|
|
113
|
+
const parsed = splitCompletedKey(key);
|
|
114
|
+
if (!parsed)
|
|
113
115
|
continue;
|
|
114
|
-
const unitType =
|
|
115
|
-
const unitId = key.slice(slashIdx + 1);
|
|
116
|
+
const { unitType, unitId } = parsed;
|
|
116
117
|
// Only validate artifact-producing unit types
|
|
117
118
|
const { verifyExpectedArtifact } = await import("./auto-recovery.js");
|
|
118
119
|
if (!verifyExpectedArtifact(unitType, unitId, basePath)) {
|
|
@@ -689,8 +689,10 @@ export async function runGSDDoctor(basePath, options) {
|
|
|
689
689
|
allTasksDone = allTasksDone && task.done;
|
|
690
690
|
}
|
|
691
691
|
// Blocker-without-replan detection
|
|
692
|
+
// Skip when all tasks are done — the blocker was implicitly resolved
|
|
693
|
+
// within the task and the slice is not stuck (#3105 Bug 2).
|
|
692
694
|
const replanPath = resolveSliceFile(basePath, milestoneId, slice.id, "REPLAN");
|
|
693
|
-
if (!replanPath) {
|
|
695
|
+
if (!replanPath && !allTasksDone) {
|
|
694
696
|
for (const task of plan.tasks) {
|
|
695
697
|
if (!task.done)
|
|
696
698
|
continue;
|
|
@@ -24,7 +24,9 @@ const NETWORK_RE = /network|ECONNRESET|ETIMEDOUT|ECONNREFUSED|socket hang up|fet
|
|
|
24
24
|
const SERVER_RE = /internal server error|500|502|503|overloaded|server_error|api_error|service.?unavailable/i;
|
|
25
25
|
// ECONNRESET/ECONNREFUSED are in NETWORK_RE (same-model retry first).
|
|
26
26
|
const CONNECTION_RE = /terminated|connection.?refused|other side closed|EPIPE|network.?(?:is\s+)?unavailable|stream_exhausted(?:_without_result)?/i;
|
|
27
|
-
|
|
27
|
+
// Catch-all for V8 JSON.parse errors: all modern variants end with "in JSON at position \d+".
|
|
28
|
+
// This eliminates the need to enumerate every error message variant individually.
|
|
29
|
+
const STREAM_RE = /in JSON at position \d+|Unexpected end of JSON|SyntaxError.*JSON/i;
|
|
28
30
|
const RESET_DELAY_RE = /reset in (\d+)s/i;
|
|
29
31
|
/**
|
|
30
32
|
* Classify an error message into one of the ErrorClass kinds.
|
|
@@ -33,9 +35,9 @@ const RESET_DELAY_RE = /reset in (\d+)s/i;
|
|
|
33
35
|
* 1. Permanent (auth/billing/quota) — unless also rate-limited
|
|
34
36
|
* 2. Rate limit (429, rate.?limit, too many requests)
|
|
35
37
|
* 3. Network (ECONNRESET, ETIMEDOUT, socket hang up, fetch failed, dns)
|
|
36
|
-
* 4.
|
|
37
|
-
* 5.
|
|
38
|
-
* 6.
|
|
38
|
+
* 4. Stream truncation (malformed JSON from mid-stream cut)
|
|
39
|
+
* 5. Server (500/502/503, overloaded, server_error)
|
|
40
|
+
* 6. Connection (terminated, ECONNREFUSED, EPIPE, other side closed)
|
|
39
41
|
* 7. Unknown
|
|
40
42
|
*/
|
|
41
43
|
export function classifyError(errorMsg, retryAfterMs) {
|
|
@@ -61,18 +63,18 @@ export function classifyError(errorMsg, retryAfterMs) {
|
|
|
61
63
|
// "billing" appearing alongside "network").
|
|
62
64
|
return { kind: "network", retryAfterMs: retryAfterMs ?? 3_000 };
|
|
63
65
|
}
|
|
64
|
-
// 4.
|
|
66
|
+
// 4. Stream truncation — downstream symptom of connection drop
|
|
67
|
+
if (STREAM_RE.test(errorMsg)) {
|
|
68
|
+
return { kind: "stream", retryAfterMs: retryAfterMs ?? 15_000 };
|
|
69
|
+
}
|
|
70
|
+
// 5. Server errors — try fallback model
|
|
65
71
|
if (SERVER_RE.test(errorMsg)) {
|
|
66
72
|
return { kind: "server", retryAfterMs: retryAfterMs ?? 30_000 };
|
|
67
73
|
}
|
|
68
|
-
//
|
|
74
|
+
// 6. Connection errors — try fallback model
|
|
69
75
|
if (CONNECTION_RE.test(errorMsg)) {
|
|
70
76
|
return { kind: "connection", retryAfterMs: retryAfterMs ?? 15_000 };
|
|
71
77
|
}
|
|
72
|
-
// 6. Stream truncation — downstream symptom of connection drop
|
|
73
|
-
if (STREAM_RE.test(errorMsg)) {
|
|
74
|
-
return { kind: "stream", retryAfterMs: retryAfterMs ?? 15_000 };
|
|
75
|
-
}
|
|
76
78
|
// 7. Unknown
|
|
77
79
|
return { kind: "unknown" };
|
|
78
80
|
}
|
|
@@ -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
|
}
|
|
@@ -22,6 +22,8 @@ import { deriveState } from "./state.js";
|
|
|
22
22
|
import { isAutoActive } from "./auto.js";
|
|
23
23
|
import { loadPrompt } from "./prompt-loader.js";
|
|
24
24
|
import { gsdRoot } from "./paths.js";
|
|
25
|
+
import { isDbAvailable, getAllMilestones, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
26
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
25
27
|
import { formatDuration } from "../shared/format-utils.js";
|
|
26
28
|
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
27
29
|
import { loadEffectiveGSDPreferences, loadGlobalGSDPreferences, getGlobalGSDPreferencesPath } from "./preferences.js";
|
|
@@ -29,13 +31,15 @@ import { showNextAction } from "../shared/tui.js";
|
|
|
29
31
|
import { ensurePreferencesFile, serializePreferencesToFrontmatter } from "./commands-prefs-wizard.js";
|
|
30
32
|
// ─── Duplicate Detection ──────────────────────────────────────────────────────
|
|
31
33
|
const DEDUP_PROMPT_SECTION = `
|
|
32
|
-
## Duplicate
|
|
34
|
+
## Pre-Investigation: Duplicate Check (REQUIRED)
|
|
33
35
|
|
|
34
|
-
Before
|
|
36
|
+
Before reading GSD source code or performing deep analysis, you MUST search for existing issues and PRs that may already address this bug. This avoids wasting tokens on already-fixed bugs.
|
|
35
37
|
|
|
36
38
|
### Search Steps
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
Use keywords from the user's problem description and the anomaly summaries in the forensic report above.
|
|
41
|
+
|
|
42
|
+
1. **Search closed issues** for similar keywords:
|
|
39
43
|
\`\`\`
|
|
40
44
|
gh issue list --repo gsd-build/gsd-2 --state closed --search "<keywords from root cause>" --limit 20
|
|
41
45
|
\`\`\`
|
|
@@ -52,20 +56,16 @@ Before offering to create a GitHub issue, you MUST search for existing issues an
|
|
|
52
56
|
|
|
53
57
|
### Analysis
|
|
54
58
|
|
|
55
|
-
For each result, compare it against
|
|
59
|
+
For each result, compare it against the user's reported symptoms and the forensic anomalies:
|
|
56
60
|
- Does the issue describe the same code path or file?
|
|
57
|
-
- Does the PR modify the
|
|
61
|
+
- Does the PR modify the area related to the reported symptoms?
|
|
58
62
|
- Is the symptom description semantically similar even if keywords differ?
|
|
59
63
|
|
|
60
|
-
###
|
|
61
|
-
|
|
62
|
-
If you find potential matches, present them to the user:
|
|
63
|
-
|
|
64
|
-
1. **"Already fixed by PR #X — skip issue creation"** — when a merged PR or closed issue clearly addresses the same root cause. Explain why you believe it matches.
|
|
65
|
-
2. **"Add my findings to existing issue #Y"** — when an open issue exists for the same bug. Use \`gh issue comment #Y --repo gsd-build/gsd-2\` to add forensic evidence.
|
|
66
|
-
3. **"Create new issue anyway"** — when existing results do not cover this specific failure.
|
|
64
|
+
### Decision Gate
|
|
67
65
|
|
|
68
|
-
|
|
66
|
+
- **Merged PR clearly fixes the described symptom** → Report "Already fixed by PR #X" with brief explanation. Skip full investigation.
|
|
67
|
+
- **Open issue matches** → Report "Existing issue #Y covers this." Offer to add forensic evidence. Skip full investigation unless user asks for deeper analysis.
|
|
68
|
+
- **No matches** → Proceed to full investigation below.
|
|
69
69
|
`;
|
|
70
70
|
async function writeForensicsDedupPref(ctx, enabled) {
|
|
71
71
|
const prefsPath = getGlobalGSDPreferencesPath();
|
|
@@ -148,6 +148,8 @@ export async function handleForensics(args, ctx, pi) {
|
|
|
148
148
|
});
|
|
149
149
|
ctx.ui.notify(`Forensic report saved: ${relative(basePath, savedPath)}`, "info");
|
|
150
150
|
pi.sendMessage({ customType: "gsd-forensics", content, display: false }, { triggerTurn: true });
|
|
151
|
+
// Persist forensics context so follow-up turns can re-inject it (#2941)
|
|
152
|
+
writeForensicsMarker(basePath, savedPath, content);
|
|
151
153
|
}
|
|
152
154
|
// ─── Report Builder ───────────────────────────────────────────────────────────
|
|
153
155
|
export async function buildForensicReport(basePath) {
|
|
@@ -167,8 +169,9 @@ export async function buildForensicReport(basePath) {
|
|
|
167
169
|
const unitTraces = scanActivityLogs(basePath, activeMilestone);
|
|
168
170
|
// 3. Load metrics
|
|
169
171
|
const metrics = loadLedgerFromDisk(basePath);
|
|
170
|
-
// 4. Load completed keys
|
|
172
|
+
// 4. Load completed keys (legacy) and DB completion counts
|
|
171
173
|
const completedKeys = loadCompletedKeys(basePath);
|
|
174
|
+
const dbCompletionCounts = getDbCompletionCounts();
|
|
172
175
|
// 5. Check crash lock
|
|
173
176
|
const crashLock = readCrashLock(basePath);
|
|
174
177
|
// 6. Run doctor
|
|
@@ -222,6 +225,7 @@ export async function buildForensicReport(basePath) {
|
|
|
222
225
|
unitTraces,
|
|
223
226
|
metrics,
|
|
224
227
|
completedKeys,
|
|
228
|
+
dbCompletionCounts,
|
|
225
229
|
crashLock,
|
|
226
230
|
doctorIssues,
|
|
227
231
|
anomalies,
|
|
@@ -458,6 +462,41 @@ function loadCompletedKeys(basePath) {
|
|
|
458
462
|
catch { /* non-fatal */ }
|
|
459
463
|
return [];
|
|
460
464
|
}
|
|
465
|
+
// ─── DB Completion Counts ────────────────────────────────────────────────────
|
|
466
|
+
function getDbCompletionCounts() {
|
|
467
|
+
if (!isDbAvailable())
|
|
468
|
+
return null;
|
|
469
|
+
const milestones = getAllMilestones();
|
|
470
|
+
let completedMilestones = 0;
|
|
471
|
+
let totalSlices = 0;
|
|
472
|
+
let completedSlices = 0;
|
|
473
|
+
let totalTasks = 0;
|
|
474
|
+
let completedTasks = 0;
|
|
475
|
+
for (const m of milestones) {
|
|
476
|
+
if (isClosedStatus(m.status))
|
|
477
|
+
completedMilestones++;
|
|
478
|
+
const slices = getMilestoneSlices(m.id);
|
|
479
|
+
for (const s of slices) {
|
|
480
|
+
totalSlices++;
|
|
481
|
+
if (isClosedStatus(s.status))
|
|
482
|
+
completedSlices++;
|
|
483
|
+
const tasks = getSliceTasks(m.id, s.id);
|
|
484
|
+
for (const t of tasks) {
|
|
485
|
+
totalTasks++;
|
|
486
|
+
if (isClosedStatus(t.status))
|
|
487
|
+
completedTasks++;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
milestones: completedMilestones,
|
|
493
|
+
milestonesTotal: milestones.length,
|
|
494
|
+
slices: completedSlices,
|
|
495
|
+
slicesTotal: totalSlices,
|
|
496
|
+
tasks: completedTasks,
|
|
497
|
+
tasksTotal: totalTasks,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
461
500
|
// ─── Anomaly Detectors ───────────────────────────────────────────────────────
|
|
462
501
|
function detectStuckLoops(units, anomalies) {
|
|
463
502
|
const counts = new Map();
|
|
@@ -515,15 +554,42 @@ function detectTimeouts(traces, anomalies) {
|
|
|
515
554
|
}
|
|
516
555
|
}
|
|
517
556
|
}
|
|
557
|
+
/**
|
|
558
|
+
* Parse a completed-unit key into its unitType and unitId.
|
|
559
|
+
*
|
|
560
|
+
* Hook units use a compound slash-delimited type ("hook/<hookName>"), so a
|
|
561
|
+
* naive `key.indexOf("/")` would split "hook/telegram-progress/M007/S01" into
|
|
562
|
+
* unitType="hook" (wrong) instead of "hook/telegram-progress".
|
|
563
|
+
*
|
|
564
|
+
* Returns `null` for malformed keys that cannot be split.
|
|
565
|
+
*/
|
|
566
|
+
export function splitCompletedKey(key) {
|
|
567
|
+
if (key.startsWith("hook/")) {
|
|
568
|
+
// Hook unit types are two segments: "hook/<hookName>/<unitId...>"
|
|
569
|
+
const secondSlash = key.indexOf("/", 5); // skip past "hook/"
|
|
570
|
+
if (secondSlash === -1)
|
|
571
|
+
return null; // malformed — no unitId after hook name
|
|
572
|
+
return {
|
|
573
|
+
unitType: key.slice(0, secondSlash),
|
|
574
|
+
unitId: key.slice(secondSlash + 1),
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
const slashIdx = key.indexOf("/");
|
|
578
|
+
if (slashIdx === -1)
|
|
579
|
+
return null;
|
|
580
|
+
return {
|
|
581
|
+
unitType: key.slice(0, slashIdx),
|
|
582
|
+
unitId: key.slice(slashIdx + 1),
|
|
583
|
+
};
|
|
584
|
+
}
|
|
518
585
|
function detectMissingArtifacts(completedKeys, basePath, activeMilestone, anomalies) {
|
|
519
586
|
// Also check the worktree path for artifacts — they may exist there but not at root
|
|
520
587
|
const wtBasePath = activeMilestone ? getAutoWorktreePath(basePath, activeMilestone) : null;
|
|
521
588
|
for (const key of completedKeys) {
|
|
522
|
-
const
|
|
523
|
-
if (
|
|
589
|
+
const parsed = splitCompletedKey(key);
|
|
590
|
+
if (!parsed)
|
|
524
591
|
continue;
|
|
525
|
-
const unitType =
|
|
526
|
-
const unitId = key.slice(slashIdx + 1);
|
|
592
|
+
const { unitType, unitId } = parsed;
|
|
527
593
|
const rootHasArtifact = verifyExpectedArtifact(unitType, unitId, basePath);
|
|
528
594
|
const wtHasArtifact = wtBasePath ? verifyExpectedArtifact(unitType, unitId, wtBasePath) : false;
|
|
529
595
|
if (!rootHasArtifact && !wtHasArtifact) {
|
|
@@ -749,6 +815,34 @@ function saveForensicReport(basePath, report, problemDescription) {
|
|
|
749
815
|
writeFileSync(filePath, sections.join("\n"), "utf-8");
|
|
750
816
|
return filePath;
|
|
751
817
|
}
|
|
818
|
+
/**
|
|
819
|
+
* Write a marker file so that buildBeforeAgentStartResult() can re-inject
|
|
820
|
+
* the forensics prompt on follow-up turns. (#2941)
|
|
821
|
+
*/
|
|
822
|
+
export function writeForensicsMarker(basePath, reportPath, promptContent) {
|
|
823
|
+
const dir = join(gsdRoot(basePath), "runtime");
|
|
824
|
+
mkdirSync(dir, { recursive: true });
|
|
825
|
+
const marker = {
|
|
826
|
+
reportPath,
|
|
827
|
+
promptContent,
|
|
828
|
+
createdAt: new Date().toISOString(),
|
|
829
|
+
};
|
|
830
|
+
writeFileSync(join(dir, "active-forensics.json"), JSON.stringify(marker), "utf-8");
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Read the active forensics marker, or null if none exists.
|
|
834
|
+
*/
|
|
835
|
+
export function readForensicsMarker(basePath) {
|
|
836
|
+
const markerPath = join(gsdRoot(basePath), "runtime", "active-forensics.json");
|
|
837
|
+
if (!existsSync(markerPath))
|
|
838
|
+
return null;
|
|
839
|
+
try {
|
|
840
|
+
return JSON.parse(readFileSync(markerPath, "utf-8"));
|
|
841
|
+
}
|
|
842
|
+
catch {
|
|
843
|
+
return null;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
752
846
|
// ─── Prompt Formatter ─────────────────────────────────────────────────────────
|
|
753
847
|
function formatReportForPrompt(report) {
|
|
754
848
|
const MAX_BYTES = 30 * 1024;
|
|
@@ -856,8 +950,17 @@ function formatReportForPrompt(report) {
|
|
|
856
950
|
}
|
|
857
951
|
sections.push("");
|
|
858
952
|
}
|
|
859
|
-
//
|
|
860
|
-
|
|
953
|
+
// Completion status — prefer DB counts, fall back to legacy completed-units.json
|
|
954
|
+
if (report.dbCompletionCounts) {
|
|
955
|
+
const c = report.dbCompletionCounts;
|
|
956
|
+
sections.push(`### Completion Status (from DB)`);
|
|
957
|
+
sections.push(`- ${c.milestones}/${c.milestonesTotal} milestones complete`);
|
|
958
|
+
sections.push(`- ${c.slices}/${c.slicesTotal} slices complete`);
|
|
959
|
+
sections.push(`- ${c.tasks}/${c.tasksTotal} tasks complete`);
|
|
960
|
+
}
|
|
961
|
+
else {
|
|
962
|
+
sections.push(`### Completed Keys: ${report.completedKeys.length}`);
|
|
963
|
+
}
|
|
861
964
|
sections.push(`### GSD Version: ${report.gsdVersion}`);
|
|
862
965
|
sections.push(`### Active Milestone: ${report.activeMilestone ?? "none"}`);
|
|
863
966
|
sections.push(`### Active Slice: ${report.activeSlice ?? "none"}`);
|