gsd-pi 2.58.0-dev.d63175c → 2.58.0-dev.e002a57
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/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 +17 -17
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- 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_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 +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- 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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_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_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_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_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_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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_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_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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_client-reference-manifest.js +1 -1
- 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_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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +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 +17 -17
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- 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/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/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
- 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/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.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +16 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -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 +27 -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.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +6 -0
- 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/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.ts +14 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +35 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -0
- 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/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/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/css/a58ef8a151aa0493.css +0 -1
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
- /package/dist/web/standalone/.next/static/{5DLsjFHdSB6_a1EDQVjr7 → nUA6d2OJrDSVq9RNb-c8b}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{5DLsjFHdSB6_a1EDQVjr7 → nUA6d2OJrDSVq9RNb-c8b}/_ssgManifest.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// GSD Extension — Projection Renderers (DB -> Markdown)
|
|
2
2
|
// Renders PLAN.md, ROADMAP.md, SUMMARY.md, and STATE.md from database rows.
|
|
3
3
|
// Projections are read-only views of engine state (Layer 3 of the architecture).
|
|
4
|
-
import { _getAdapter, isDbAvailable, getMilestone, getMilestoneSlices, getSliceTasks, } from "./gsd-db.js";
|
|
4
|
+
import { _getAdapter, isDbAvailable, getMilestone, getMilestoneSlices, getSliceTasks, getVerificationEvidence, } from "./gsd-db.js";
|
|
5
5
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { mkdirSync, existsSync } from "node:fs";
|
|
@@ -16,8 +16,10 @@ export function renderPlanContent(sliceRow, taskRows) {
|
|
|
16
16
|
const lines = [];
|
|
17
17
|
lines.push(`# ${sliceRow.id}: ${sliceRow.title}`);
|
|
18
18
|
lines.push("");
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
// #2945: never use full_summary_md/full_uat_md as display fallbacks —
|
|
20
|
+
// they contain multi-line rendered markdown that corrupts single-line fields.
|
|
21
|
+
lines.push(`**Goal:** ${sliceRow.goal || "TBD"}`);
|
|
22
|
+
lines.push(`**Demo:** After this: ${sliceRow.demo || "TBD"}`);
|
|
21
23
|
lines.push("");
|
|
22
24
|
lines.push("## Tasks");
|
|
23
25
|
for (const task of taskRows) {
|
|
@@ -85,7 +87,10 @@ export function renderRoadmapContent(milestoneRow, sliceRows) {
|
|
|
85
87
|
depends = slice.depends.join(", ");
|
|
86
88
|
}
|
|
87
89
|
const risk = (slice.risk || "low").toLowerCase();
|
|
88
|
-
|
|
90
|
+
// #2945 Bug 1: never use full_uat_md as a table cell fallback — it contains
|
|
91
|
+
// multi-line UAT content (preconditions, steps, expected results) that
|
|
92
|
+
// corrupts the markdown table and makes subsequent slices invisible.
|
|
93
|
+
const demo = slice.demo || "TBD";
|
|
89
94
|
lines.push(`| ${slice.id} | ${slice.title} | ${risk} | ${depends} | ${done} | ${demo} |`);
|
|
90
95
|
}
|
|
91
96
|
lines.push("");
|
|
@@ -108,64 +113,85 @@ export function renderRoadmapProjection(basePath, milestoneId) {
|
|
|
108
113
|
// ─── SUMMARY.md Projection ──────────────────────────────────────────────
|
|
109
114
|
/**
|
|
110
115
|
* Render SUMMARY.md content from a task row.
|
|
111
|
-
*
|
|
116
|
+
* Single source of truth for summary rendering — used both at completion
|
|
117
|
+
* time and at projection regeneration time (#2720).
|
|
118
|
+
*
|
|
119
|
+
* @param evidence - Optional verification evidence rows. When called from
|
|
120
|
+
* complete-task, these are passed directly. When called from projection
|
|
121
|
+
* regeneration, they are queried from the DB by renderSummaryProjection.
|
|
112
122
|
*/
|
|
113
|
-
export function renderSummaryContent(taskRow, sliceId, milestoneId) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
123
|
+
export function renderSummaryContent(taskRow, sliceId, milestoneId, evidence) {
|
|
124
|
+
// ── Frontmatter (YAML list format, matches parseSummary() expectations) ──
|
|
125
|
+
const keyFilesYaml = taskRow.key_files && taskRow.key_files.length > 0
|
|
126
|
+
? taskRow.key_files.map(f => ` - ${f}`).join("\n")
|
|
127
|
+
: " - (none)";
|
|
128
|
+
const keyDecisionsYaml = taskRow.key_decisions && taskRow.key_decisions.length > 0
|
|
129
|
+
? taskRow.key_decisions.map(d => ` - ${d}`).join("\n")
|
|
130
|
+
: " - (none)";
|
|
131
|
+
// Derive verification_result from evidence if available
|
|
132
|
+
const evidenceList = evidence ?? [];
|
|
133
|
+
const allPassed = evidenceList.length > 0 &&
|
|
134
|
+
evidenceList.every(e => {
|
|
135
|
+
const code = e.exitCode ?? e.exit_code ?? -1;
|
|
136
|
+
return code === 0 || e.verdict.includes("\u2705") || e.verdict.toLowerCase().includes("pass");
|
|
137
|
+
});
|
|
138
|
+
const verificationResult = taskRow.verification_result
|
|
139
|
+
? (allPassed ? "passed" : (evidenceList.length === 0 ? "untested" : "mixed"))
|
|
140
|
+
: (allPassed ? "passed" : (evidenceList.length === 0 ? "untested" : "mixed"));
|
|
141
|
+
// Build verification evidence table
|
|
142
|
+
let evidenceTable = "| # | Command | Exit Code | Verdict | Duration |\n|---|---------|-----------|---------|----------|\n";
|
|
143
|
+
if (evidenceList.length > 0) {
|
|
144
|
+
evidenceList.forEach((e, i) => {
|
|
145
|
+
const code = e.exitCode ?? e.exit_code ?? 0;
|
|
146
|
+
const dur = e.durationMs ?? e.duration_ms ?? 0;
|
|
147
|
+
evidenceTable += `| ${i + 1} | \`${e.command}\` | ${code} | ${e.verdict} | ${dur}ms |\n`;
|
|
148
|
+
});
|
|
133
149
|
}
|
|
134
150
|
else {
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
lines.push("patterns_established: []");
|
|
138
|
-
lines.push("drill_down_paths: []");
|
|
139
|
-
lines.push("observability_surfaces: []");
|
|
140
|
-
lines.push(`duration: "${taskRow.duration || ""}"`);
|
|
141
|
-
lines.push(`verification_result: "${taskRow.verification_result || ""}"`);
|
|
142
|
-
lines.push(`completed_at: ${taskRow.completed_at || ""}`);
|
|
143
|
-
lines.push(`blocker_discovered: ${taskRow.blocker_discovered ? "true" : "false"}`);
|
|
144
|
-
lines.push("---");
|
|
145
|
-
lines.push("");
|
|
146
|
-
lines.push(`# ${taskRow.id}: ${taskRow.title}`);
|
|
147
|
-
lines.push("");
|
|
148
|
-
// One-liner (if present)
|
|
149
|
-
if (taskRow.one_liner) {
|
|
150
|
-
lines.push(`> ${taskRow.one_liner}`);
|
|
151
|
-
lines.push("");
|
|
151
|
+
evidenceTable += "| \u2014 | No verification commands discovered | \u2014 | \u2014 | \u2014 |\n";
|
|
152
152
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
153
|
+
const title = taskRow.one_liner || taskRow.title || taskRow.id;
|
|
154
|
+
return `---
|
|
155
|
+
id: ${taskRow.id}
|
|
156
|
+
parent: ${sliceId}
|
|
157
|
+
milestone: ${milestoneId}
|
|
158
|
+
key_files:
|
|
159
|
+
${keyFilesYaml}
|
|
160
|
+
key_decisions:
|
|
161
|
+
${keyDecisionsYaml}
|
|
162
|
+
duration: ${taskRow.duration || ""}
|
|
163
|
+
verification_result: ${verificationResult}
|
|
164
|
+
completed_at: ${taskRow.completed_at || ""}
|
|
165
|
+
blocker_discovered: ${taskRow.blocker_discovered ? "true" : "false"}
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
# ${taskRow.id}: ${title}
|
|
169
|
+
|
|
170
|
+
**${taskRow.one_liner || ""}**
|
|
171
|
+
|
|
172
|
+
## What Happened
|
|
173
|
+
|
|
174
|
+
${taskRow.narrative || "No summary recorded."}
|
|
175
|
+
|
|
176
|
+
## Verification
|
|
177
|
+
|
|
178
|
+
${taskRow.verification_result || "No verification recorded."}
|
|
179
|
+
|
|
180
|
+
## Verification Evidence
|
|
181
|
+
|
|
182
|
+
${evidenceTable}
|
|
183
|
+
## Deviations
|
|
184
|
+
|
|
185
|
+
${taskRow.deviations || "None."}
|
|
186
|
+
|
|
187
|
+
## Known Issues
|
|
188
|
+
|
|
189
|
+
${taskRow.known_issues || "None."}
|
|
190
|
+
|
|
191
|
+
## Files Created/Modified
|
|
192
|
+
|
|
193
|
+
${taskRow.key_files && taskRow.key_files.length > 0 ? taskRow.key_files.map(f => `- \`${f}\``).join("\n") : "None."}
|
|
194
|
+
`;
|
|
169
195
|
}
|
|
170
196
|
/**
|
|
171
197
|
* Render SUMMARY.md projection to disk for a specific task.
|
|
@@ -176,7 +202,8 @@ export function renderSummaryProjection(basePath, milestoneId, sliceId, taskId)
|
|
|
176
202
|
const taskRow = taskRows.find(t => t.id === taskId);
|
|
177
203
|
if (!taskRow)
|
|
178
204
|
return;
|
|
179
|
-
const
|
|
205
|
+
const evidenceRows = getVerificationEvidence(milestoneId, sliceId, taskId);
|
|
206
|
+
const content = renderSummaryContent(taskRow, sliceId, milestoneId, evidenceRows);
|
|
180
207
|
const dir = join(basePath, ".gsd", "milestones", milestoneId, "slices", sliceId, "tasks");
|
|
181
208
|
mkdirSync(dir, { recursive: true });
|
|
182
209
|
atomicWriteSync(join(dir, `${taskId}-SUMMARY.md`), content);
|
|
@@ -190,13 +217,18 @@ export function renderSummaryProjection(basePath, milestoneId, sliceId, taskId)
|
|
|
190
217
|
export function renderStateContent(state) {
|
|
191
218
|
const lines = [];
|
|
192
219
|
lines.push("# GSD State", "");
|
|
193
|
-
const activeMilestone = state.activeMilestone
|
|
194
|
-
? `${state.activeMilestone.id}: ${state.activeMilestone.title}`
|
|
195
|
-
: "None";
|
|
196
220
|
const activeSlice = state.activeSlice
|
|
197
221
|
? `${state.activeSlice.id}: ${state.activeSlice.title}`
|
|
198
222
|
: "None";
|
|
199
|
-
|
|
223
|
+
if (state.phase === 'complete' && state.lastCompletedMilestone) {
|
|
224
|
+
lines.push(`**Last Completed Milestone:** ${state.lastCompletedMilestone.id}: ${state.lastCompletedMilestone.title}`);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
const activeMilestone = state.activeMilestone
|
|
228
|
+
? `${state.activeMilestone.id}: ${state.activeMilestone.title}`
|
|
229
|
+
: "None";
|
|
230
|
+
lines.push(`**Active Milestone:** ${activeMilestone}`);
|
|
231
|
+
}
|
|
200
232
|
lines.push(`**Active Slice:** ${activeSlice}`);
|
|
201
233
|
lines.push(`**Phase:** ${state.phase}`);
|
|
202
234
|
if (state.requirements) {
|
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { mkdirSync, existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
3
|
+
import { logWarning, logError } from "./workflow-logger.js";
|
|
3
4
|
import { readEvents, findForkPoint, appendEvent, getSessionId } from "./workflow-events.js";
|
|
4
|
-
import { transaction, updateTaskStatus, updateSliceStatus, insertVerificationEvidence, upsertDecision, openDatabase, } from "./gsd-db.js";
|
|
5
|
+
import { transaction, updateTaskStatus, updateSliceStatus, getSliceTasks, insertVerificationEvidence, upsertDecision, openDatabase, } from "./gsd-db.js";
|
|
6
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
5
7
|
import { writeManifest } from "./workflow-manifest.js";
|
|
6
8
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
7
9
|
import { acquireSyncLock, releaseSyncLock } from "./sync-lock.js";
|
|
10
|
+
// ─── Replay Helpers ──────────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Replay a complete_slice event with task validation.
|
|
13
|
+
*
|
|
14
|
+
* #2945 Bug 2: The original replay blindly called updateSliceStatus("done")
|
|
15
|
+
* without checking whether all tasks in the slice are actually complete.
|
|
16
|
+
* During API overload or partial execution, a complete_slice event could
|
|
17
|
+
* be logged even when tasks were skipped, causing the milestone completion
|
|
18
|
+
* guard to see the slice as "done" and allow premature milestone completion.
|
|
19
|
+
*
|
|
20
|
+
* This function validates that every task in the slice has a closed status
|
|
21
|
+
* before marking the slice as done. If any task is still pending, the slice
|
|
22
|
+
* status is left unchanged.
|
|
23
|
+
*/
|
|
24
|
+
export function replaySliceComplete(milestoneId, sliceId, ts) {
|
|
25
|
+
const tasks = getSliceTasks(milestoneId, sliceId);
|
|
26
|
+
// If there are tasks and any are not closed, skip the status update
|
|
27
|
+
if (tasks.length > 0) {
|
|
28
|
+
const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
|
|
29
|
+
if (incompleteTasks.length > 0) {
|
|
30
|
+
process.stderr.write(`[gsd] reconcile: skipping complete_slice replay for ${sliceId} — ` +
|
|
31
|
+
`${incompleteTasks.length} task(s) still pending\n`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
updateSliceStatus(milestoneId, sliceId, "done", ts);
|
|
36
|
+
}
|
|
8
37
|
// ─── replayEvents ─────────────────────────────────────────────────────────────
|
|
9
38
|
/**
|
|
10
39
|
* Replay a list of WorkflowEvents by dispatching each to the appropriate
|
|
@@ -58,7 +87,8 @@ function replayEvents(events) {
|
|
|
58
87
|
case "complete_slice": {
|
|
59
88
|
const milestoneId = p["milestoneId"];
|
|
60
89
|
const sliceId = p["sliceId"];
|
|
61
|
-
|
|
90
|
+
// #2945 Bug 2: validate tasks before marking slice done
|
|
91
|
+
replaySliceComplete(milestoneId, sliceId, event.ts);
|
|
62
92
|
break;
|
|
63
93
|
}
|
|
64
94
|
case "plan_slice": {
|
|
@@ -221,7 +251,7 @@ export function reconcileWorktreeLogs(mainBasePath, worktreeBasePath) {
|
|
|
221
251
|
// Acquire advisory lock to prevent concurrent reconcile + append races
|
|
222
252
|
const lock = acquireSyncLock(mainBasePath);
|
|
223
253
|
if (!lock.acquired) {
|
|
224
|
-
|
|
254
|
+
logWarning("reconcile", "could not acquire sync lock — another reconciliation may be in progress");
|
|
225
255
|
return { autoMerged: 0, conflicts: [] };
|
|
226
256
|
}
|
|
227
257
|
try {
|
|
@@ -251,7 +281,7 @@ function _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath) {
|
|
|
251
281
|
if (conflicts.length > 0) {
|
|
252
282
|
// D-04: atomic all-or-nothing — block entire merge
|
|
253
283
|
writeConflictsFile(mainBasePath, conflicts, worktreeBasePath);
|
|
254
|
-
|
|
284
|
+
logError("reconcile", `${conflicts.length} conflict(s) detected`, { count: String(conflicts.length), path: join(mainBasePath, ".gsd", "CONFLICTS.md") });
|
|
255
285
|
return { autoMerged: 0, conflicts };
|
|
256
286
|
}
|
|
257
287
|
// Step 6: Clean merge — stable sort by timestamp (index-based tiebreaker)
|
|
@@ -272,7 +302,7 @@ function _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath) {
|
|
|
272
302
|
writeManifest(mainBasePath);
|
|
273
303
|
}
|
|
274
304
|
catch (err) {
|
|
275
|
-
|
|
305
|
+
logWarning("reconcile", "manifest write failed (non-fatal)", { error: err.message });
|
|
276
306
|
}
|
|
277
307
|
return { autoMerged: merged.length, conflicts: [] };
|
|
278
308
|
}
|
|
@@ -3,6 +3,7 @@ import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
|
3
3
|
import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
|
|
4
4
|
import { resolveMilestoneFile, resolveSliceFile, resolveTaskFile, resolveTasksDir, } from "./paths.js";
|
|
5
5
|
import { deriveState } from "./state.js";
|
|
6
|
+
import { extractVerdict } from "./verdict-parser.js";
|
|
6
7
|
import { findMilestoneIds } from "./guided-flow.js";
|
|
7
8
|
import { getSliceBranchName, detectWorktreeName } from "./worktree.js";
|
|
8
9
|
// Extract milestone title from roadmap header without using parsers.
|
|
@@ -116,6 +117,29 @@ export async function indexWorkspace(basePath, opts = {}) {
|
|
|
116
117
|
taskId: state.activeTask?.id,
|
|
117
118
|
phase: state.phase,
|
|
118
119
|
};
|
|
120
|
+
// Enrich milestones with authoritative status from state registry (#2807)
|
|
121
|
+
if (state.registry) {
|
|
122
|
+
const registryMap = new Map(state.registry.map(e => [e.id, e]));
|
|
123
|
+
for (const milestone of milestones) {
|
|
124
|
+
const entry = registryMap.get(milestone.id);
|
|
125
|
+
if (entry) {
|
|
126
|
+
milestone.status = entry.status;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Populate validationVerdict from VALIDATION files (#2807)
|
|
131
|
+
for (const milestone of milestones) {
|
|
132
|
+
const validationPath = resolveMilestoneFile(basePath, milestone.id, "VALIDATION");
|
|
133
|
+
if (validationPath) {
|
|
134
|
+
const validationContent = await loadFile(validationPath);
|
|
135
|
+
if (validationContent) {
|
|
136
|
+
const verdict = extractVerdict(validationContent);
|
|
137
|
+
if (verdict === "pass" || verdict === "needs-attention" || verdict === "needs-remediation") {
|
|
138
|
+
milestone.validationVerdict = verdict;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
119
143
|
const scopes = [{ scope: "project", label: "project", kind: "project" }];
|
|
120
144
|
for (const milestone of milestones) {
|
|
121
145
|
scopes.push({ scope: milestone.id, label: `${milestone.id}: ${milestone.title}`, kind: "milestone" });
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* 3. merge() — LLM-guided reconciliation of .gsd/ artifacts back to main
|
|
15
15
|
* 4. remove() — git worktree remove + branch cleanup
|
|
16
16
|
*/
|
|
17
|
-
import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync } from "node:fs";
|
|
17
|
+
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync } from "node:fs";
|
|
18
18
|
import { execFileSync } from "node:child_process";
|
|
19
19
|
import { join, resolve, sep } from "node:path";
|
|
20
20
|
import { GSDError, GSD_PARSE_ERROR, GSD_STALE_STATE, GSD_LOCK_HELD, GSD_GIT_ERROR, GSD_MERGE_CONFLICT } from "./errors.js";
|
|
@@ -203,6 +203,73 @@ export function listWorktrees(basePath) {
|
|
|
203
203
|
}
|
|
204
204
|
return worktrees;
|
|
205
205
|
}
|
|
206
|
+
// ─── Nested .git Detection (#2616) ──────────────────────────────────────
|
|
207
|
+
//
|
|
208
|
+
// Scaffolding tools (create-next-app, cargo init, etc.) create nested .git
|
|
209
|
+
// directories inside worktrees. Git records these as gitlinks (mode 160000)
|
|
210
|
+
// without a .gitmodules entry — so worktree cleanup destroys the only copy
|
|
211
|
+
// of their object database, causing permanent silent data loss.
|
|
212
|
+
/** Directories to skip when scanning for nested .git dirs. */
|
|
213
|
+
const NESTED_GIT_SKIP_DIRS = new Set([
|
|
214
|
+
".git", ".gsd", "node_modules", ".next", ".nuxt", "dist", "build",
|
|
215
|
+
"__pycache__", ".tox", ".venv", "venv", "target", "vendor",
|
|
216
|
+
]);
|
|
217
|
+
/**
|
|
218
|
+
* Recursively find nested .git directories inside a worktree root.
|
|
219
|
+
* Returns paths to directories that contain their own .git (directory, not file).
|
|
220
|
+
* Skips node_modules, .gsd, and other non-project directories for performance.
|
|
221
|
+
*
|
|
222
|
+
* A nested .git *directory* (not a .git file — which is a legitimate worktree
|
|
223
|
+
* pointer) indicates a scaffolded repo that will become an orphaned gitlink.
|
|
224
|
+
*/
|
|
225
|
+
export function findNestedGitDirs(rootPath) {
|
|
226
|
+
const results = [];
|
|
227
|
+
function walk(dir, depth) {
|
|
228
|
+
// Cap recursion depth to avoid runaway scanning
|
|
229
|
+
if (depth > 10)
|
|
230
|
+
return;
|
|
231
|
+
let entries;
|
|
232
|
+
try {
|
|
233
|
+
entries = readdirSync(dir);
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
return; // Permission denied, broken symlink, etc.
|
|
237
|
+
}
|
|
238
|
+
for (const entry of entries) {
|
|
239
|
+
if (NESTED_GIT_SKIP_DIRS.has(entry))
|
|
240
|
+
continue;
|
|
241
|
+
const fullPath = join(dir, entry);
|
|
242
|
+
// Only follow real directories, not symlinks
|
|
243
|
+
let stat;
|
|
244
|
+
try {
|
|
245
|
+
stat = lstatSync(fullPath);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (!stat.isDirectory())
|
|
251
|
+
continue;
|
|
252
|
+
// Check if this directory contains a .git *directory* (not a .git file).
|
|
253
|
+
// A .git file is a worktree pointer and is legitimate.
|
|
254
|
+
// A .git directory is a standalone repo created by scaffolding.
|
|
255
|
+
const innerGit = join(fullPath, ".git");
|
|
256
|
+
try {
|
|
257
|
+
const innerStat = lstatSync(innerGit);
|
|
258
|
+
if (innerStat.isDirectory()) {
|
|
259
|
+
results.push(fullPath);
|
|
260
|
+
// Don't recurse into the nested repo — we found what we need
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// No .git here — continue scanning
|
|
266
|
+
}
|
|
267
|
+
walk(fullPath, depth + 1);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
walk(rootPath, 0);
|
|
271
|
+
return results;
|
|
272
|
+
}
|
|
206
273
|
/**
|
|
207
274
|
* Remove a worktree and optionally delete its branch.
|
|
208
275
|
* If the process is currently inside the worktree, chdir out first.
|
|
@@ -269,6 +336,24 @@ export function removeWorktree(basePath, name, opts = {}) {
|
|
|
269
336
|
// submodule status failed — proceed with normal removal
|
|
270
337
|
}
|
|
271
338
|
}
|
|
339
|
+
// Nested .git safety (#2616): detect nested .git directories created by
|
|
340
|
+
// scaffolding tools (create-next-app, cargo init, etc.). These produce
|
|
341
|
+
// gitlink entries (mode 160000) without .gitmodules — cleanup would destroy
|
|
342
|
+
// the only copy of the nested object database, causing permanent data loss.
|
|
343
|
+
// Fix: remove the nested .git dirs so git tracks the files as regular content.
|
|
344
|
+
const nestedGitDirs = findNestedGitDirs(resolvedWtPath);
|
|
345
|
+
if (nestedGitDirs.length > 0) {
|
|
346
|
+
for (const nestedDir of nestedGitDirs) {
|
|
347
|
+
const nestedGitPath = join(nestedDir, ".git");
|
|
348
|
+
try {
|
|
349
|
+
rmSync(nestedGitPath, { recursive: true, force: true });
|
|
350
|
+
logWarning("reconcile", `Removed nested .git directory from scaffolded project to prevent data loss (#2616)`, { worktree: name, nestedRepo: nestedDir });
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
logWarning("reconcile", `Failed to remove nested .git directory — files may be lost as orphaned gitlink`, { worktree: name, nestedRepo: nestedDir });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
272
357
|
// Remove worktree: try non-force first when submodules have changes,
|
|
273
358
|
// falling back to force only after submodule state has been preserved.
|
|
274
359
|
const useForce = hasSubmoduleChanges ? false : force;
|
|
@@ -283,6 +368,25 @@ export function removeWorktree(basePath, name, opts = {}) {
|
|
|
283
368
|
}
|
|
284
369
|
catch { /* may fail */ }
|
|
285
370
|
}
|
|
371
|
+
// (#2821) If the worktree directory STILL exists after both native removal
|
|
372
|
+
// attempts (e.g. untracked files like ASSESSMENT/UAT-RESULT prevent git
|
|
373
|
+
// worktree remove), force-remove the git internal worktree metadata first,
|
|
374
|
+
// then remove the filesystem directory. Without this, the .git/worktrees/<name>
|
|
375
|
+
// lock prevents rmSync from cleaning up, and the orphaned worktree directory
|
|
376
|
+
// causes every subsequent `/gsd auto` to re-enter the stale worktree.
|
|
377
|
+
if (existsSync(resolvedWtPath)) {
|
|
378
|
+
try {
|
|
379
|
+
const wtInternalDir = join(basePath, ".git", "worktrees", name);
|
|
380
|
+
if (existsSync(wtInternalDir)) {
|
|
381
|
+
rmSync(wtInternalDir, { recursive: true, force: true });
|
|
382
|
+
}
|
|
383
|
+
rmSync(resolvedWtPath, { recursive: true, force: true });
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
logWarning("reconcile", `Worktree directory could not be removed after git internal cleanup: ${resolvedWtPath}. ` +
|
|
387
|
+
`Manual cleanup: rm -rf "${resolvedWtPath.replaceAll("\\", "/")}"`, { worktree: name });
|
|
388
|
+
}
|
|
389
|
+
}
|
|
286
390
|
// Prune stale entries so git knows the worktree is gone
|
|
287
391
|
nativeWorktreePrune(basePath);
|
|
288
392
|
if (deleteBranch) {
|
|
@@ -248,7 +248,12 @@ export class WorktreeResolver {
|
|
|
248
248
|
eventType: "worktree-merge-start",
|
|
249
249
|
data: { milestoneId, mode },
|
|
250
250
|
});
|
|
251
|
-
|
|
251
|
+
// #2625: If we are physically inside an auto-worktree, we MUST merge
|
|
252
|
+
// regardless of the current isolation config. This prevents data loss when
|
|
253
|
+
// the default isolation mode changes between versions (e.g., "worktree" ->
|
|
254
|
+
// "none"): the worktree branch still holds real commits that need merging.
|
|
255
|
+
const inWorktree = this.deps.isInAutoWorktree(this.s.basePath) && this.s.originalBasePath;
|
|
256
|
+
if (mode === "none" && !inWorktree) {
|
|
252
257
|
debugLog("WorktreeResolver", {
|
|
253
258
|
action: "mergeAndExit",
|
|
254
259
|
milestoneId,
|
|
@@ -257,8 +262,7 @@ export class WorktreeResolver {
|
|
|
257
262
|
});
|
|
258
263
|
return;
|
|
259
264
|
}
|
|
260
|
-
if (mode === "worktree" ||
|
|
261
|
-
(this.deps.isInAutoWorktree(this.s.basePath) && this.s.originalBasePath)) {
|
|
265
|
+
if (mode === "worktree" || inWorktree) {
|
|
262
266
|
this._mergeWorktreeMode(milestoneId, ctx);
|
|
263
267
|
}
|
|
264
268
|
else if (mode === "branch") {
|
|
@@ -308,6 +312,19 @@ export class WorktreeResolver {
|
|
|
308
312
|
if (roadmapPath) {
|
|
309
313
|
const roadmapContent = this.deps.readFileSync(roadmapPath, "utf-8");
|
|
310
314
|
const mergeResult = this.deps.mergeMilestoneToMain(originalBase, milestoneId, roadmapContent);
|
|
315
|
+
// #2945 Bug 3: mergeMilestoneToMain performs best-effort worktree
|
|
316
|
+
// cleanup internally (step 12), but it can silently fail on Windows
|
|
317
|
+
// or when the worktree directory is locked. Perform a secondary
|
|
318
|
+
// teardown here to ensure the worktree is properly cleaned up.
|
|
319
|
+
// This is idempotent — if the worktree was already removed,
|
|
320
|
+
// teardownAutoWorktree handles the no-op case gracefully.
|
|
321
|
+
try {
|
|
322
|
+
this.deps.teardownAutoWorktree(originalBase, milestoneId);
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
// Best-effort — the primary cleanup in mergeMilestoneToMain may
|
|
326
|
+
// have already removed the worktree.
|
|
327
|
+
}
|
|
311
328
|
if (mergeResult.codeFilesChanged) {
|
|
312
329
|
ctx.notify(`Milestone ${milestoneId} merged to main.${mergeResult.pushed ? " Pushed to remote." : ""}`, "info");
|
|
313
330
|
}
|
|
@@ -74,7 +74,9 @@ function readConfigs() {
|
|
|
74
74
|
return servers;
|
|
75
75
|
}
|
|
76
76
|
function getServerConfig(name) {
|
|
77
|
-
|
|
77
|
+
const trimmed = name.trim();
|
|
78
|
+
return readConfigs().find((s) => s.name === trimmed ||
|
|
79
|
+
s.name.toLowerCase() === trimmed.toLowerCase());
|
|
78
80
|
}
|
|
79
81
|
/** Resolve ${VAR} references in env values against process.env. */
|
|
80
82
|
function resolveEnv(env) {
|
|
@@ -90,12 +92,14 @@ function resolveEnv(env) {
|
|
|
90
92
|
return resolved;
|
|
91
93
|
}
|
|
92
94
|
async function getOrConnect(name, signal) {
|
|
93
|
-
const existing = connections.get(name);
|
|
94
|
-
if (existing)
|
|
95
|
-
return existing.client;
|
|
96
95
|
const config = getServerConfig(name);
|
|
97
96
|
if (!config)
|
|
98
97
|
throw new Error(`Unknown MCP server: "${name}". Use mcp_servers to list available servers.`);
|
|
98
|
+
// Always use config.name as the canonical cache key so that variant
|
|
99
|
+
// casing / whitespace still hits the same connection.
|
|
100
|
+
const existing = connections.get(config.name);
|
|
101
|
+
if (existing)
|
|
102
|
+
return existing.client;
|
|
99
103
|
const client = new Client({ name: "gsd", version: "1.0.0" });
|
|
100
104
|
let transport;
|
|
101
105
|
if (config.transport === "stdio" && config.command) {
|
|
@@ -108,14 +112,14 @@ async function getOrConnect(name, signal) {
|
|
|
108
112
|
});
|
|
109
113
|
}
|
|
110
114
|
else if (config.transport === "http" && config.url) {
|
|
111
|
-
const resolvedUrl = config.url.replace(/\$\{([^}]+)\}/g, (_,
|
|
115
|
+
const resolvedUrl = config.url.replace(/\$\{([^}]+)\}/g, (_, varName) => process.env[varName] ?? "");
|
|
112
116
|
transport = new StreamableHTTPClientTransport(new URL(resolvedUrl));
|
|
113
117
|
}
|
|
114
118
|
else {
|
|
115
|
-
throw new Error(`Server "${name}" has unsupported transport: ${config.transport}`);
|
|
119
|
+
throw new Error(`Server "${config.name}" has unsupported transport: ${config.transport}`);
|
|
116
120
|
}
|
|
117
121
|
await client.connect(transport, { signal, timeout: 30000 });
|
|
118
|
-
connections.set(name, { client, transport });
|
|
122
|
+
connections.set(config.name, { client, transport });
|
|
119
123
|
return client;
|
|
120
124
|
}
|
|
121
125
|
async function closeAll() {
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// GSD2 — Ollama Extension: First-class local LLM support
|
|
2
|
+
/**
|
|
3
|
+
* Ollama Extension
|
|
4
|
+
*
|
|
5
|
+
* Auto-detects a running Ollama instance, discovers locally pulled models,
|
|
6
|
+
* and registers them as a first-class provider. No configuration required —
|
|
7
|
+
* if Ollama is running, models appear automatically.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Auto-discovery of local models via /api/tags
|
|
11
|
+
* - Capability detection (vision, reasoning, context window)
|
|
12
|
+
* - /ollama slash commands for model management
|
|
13
|
+
* - ollama_manage tool for LLM-driven model operations
|
|
14
|
+
* - Zero-cost model registration (local inference)
|
|
15
|
+
*
|
|
16
|
+
* Respects OLLAMA_HOST env var for non-default endpoints.
|
|
17
|
+
*/
|
|
18
|
+
import { importExtensionModule } from "@gsd/pi-coding-agent";
|
|
19
|
+
import * as client from "./ollama-client.js";
|
|
20
|
+
import { discoverModels, getOllamaOpenAIBaseUrl } from "./ollama-discovery.js";
|
|
21
|
+
import { registerOllamaCommands } from "./ollama-commands.js";
|
|
22
|
+
/** Default compat settings for Ollama models via OpenAI-compat endpoint */
|
|
23
|
+
const OLLAMA_COMPAT = {
|
|
24
|
+
supportsDeveloperRole: false,
|
|
25
|
+
supportsReasoningEffort: false,
|
|
26
|
+
supportsUsageInStreaming: false,
|
|
27
|
+
maxTokensField: "max_tokens",
|
|
28
|
+
supportsStore: false,
|
|
29
|
+
};
|
|
30
|
+
let toolsPromise = null;
|
|
31
|
+
async function registerOllamaTools(pi) {
|
|
32
|
+
if (!toolsPromise) {
|
|
33
|
+
toolsPromise = (async () => {
|
|
34
|
+
const { registerOllamaTool } = await importExtensionModule(import.meta.url, "./ollama-tool.js");
|
|
35
|
+
registerOllamaTool(pi);
|
|
36
|
+
})().catch((error) => {
|
|
37
|
+
toolsPromise = null;
|
|
38
|
+
throw error;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return toolsPromise;
|
|
42
|
+
}
|
|
43
|
+
/** Track whether we've registered models so we can clean up on shutdown */
|
|
44
|
+
let providerRegistered = false;
|
|
45
|
+
/**
|
|
46
|
+
* Probe Ollama and register discovered models.
|
|
47
|
+
* Safe to call multiple times — re-discovers and re-registers.
|
|
48
|
+
*/
|
|
49
|
+
async function probeAndRegister(pi) {
|
|
50
|
+
const running = await client.isRunning();
|
|
51
|
+
if (!running) {
|
|
52
|
+
if (providerRegistered) {
|
|
53
|
+
pi.unregisterProvider("ollama");
|
|
54
|
+
providerRegistered = false;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const models = await discoverModels();
|
|
59
|
+
if (models.length === 0)
|
|
60
|
+
return true; // Running but no models pulled
|
|
61
|
+
const baseUrl = getOllamaOpenAIBaseUrl();
|
|
62
|
+
pi.registerProvider("ollama", {
|
|
63
|
+
authMode: "none",
|
|
64
|
+
baseUrl,
|
|
65
|
+
api: "openai-completions",
|
|
66
|
+
isReady: () => true,
|
|
67
|
+
models: models.map((m) => ({
|
|
68
|
+
id: m.id,
|
|
69
|
+
name: m.name,
|
|
70
|
+
reasoning: m.reasoning,
|
|
71
|
+
input: m.input,
|
|
72
|
+
cost: m.cost,
|
|
73
|
+
contextWindow: m.contextWindow,
|
|
74
|
+
maxTokens: m.maxTokens,
|
|
75
|
+
compat: OLLAMA_COMPAT,
|
|
76
|
+
})),
|
|
77
|
+
});
|
|
78
|
+
providerRegistered = true;
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
export default function ollama(pi) {
|
|
82
|
+
// Register slash commands immediately (they check Ollama availability themselves)
|
|
83
|
+
registerOllamaCommands(pi);
|
|
84
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
85
|
+
// Register tool (deferred to avoid blocking startup)
|
|
86
|
+
if (ctx.hasUI) {
|
|
87
|
+
void registerOllamaTools(pi).catch((error) => {
|
|
88
|
+
ctx.ui.notify(`Ollama tool failed to load: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
await registerOllamaTools(pi);
|
|
93
|
+
}
|
|
94
|
+
// Async probe — don't block startup
|
|
95
|
+
probeAndRegister(pi)
|
|
96
|
+
.then((found) => {
|
|
97
|
+
if (found && ctx.hasUI) {
|
|
98
|
+
ctx.ui.setStatus("ollama", "Ollama");
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
.catch(() => {
|
|
102
|
+
// Silently ignore probe failures
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
pi.on("session_shutdown", async () => {
|
|
106
|
+
if (providerRegistered) {
|
|
107
|
+
pi.unregisterProvider("ollama");
|
|
108
|
+
providerRegistered = false;
|
|
109
|
+
}
|
|
110
|
+
toolsPromise = null;
|
|
111
|
+
});
|
|
112
|
+
}
|