@opengsd/gsd-pi 1.0.2-dev.e70300c → 1.0.2-dev.fb7ddf1
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 +63 -12
- package/dist/headless-answers.js +2 -1
- package/dist/headless-events.d.ts +1 -0
- package/dist/headless-events.js +8 -1
- package/dist/onboarding.js +22 -3
- package/dist/resource-loader.d.ts +7 -0
- package/dist/resource-loader.js +44 -9
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +34 -11
- package/dist/resources/extensions/context7/index.js +12 -2
- package/dist/resources/extensions/get-secrets-from-user.js +16 -16
- package/dist/resources/extensions/google-cli/index.js +30 -0
- package/dist/resources/extensions/google-cli/models.js +55 -0
- package/dist/resources/extensions/google-cli/package.json +11 -0
- package/dist/resources/extensions/google-cli/readiness.js +12 -0
- package/dist/resources/extensions/google-cli/stream-adapter.js +191 -0
- package/dist/resources/extensions/gsd/auto/loop.js +81 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
- package/dist/resources/extensions/gsd/auto/phases.js +38 -1
- package/dist/resources/extensions/gsd/auto/run-unit.js +8 -0
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +17 -7
- package/dist/resources/extensions/gsd/auto-post-unit.js +65 -16
- package/dist/resources/extensions/gsd/auto-prompts.js +5 -236
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-start.js +232 -49
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -1
- package/dist/resources/extensions/gsd/auto-verification.js +14 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +34 -1
- package/dist/resources/extensions/gsd/auto.js +40 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +39 -5
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +107 -27
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
- package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +4 -4
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
- package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
- package/dist/resources/extensions/gsd/commands-usage.js +105 -1
- package/dist/resources/extensions/gsd/config-overlay.js +20 -14
- package/dist/resources/extensions/gsd/context-overlay.js +22 -16
- package/dist/resources/extensions/gsd/dashboard-overlay.js +10 -23
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +87 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +70 -5
- package/dist/resources/extensions/gsd/doctor-providers.js +54 -24
- package/dist/resources/extensions/gsd/doctor.js +7 -2
- package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
- package/dist/resources/extensions/gsd/guided-flow.js +5 -6
- package/dist/resources/extensions/gsd/key-manager.js +45 -13
- package/dist/resources/extensions/gsd/mcp-filter.js +57 -18
- package/dist/resources/extensions/gsd/mcp-project-config.js +15 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +5 -1
- package/dist/resources/extensions/gsd/milestone-actions.js +3 -0
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +28 -0
- package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
- package/dist/resources/extensions/gsd/parallel-merge.js +6 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
- package/dist/resources/extensions/gsd/post-execution-checks.js +5 -4
- package/dist/resources/extensions/gsd/preferences-skills.js +11 -4
- package/dist/resources/extensions/gsd/preferences.js +14 -2
- package/dist/resources/extensions/gsd/prompt-loader.js +2 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +4 -2
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/system.md +3 -20
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
- package/dist/resources/extensions/gsd/repo-identity.js +36 -6
- package/dist/resources/extensions/gsd/repository-registry.js +3 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +13 -6
- package/dist/resources/extensions/gsd/skill-activation.js +233 -0
- package/dist/resources/extensions/gsd/skill-catalog.data.js +820 -0
- package/dist/resources/extensions/gsd/skill-catalog.install.js +179 -0
- package/dist/resources/extensions/gsd/skill-catalog.js +5 -1028
- package/dist/resources/extensions/gsd/skill-discovery.js +121 -79
- package/dist/resources/extensions/gsd/skill-scope.js +52 -0
- package/dist/resources/extensions/gsd/skill-telemetry.js +6 -39
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
- package/dist/resources/extensions/gsd/skills.js +60 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +351 -0
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +41 -0
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +4 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +42 -8
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +63 -2
- package/dist/resources/extensions/gsd/tui/render-kit.js +51 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +35 -26
- package/dist/resources/extensions/gsd/user-input-boundary.js +1 -1
- package/dist/resources/extensions/gsd/vision-ask.js +22 -0
- package/dist/resources/extensions/gsd/visualizer-overlay.js +8 -36
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
- package/dist/resources/extensions/gsd/worktree-state-projection.js +29 -0
- package/dist/resources/extensions/search-the-web/native-search.js +57 -8
- package/dist/resources/extensions/shared/confirm-ui.js +9 -6
- package/dist/resources/extensions/shared/dialog-frame.js +42 -0
- package/dist/resources/extensions/shared/interview-ui.js +42 -30
- package/dist/resources/extensions/shared/next-action-ui.js +6 -6
- package/dist/resources/extensions/subagent/index.js +8 -15
- package/dist/resources/shared/package-manager-detection.js +36 -0
- package/dist/resources/skills/agent-browser/SKILL.md +1 -1
- package/dist/resources/skills/api-design/SKILL.md +1 -1
- package/dist/resources/skills/code-optimizer/SKILL.md +6 -11
- package/dist/resources/skills/create-gsd-extension/SKILL.md +1 -1
- package/dist/resources/skills/create-mcp-server/SKILL.md +1 -1
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +2 -10
- package/dist/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
- package/dist/resources/skills/decompose-into-slices/SKILL.md +3 -3
- package/dist/resources/skills/dependency-upgrade/SKILL.md +1 -1
- package/dist/resources/skills/forensics/SKILL.md +2 -2
- package/dist/resources/skills/grill-me/SKILL.md +1 -1
- package/dist/resources/skills/handoff/SKILL.md +1 -1
- package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
- package/dist/resources/skills/observability/SKILL.md +1 -1
- package/dist/resources/skills/security-review/SKILL.md +1 -1
- package/dist/resources/skills/spike-wrap-up/SKILL.md +1 -1
- package/dist/resources/skills/tdd/SKILL.md +1 -1
- package/dist/resources/skills/write-docs/SKILL.md +1 -1
- package/dist/resources/skills/write-milestone-brief/SKILL.md +1 -1
- package/dist/update-check.d.ts +6 -2
- package/dist/update-check.js +7 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/package.json +5 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.test.js +5 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +15 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/dist/workflow.test.js +1 -0
- package/packages/contracts/dist/workflow.test.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +144 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +7 -1
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +47 -8
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +16 -14
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/skills.js +6 -0
- package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
- package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
- package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +48 -206
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +67 -220
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +50 -0
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
- package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -0
- 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/tests/tool-search-shim.test.js +29 -1
- package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.d.ts +4 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.js +58 -10
- package/packages/pi-ai/dist/utils/tool-search-shim.js.map +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.d.ts +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/README.md +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +3 -0
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -7
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +5 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +0 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/package.json +8 -8
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/scripts/install/detect-existing.js +17 -3
- package/scripts/install/npm-global.js +103 -33
- package/scripts/install.js +1 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -11
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +86 -19
- package/src/resources/extensions/context7/index.ts +15 -2
- package/src/resources/extensions/get-secrets-from-user.ts +17 -16
- package/src/resources/extensions/google-cli/index.ts +34 -0
- package/src/resources/extensions/google-cli/models.ts +57 -0
- package/src/resources/extensions/google-cli/package.json +11 -0
- package/src/resources/extensions/google-cli/readiness.ts +15 -0
- package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
- package/src/resources/extensions/gsd/auto/loop.ts +96 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
- package/src/resources/extensions/gsd/auto/phases.ts +47 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
- package/src/resources/extensions/gsd/auto-post-unit.ts +101 -18
- package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
- package/src/resources/extensions/gsd/auto-start.ts +307 -56
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +3 -1
- package/src/resources/extensions/gsd/auto-verification.ts +18 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +45 -1
- package/src/resources/extensions/gsd/auto.ts +50 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +124 -25
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
- package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +4 -4
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
- package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-usage.ts +110 -5
- package/src/resources/extensions/gsd/config-overlay.ts +19 -16
- package/src/resources/extensions/gsd/context-overlay.ts +24 -19
- package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +72 -5
- package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +7 -2
- package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
- package/src/resources/extensions/gsd/guided-flow.ts +5 -6
- package/src/resources/extensions/gsd/key-manager.ts +57 -14
- package/src/resources/extensions/gsd/mcp-filter.ts +64 -17
- package/src/resources/extensions/gsd/mcp-project-config.ts +24 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +6 -0
- package/src/resources/extensions/gsd/milestone-actions.ts +2 -0
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
- package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
- package/src/resources/extensions/gsd/parallel-merge.ts +6 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
- package/src/resources/extensions/gsd/post-execution-checks.ts +7 -4
- package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
- package/src/resources/extensions/gsd/preferences.ts +17 -2
- package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/system.md +3 -20
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
- package/src/resources/extensions/gsd/repo-identity.ts +35 -7
- package/src/resources/extensions/gsd/repository-registry.ts +3 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +13 -6
- package/src/resources/extensions/gsd/skill-activation.ts +292 -0
- package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
- package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
- package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
- package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
- package/src/resources/extensions/gsd/skill-scope.ts +63 -0
- package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
- package/src/resources/extensions/gsd/skills.ts +75 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
- package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +40 -3
- package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +22 -3
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +56 -1
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +127 -10
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
- package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +67 -1
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
- package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
- package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
- package/src/resources/extensions/gsd/vision-ask.ts +28 -0
- package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
- package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -0
- package/src/resources/extensions/search-the-web/native-search.ts +60 -8
- package/src/resources/extensions/shared/confirm-ui.ts +8 -12
- package/src/resources/extensions/shared/dialog-frame.ts +71 -0
- package/src/resources/extensions/shared/interview-ui.ts +43 -42
- package/src/resources/extensions/shared/next-action-ui.ts +6 -6
- package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
- package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
- package/src/resources/extensions/subagent/index.ts +8 -15
- package/src/resources/shared/package-manager-detection.ts +39 -0
- package/src/resources/skills/agent-browser/SKILL.md +1 -1
- package/src/resources/skills/api-design/SKILL.md +1 -1
- package/src/resources/skills/code-optimizer/SKILL.md +6 -11
- package/src/resources/skills/create-gsd-extension/SKILL.md +1 -1
- package/src/resources/skills/create-mcp-server/SKILL.md +1 -1
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/src/resources/skills/create-skill/workflows/verify-skill.md +2 -10
- package/src/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
- package/src/resources/skills/decompose-into-slices/SKILL.md +3 -3
- package/src/resources/skills/dependency-upgrade/SKILL.md +1 -1
- package/src/resources/skills/forensics/SKILL.md +2 -2
- package/src/resources/skills/grill-me/SKILL.md +1 -1
- package/src/resources/skills/handoff/SKILL.md +1 -1
- package/src/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
- package/src/resources/skills/observability/SKILL.md +1 -1
- package/src/resources/skills/security-review/SKILL.md +1 -1
- package/src/resources/skills/spike-wrap-up/SKILL.md +1 -1
- package/src/resources/skills/tdd/SKILL.md +1 -1
- package/src/resources/skills/write-docs/SKILL.md +1 -1
- package/src/resources/skills/write-milestone-brief/SKILL.md +1 -1
- /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
|
@@ -16,7 +16,7 @@ import { delimiter, join } from "node:path";
|
|
|
16
16
|
import { AuthStorage } from "@gsd/pi-coding-agent";
|
|
17
17
|
import { getEnvApiKey } from "@gsd/pi-ai";
|
|
18
18
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
19
|
-
import { getAuthPath, PROVIDER_REGISTRY, type ProviderCategory } from "./key-manager.js";
|
|
19
|
+
import { getAuthPath, PROVIDER_REGISTRY, supportsBrowserOAuth, type ProviderCategory } from "./key-manager.js";
|
|
20
20
|
import { homedir } from "node:os";
|
|
21
21
|
|
|
22
22
|
// ── Types ──────────────────────────────────────────────────────────────────────
|
|
@@ -42,11 +42,10 @@ export interface ProviderCheckResult {
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Providers that use external CLI authentication (not API keys).
|
|
45
|
-
*
|
|
45
|
+
* When explicitly selected, the provider's own CLI/session owns auth.
|
|
46
46
|
*/
|
|
47
47
|
const CLI_AUTH_PROVIDERS = new Set([
|
|
48
48
|
"claude-code",
|
|
49
|
-
"openai-codex",
|
|
50
49
|
"google-gemini-cli",
|
|
51
50
|
"google-antigravity",
|
|
52
51
|
]);
|
|
@@ -156,26 +155,30 @@ interface KeyLookup {
|
|
|
156
155
|
* Map of CLI provider IDs to their binary names on disk.
|
|
157
156
|
* Used for lightweight binary-presence checks (PATH scan, no subprocess).
|
|
158
157
|
*/
|
|
159
|
-
const CLI_BINARY_MAP: Record<string, string> = {
|
|
160
|
-
"claude-code": "claude",
|
|
161
|
-
"
|
|
162
|
-
"google-
|
|
163
|
-
"google-antigravity": "antigravity",
|
|
158
|
+
const CLI_BINARY_MAP: Record<string, string[]> = {
|
|
159
|
+
"claude-code": ["claude", "claude-code"],
|
|
160
|
+
"google-gemini-cli": ["gemini"],
|
|
161
|
+
"google-antigravity": ["agy"],
|
|
164
162
|
};
|
|
165
163
|
|
|
164
|
+
const CLI_AUTH_PATH_CHECK_PROVIDERS = new Set([
|
|
165
|
+
"google-gemini-cli",
|
|
166
|
+
"google-antigravity",
|
|
167
|
+
]);
|
|
168
|
+
|
|
166
169
|
/**
|
|
167
170
|
* Check if a CLI provider's binary exists anywhere in PATH.
|
|
168
171
|
* Fast filesystem scan — no subprocess, no network, sub-1ms.
|
|
169
172
|
*/
|
|
170
173
|
function isCliBinaryInPath(providerId: string): boolean {
|
|
171
|
-
const
|
|
172
|
-
if (!
|
|
174
|
+
const binaries = CLI_BINARY_MAP[providerId];
|
|
175
|
+
if (!binaries) return false;
|
|
173
176
|
|
|
174
177
|
const pathDirs = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
175
178
|
|
|
176
179
|
// On Windows, command shims are commonly installed as .cmd/.exe/.bat/.com.
|
|
177
180
|
// Scan PATHEXT candidates in addition to the bare binary name.
|
|
178
|
-
const executableNames: string[] = [
|
|
181
|
+
const executableNames: string[] = [...binaries];
|
|
179
182
|
if (process.platform === "win32") {
|
|
180
183
|
const rawPathExt = process.env.PATHEXT
|
|
181
184
|
?.split(";")
|
|
@@ -185,9 +188,11 @@ function isCliBinaryInPath(providerId: string): boolean {
|
|
|
185
188
|
ext.startsWith(".") ? ext.toLowerCase() : `.${ext.toLowerCase()}`,
|
|
186
189
|
);
|
|
187
190
|
const defaultExt = [".exe", ".cmd", ".bat", ".com"];
|
|
188
|
-
for (const
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
+
for (const binary of binaries) {
|
|
192
|
+
for (const ext of [...normalizedPathExt, ...defaultExt]) {
|
|
193
|
+
const candidate = `${binary}${ext}`;
|
|
194
|
+
if (!executableNames.includes(candidate)) executableNames.push(candidate);
|
|
195
|
+
}
|
|
191
196
|
}
|
|
192
197
|
}
|
|
193
198
|
|
|
@@ -224,12 +229,6 @@ function hasModelsJsonApiKey(providerId: string): boolean {
|
|
|
224
229
|
function resolveKey(providerId: string): KeyLookup {
|
|
225
230
|
const info = PROVIDER_REGISTRY.find(p => p.id === providerId);
|
|
226
231
|
|
|
227
|
-
// claude-code never stores credentials in auth.json — GSD delegates entirely to
|
|
228
|
-
// the local CLI binary. Presence of the binary in PATH is the only signal.
|
|
229
|
-
if (providerId === "claude-code") {
|
|
230
|
-
return { found: isCliBinaryInPath("claude-code"), source: "env", backedOff: false };
|
|
231
|
-
}
|
|
232
|
-
|
|
233
232
|
if (providerId === "anthropic-vertex" && process.env.ANTHROPIC_VERTEX_PROJECT_ID) {
|
|
234
233
|
return { found: true, source: "env", backedOff: false };
|
|
235
234
|
}
|
|
@@ -242,9 +241,15 @@ function resolveKey(providerId: string): KeyLookup {
|
|
|
242
241
|
const creds = auth.getCredentialsForProvider(providerId);
|
|
243
242
|
if (creds.length > 0) {
|
|
244
243
|
// Filter out empty placeholder keys (from skipped onboarding)
|
|
245
|
-
const hasRealKey = creds.some(c =>
|
|
246
|
-
|
|
247
|
-
|
|
244
|
+
const hasRealKey = creds.some(c => {
|
|
245
|
+
if (c.type === "oauth") return true;
|
|
246
|
+
if (c.type !== "api_key") return false;
|
|
247
|
+
|
|
248
|
+
const key = (c as { key?: string }).key?.trim();
|
|
249
|
+
if (!key) return false;
|
|
250
|
+
|
|
251
|
+
return !(CLI_AUTH_PROVIDERS.has(providerId) && key === "cli");
|
|
252
|
+
});
|
|
248
253
|
if (hasRealKey) {
|
|
249
254
|
return {
|
|
250
255
|
found: true,
|
|
@@ -275,6 +280,12 @@ function resolveKey(providerId: string): KeyLookup {
|
|
|
275
280
|
return { found: true, source: "models.json", backedOff: false };
|
|
276
281
|
}
|
|
277
282
|
|
|
283
|
+
// Cross-provider routes can use a local CLI when it is installed. Explicit
|
|
284
|
+
// external CLI provider selections are handled in checkLlmProviders() below.
|
|
285
|
+
if (CLI_AUTH_PROVIDERS.has(providerId) && isCliBinaryInPath(providerId)) {
|
|
286
|
+
return { found: true, source: "env", backedOff: false };
|
|
287
|
+
}
|
|
288
|
+
|
|
278
289
|
return { found: false, source: "none", backedOff: false };
|
|
279
290
|
}
|
|
280
291
|
|
|
@@ -285,15 +296,32 @@ function checkLlmProviders(): ProviderCheckResult[] {
|
|
|
285
296
|
const results: ProviderCheckResult[] = [];
|
|
286
297
|
|
|
287
298
|
for (const providerId of required) {
|
|
288
|
-
// CLI-authenticated providers don't need API keys
|
|
299
|
+
// CLI-authenticated providers don't need API keys. The provider's own
|
|
300
|
+
// request path validates CLI sessions when it is used.
|
|
289
301
|
if (CLI_AUTH_PROVIDERS.has(providerId)) {
|
|
290
302
|
const info = PROVIDER_REGISTRY.find(p => p.id === providerId);
|
|
303
|
+
const label = info?.label ?? providerId;
|
|
304
|
+
if (CLI_AUTH_PATH_CHECK_PROVIDERS.has(providerId) && !isCliBinaryInPath(providerId)) {
|
|
305
|
+
const binaries = CLI_BINARY_MAP[providerId]?.map(binary => `\`${binary}\``).join(" or ");
|
|
306
|
+
results.push({
|
|
307
|
+
name: providerId,
|
|
308
|
+
label,
|
|
309
|
+
category: "llm",
|
|
310
|
+
status: "error",
|
|
311
|
+
message: `${label} — CLI not found`,
|
|
312
|
+
detail: binaries
|
|
313
|
+
? `Install ${label} and ensure ${binaries} is on PATH`
|
|
314
|
+
: `Install ${label} and ensure its CLI is on PATH`,
|
|
315
|
+
required: true,
|
|
316
|
+
});
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
291
319
|
results.push({
|
|
292
320
|
name: providerId,
|
|
293
|
-
label
|
|
321
|
+
label,
|
|
294
322
|
category: "llm",
|
|
295
323
|
status: "ok",
|
|
296
|
-
message: `${
|
|
324
|
+
message: `${label} — CLI auth (no key needed)`,
|
|
297
325
|
required: true,
|
|
298
326
|
});
|
|
299
327
|
continue;
|
|
@@ -333,7 +361,7 @@ function checkLlmProviders(): ProviderCheckResult[] {
|
|
|
333
361
|
message: `${label} — not configured`,
|
|
334
362
|
detail: providerId === "anthropic-vertex"
|
|
335
363
|
? "Set ANTHROPIC_VERTEX_PROJECT_ID and authenticate with Google ADC"
|
|
336
|
-
: info
|
|
364
|
+
: info && supportsBrowserOAuth(info)
|
|
337
365
|
? `Run /gsd keys to authenticate`
|
|
338
366
|
: `Set ${envVar} or run /gsd keys`,
|
|
339
367
|
required: true,
|
|
@@ -332,7 +332,7 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|
|
332
332
|
return true;
|
|
333
333
|
};
|
|
334
334
|
|
|
335
|
-
const prefs = loadEffectiveGSDPreferences();
|
|
335
|
+
const prefs = loadEffectiveGSDPreferences(basePath);
|
|
336
336
|
if (prefs) {
|
|
337
337
|
const prefIssues = validatePreferenceShape(prefs.preferences);
|
|
338
338
|
for (const issue of prefIssues) {
|
|
@@ -514,13 +514,18 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|
|
514
514
|
try {
|
|
515
515
|
if (!lstatSync(join(slicesDir, entry)).isDirectory()) continue;
|
|
516
516
|
} catch { continue; }
|
|
517
|
+
if (entry === "parallel-research") continue;
|
|
517
518
|
if (!knownSliceIds.has(entry)) {
|
|
519
|
+
const quarantineExample = `.gsd/quarantine/milestones/${milestoneId}/slices/${entry}-manual-review`;
|
|
518
520
|
issues.push({
|
|
519
521
|
severity: "warning",
|
|
520
522
|
code: "orphaned_slice_directory",
|
|
521
523
|
scope: "milestone",
|
|
522
524
|
unitId: milestoneId,
|
|
523
|
-
message:
|
|
525
|
+
message:
|
|
526
|
+
`Directory "${entry}" exists in ${milestoneId}/slices/ but is not referenced in the roadmap or DB. ` +
|
|
527
|
+
`Review it; if stale, move or delete it. To preserve it, move it under ${quarantineExample}. ` +
|
|
528
|
+
"If it contains work to keep, copy or merge that content into a DB-backed slice before resuming.",
|
|
524
529
|
file: `${relMilestonePath(basePath, milestoneId)}/slices/${entry}`,
|
|
525
530
|
fixable: false,
|
|
526
531
|
});
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
|
-
import { join } from "node:path";
|
|
6
|
+
import { dirname, join, resolve } from "node:path";
|
|
7
7
|
|
|
8
8
|
import { autoResolveSafeConflictPaths } from "./git-conflict-resolve.js";
|
|
9
9
|
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
@@ -14,6 +14,21 @@ function splitZeroDelimited(output: string): string[] {
|
|
|
14
14
|
return output.split("\0").filter(Boolean);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
function hasGitMarker(basePath: string): boolean {
|
|
18
|
+
try {
|
|
19
|
+
let dir = resolve(basePath);
|
|
20
|
+
for (let i = 0; i < 30; i++) {
|
|
21
|
+
if (existsSync(join(dir, ".git"))) return true;
|
|
22
|
+
const parent = dirname(dir);
|
|
23
|
+
if (parent === dir) break;
|
|
24
|
+
dir = parent;
|
|
25
|
+
}
|
|
26
|
+
} catch {
|
|
27
|
+
// Fall through to the git probes, which will report unknown on failure.
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
17
32
|
export function listUnmergedGitPaths(basePath: string): string[] | null {
|
|
18
33
|
try {
|
|
19
34
|
const output = spawnSync("git", ["diff", "--name-only", "--diff-filter=U", "-z"], {
|
|
@@ -75,6 +90,15 @@ export interface GitConflictProbeResult {
|
|
|
75
90
|
}
|
|
76
91
|
|
|
77
92
|
export function probeGitConflictState(basePath: string): GitConflictProbeResult {
|
|
93
|
+
if (!hasGitMarker(basePath)) {
|
|
94
|
+
return {
|
|
95
|
+
status: "clean",
|
|
96
|
+
unmerged: [],
|
|
97
|
+
checkFailures: [],
|
|
98
|
+
mergeStateBlockers: [],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
78
102
|
const unmerged = listUnmergedGitPaths(basePath);
|
|
79
103
|
if (unmerged === null) {
|
|
80
104
|
return {
|
|
@@ -1218,7 +1218,7 @@ async function dispatchWorkflow(
|
|
|
1218
1218
|
|
|
1219
1219
|
if (unitType) setGuidedUnitContext(projectRoot, unitType);
|
|
1220
1220
|
try {
|
|
1221
|
-
pi.sendMessage(
|
|
1221
|
+
await pi.sendMessage(
|
|
1222
1222
|
{
|
|
1223
1223
|
customType,
|
|
1224
1224
|
content: buildWorkflowDispatchContent({ workflow, workflowPath, task: note }),
|
|
@@ -1231,10 +1231,9 @@ async function dispatchWorkflow(
|
|
|
1231
1231
|
throw err;
|
|
1232
1232
|
}
|
|
1233
1233
|
} finally {
|
|
1234
|
-
// Restore full tool
|
|
1235
|
-
//
|
|
1236
|
-
//
|
|
1237
|
-
// block ensures restoration even if sendMessage throws.
|
|
1234
|
+
// Restore full tool/skill surface after the turn completes. Awaiting
|
|
1235
|
+
// sendMessage ensures scoped skills stay in _baseSystemPrompt through
|
|
1236
|
+
// before_agent_start (#3628, skill token savings).
|
|
1238
1237
|
restoreGsdWorkflowTools(pi, savedTools);
|
|
1239
1238
|
}
|
|
1240
1239
|
}
|
|
@@ -1358,7 +1357,7 @@ function buildHeadlessDiscussPrompt(nextId: string, seedContext: string, _basePa
|
|
|
1358
1357
|
* Run preparation phase if enabled, then build the discuss prompt.
|
|
1359
1358
|
* Preparation analyzes the codebase and prior context, injecting the results
|
|
1360
1359
|
* as supplementary context into the standard discuss template. The discuss
|
|
1361
|
-
* template drives the conversation
|
|
1360
|
+
* template drives the conversation with a variable vision opener, while
|
|
1362
1361
|
* the preparation briefs give the agent grounding in the existing codebase.
|
|
1363
1362
|
*
|
|
1364
1363
|
* @param ctx - Extension command context with UI for progress notifications
|
|
@@ -22,6 +22,7 @@ import { gsdHome } from "./gsd-home.js";
|
|
|
22
22
|
// ─── Provider Registry ─────────────────────────────────────────────────────────
|
|
23
23
|
|
|
24
24
|
export type ProviderCategory = "llm" | "tool" | "search" | "remote";
|
|
25
|
+
export type ProviderAuthMode = "apiKey" | "browserOAuth" | "externalCli" | "cloudIdentity" | "none";
|
|
25
26
|
|
|
26
27
|
export interface ProviderInfo {
|
|
27
28
|
id: string;
|
|
@@ -29,24 +30,24 @@ export interface ProviderInfo {
|
|
|
29
30
|
category: ProviderCategory;
|
|
30
31
|
envVar?: string;
|
|
31
32
|
prefixes?: string[];
|
|
32
|
-
|
|
33
|
+
authMode?: ProviderAuthMode;
|
|
33
34
|
dashboardUrl?: string;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export const PROVIDER_REGISTRY: ProviderInfo[] = [
|
|
37
38
|
// LLM Providers
|
|
38
|
-
{ id: "anthropic", label: "Anthropic (Claude)", category: "llm", envVar: "ANTHROPIC_API_KEY", prefixes: ["sk-ant-"],
|
|
39
|
+
{ id: "anthropic", label: "Anthropic (Claude)", category: "llm", envVar: "ANTHROPIC_API_KEY", prefixes: ["sk-ant-"], authMode: "apiKey", dashboardUrl: "console.anthropic.com" },
|
|
39
40
|
// Claude Code CLI: routes through the local `claude` binary — no API key,
|
|
40
41
|
// authentication is handled by the CLI's own OAuth flow.
|
|
41
42
|
// Referenced by doctor-providers.ts, auto-model-selection.ts, and others;
|
|
42
43
|
// must be in the canonical registry so all consumers see the same catalog.
|
|
43
44
|
// See: https://github.com/open-gsd/gsd-pi/issues/4541
|
|
44
|
-
{ id: "claude-code", label: "Claude Code CLI", category: "llm",
|
|
45
|
+
{ id: "claude-code", label: "Claude Code CLI", category: "llm", authMode: "externalCli" },
|
|
45
46
|
{ id: "openai", label: "OpenAI", category: "llm", envVar: "OPENAI_API_KEY", prefixes: ["sk-"], dashboardUrl: "platform.openai.com/api-keys" },
|
|
46
|
-
{ id: "github-copilot", label: "GitHub Copilot", category: "llm", envVar: "GITHUB_TOKEN",
|
|
47
|
-
{ id: "openai-codex", label: "ChatGPT Plus/Pro (Codex)",category: "llm",
|
|
48
|
-
{ id: "google-gemini-cli",label: "Google Gemini CLI", category: "llm",
|
|
49
|
-
{ id: "google-antigravity",label: "Antigravity", category: "llm",
|
|
47
|
+
{ id: "github-copilot", label: "GitHub Copilot", category: "llm", envVar: "GITHUB_TOKEN", authMode: "browserOAuth" },
|
|
48
|
+
{ id: "openai-codex", label: "ChatGPT Plus/Pro (Codex)",category: "llm", authMode: "browserOAuth" },
|
|
49
|
+
{ id: "google-gemini-cli",label: "Google Gemini CLI", category: "llm", authMode: "externalCli" },
|
|
50
|
+
{ id: "google-antigravity",label: "Antigravity", category: "llm", authMode: "externalCli" },
|
|
50
51
|
{ id: "google", label: "Google (Gemini)", category: "llm", envVar: "GEMINI_API_KEY", dashboardUrl: "aistudio.google.com/apikey" },
|
|
51
52
|
{ id: "groq", label: "Groq", category: "llm", envVar: "GROQ_API_KEY", dashboardUrl: "console.groq.com" },
|
|
52
53
|
{ id: "xai", label: "xAI (Grok)", category: "llm", envVar: "XAI_API_KEY", dashboardUrl: "console.x.ai" },
|
|
@@ -77,6 +78,21 @@ export const PROVIDER_REGISTRY: ProviderInfo[] = [
|
|
|
77
78
|
|
|
78
79
|
// ─── Utilities ──────────────────────────────────────────────────────────────────
|
|
79
80
|
|
|
81
|
+
export function getProviderAuthMode(provider: ProviderInfo): ProviderAuthMode {
|
|
82
|
+
return provider.authMode ?? "apiKey";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function supportsBrowserOAuth(provider: ProviderInfo): boolean {
|
|
86
|
+
return getProviderAuthMode(provider) === "browserOAuth";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function supportsStoredApiKey(provider: ProviderInfo): boolean {
|
|
90
|
+
const mode = getProviderAuthMode(provider);
|
|
91
|
+
if (mode === "externalCli" || mode === "cloudIdentity" || mode === "none") return false;
|
|
92
|
+
if (mode === "browserOAuth") return Boolean(provider.envVar || provider.prefixes?.length);
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
80
96
|
/**
|
|
81
97
|
* Mask an API key for display: show first 4 + last 4 chars.
|
|
82
98
|
* Keys shorter than 12 chars show only first 2 + last 2.
|
|
@@ -104,10 +120,13 @@ export function formatDuration(ms: number): string {
|
|
|
104
120
|
/**
|
|
105
121
|
* Describe a credential's type and status.
|
|
106
122
|
*/
|
|
107
|
-
export function describeCredential(cred: AuthCredential): string {
|
|
123
|
+
export function describeCredential(cred: AuthCredential, provider?: ProviderInfo): string {
|
|
108
124
|
if (cred.type === "api_key") {
|
|
109
125
|
const apiCred = cred as ApiKeyCredential;
|
|
110
126
|
if (!apiCred.key) return "empty key";
|
|
127
|
+
if (apiCred.key === "cli" && provider && getProviderAuthMode(provider) === "externalCli") {
|
|
128
|
+
return "external CLI";
|
|
129
|
+
}
|
|
111
130
|
return `API key (${maskKey(apiCred.key)})`;
|
|
112
131
|
}
|
|
113
132
|
if (cred.type === "oauth") {
|
|
@@ -171,7 +190,7 @@ export function getAllKeyStatuses(auth: AuthStorage): KeyStatus[] {
|
|
|
171
190
|
const desc =
|
|
172
191
|
creds.length > 1
|
|
173
192
|
? `${creds.length} keys (round-robin)`
|
|
174
|
-
: describeCredential(firstCred);
|
|
193
|
+
: describeCredential(firstCred, provider);
|
|
175
194
|
return {
|
|
176
195
|
provider,
|
|
177
196
|
configured: true,
|
|
@@ -289,9 +308,28 @@ export async function handleAddKey(
|
|
|
289
308
|
provider = PROVIDER_REGISTRY[idx];
|
|
290
309
|
}
|
|
291
310
|
|
|
292
|
-
|
|
293
|
-
if (
|
|
294
|
-
|
|
311
|
+
const authMode = getProviderAuthMode(provider);
|
|
312
|
+
if (authMode === "externalCli") {
|
|
313
|
+
ctx.ui.notify(
|
|
314
|
+
`${provider.label} is authenticated by its own local CLI. ` +
|
|
315
|
+
`Sign in with that CLI first, then run /login to activate it in GSD.`,
|
|
316
|
+
"info",
|
|
317
|
+
);
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (authMode === "cloudIdentity") {
|
|
322
|
+
ctx.ui.notify(
|
|
323
|
+
`${provider.label} uses cloud identity credentials. Configure the provider's cloud CLI or environment, then restart GSD.`,
|
|
324
|
+
"info",
|
|
325
|
+
);
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (supportsBrowserOAuth(provider)) {
|
|
330
|
+
const methods = supportsStoredApiKey(provider)
|
|
331
|
+
? ["API token/key", "Browser login (OAuth)"]
|
|
332
|
+
: ["Browser login (OAuth)"];
|
|
295
333
|
const method = await ctx.ui.select(
|
|
296
334
|
`${provider.label} — how do you want to authenticate?`,
|
|
297
335
|
methods,
|
|
@@ -308,6 +346,11 @@ export async function handleAddKey(
|
|
|
308
346
|
}
|
|
309
347
|
}
|
|
310
348
|
|
|
349
|
+
if (!supportsStoredApiKey(provider)) {
|
|
350
|
+
ctx.ui.notify(`${provider.label} does not accept a GSD-stored API key. Use /login.`, "info");
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
|
|
311
354
|
// API key input
|
|
312
355
|
const input = await ctx.ui.input(
|
|
313
356
|
`API key for ${provider.label}:`,
|
|
@@ -387,7 +430,7 @@ export async function handleRemoveKey(
|
|
|
387
430
|
|
|
388
431
|
// Multi-key handling
|
|
389
432
|
if (creds.length > 1) {
|
|
390
|
-
const options = creds.map((c, i) => `[${i + 1}] ${describeCredential(c)}`);
|
|
433
|
+
const options = creds.map((c, i) => `[${i + 1}] ${describeCredential(c, provider)}`);
|
|
391
434
|
options.push("Remove all");
|
|
392
435
|
|
|
393
436
|
const choice = await ctx.ui.select(
|
|
@@ -411,7 +454,7 @@ export async function handleRemoveKey(
|
|
|
411
454
|
} else {
|
|
412
455
|
const confirmed = await ctx.ui.confirm(
|
|
413
456
|
"Remove key?",
|
|
414
|
-
`Remove ${describeCredential(creds[0])} for ${provider.label}?`,
|
|
457
|
+
`Remove ${describeCredential(creds[0], provider)} for ${provider.label}?`,
|
|
415
458
|
);
|
|
416
459
|
if (!confirmed) return false;
|
|
417
460
|
auth.remove(provider.id);
|
|
@@ -6,37 +6,84 @@ import { resolveModelMcpConfig } from "./preferences-mcp.js";
|
|
|
6
6
|
|
|
7
7
|
interface McpJsonFile {
|
|
8
8
|
mcpServers?: Record<string, unknown>;
|
|
9
|
+
servers?: Record<string, unknown>;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
interface ClaudeSettingsFile {
|
|
12
13
|
mcpServers?: Record<string, unknown>;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
interface DiscoveredMcpServer {
|
|
17
|
+
name: string;
|
|
18
|
+
config: unknown;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
22
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function readJsonFile(path: string, ignoreParseErrors = false): unknown | undefined {
|
|
26
|
+
if (!existsSync(path)) return undefined;
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(readFileSync(path, "utf-8")) as unknown;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
if (!ignoreParseErrors) throw err;
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function collectServerEntries(servers: unknown): DiscoveredMcpServer[] {
|
|
36
|
+
if (!isRecord(servers)) return [];
|
|
37
|
+
return Object.entries(servers).map(([name, config]) => ({ name, config }));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function discoverMcpServers(projectDir: string): DiscoveredMcpServer[] {
|
|
16
41
|
const mcpJsonPath = resolve(projectDir, ".mcp.json");
|
|
17
42
|
const settingsPath = resolve(projectDir, ".claude", "settings.json");
|
|
18
43
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
44
|
+
const mcpJson = readJsonFile(mcpJsonPath) as McpJsonFile | undefined;
|
|
45
|
+
const settings = readJsonFile(settingsPath, true) as ClaudeSettingsFile | undefined;
|
|
46
|
+
|
|
47
|
+
const seen = new Set<string>();
|
|
48
|
+
const discovered: DiscoveredMcpServer[] = [];
|
|
49
|
+
for (const entry of [
|
|
50
|
+
...collectServerEntries(mcpJson?.mcpServers),
|
|
51
|
+
...collectServerEntries(mcpJson?.servers),
|
|
52
|
+
...collectServerEntries(settings?.mcpServers),
|
|
53
|
+
]) {
|
|
54
|
+
if (seen.has(entry.name)) continue;
|
|
55
|
+
seen.add(entry.name);
|
|
56
|
+
discovered.push(entry);
|
|
24
57
|
}
|
|
58
|
+
return discovered;
|
|
59
|
+
}
|
|
25
60
|
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
61
|
+
function isWorkflowMcpServerConfig(config: unknown): boolean {
|
|
62
|
+
if (!isRecord(config)) return false;
|
|
63
|
+
const env = config.env;
|
|
64
|
+
if (isRecord(env)) {
|
|
65
|
+
if (
|
|
66
|
+
typeof env.GSD_WORKFLOW_PROJECT_ROOT === "string"
|
|
67
|
+
|| typeof env.GSD_WORKFLOW_EXECUTORS_MODULE === "string"
|
|
68
|
+
|| typeof env.GSD_WORKFLOW_WRITE_GATE_MODULE === "string"
|
|
69
|
+
|| typeof env.GSD_PERSIST_WRITE_GATE_STATE === "string"
|
|
70
|
+
) {
|
|
71
|
+
return true;
|
|
36
72
|
}
|
|
37
73
|
}
|
|
38
74
|
|
|
39
|
-
|
|
75
|
+
const command = typeof config.command === "string" ? config.command : "";
|
|
76
|
+
if (command.includes("gsd-mcp-server")) return true;
|
|
77
|
+
const args = Array.isArray(config.args) ? config.args.filter((arg): arg is string => typeof arg === "string") : [];
|
|
78
|
+
return args.some((arg) => arg.includes("gsd-mcp-server") || arg.includes("packages/mcp-server"));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function discoverWorkflowMcpServerName(projectDir: string): string | undefined {
|
|
82
|
+
return discoverMcpServers(projectDir).find((server) => isWorkflowMcpServerConfig(server.config))?.name;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function discoverMcpServerNames(projectDir: string): string[] {
|
|
86
|
+
return discoverMcpServers(projectDir).map((server) => server.name);
|
|
40
87
|
}
|
|
41
88
|
|
|
42
89
|
export function computeMcpDisallowedTools(
|
|
@@ -21,6 +21,11 @@ export interface EnsureProjectWorkflowMcpConfigResult {
|
|
|
21
21
|
status: "created" | "updated" | "unchanged";
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
interface ProjectWorkflowMcpServerSpec {
|
|
25
|
+
serverName: string;
|
|
26
|
+
server: ProjectMcpServerConfig;
|
|
27
|
+
}
|
|
28
|
+
|
|
24
29
|
interface McpConfigFile {
|
|
25
30
|
mcpServers?: Record<string, ProjectMcpServerConfig>;
|
|
26
31
|
servers?: Record<string, ProjectMcpServerConfig>;
|
|
@@ -48,6 +53,13 @@ export function buildProjectWorkflowMcpServerConfig(
|
|
|
48
53
|
projectRoot: string,
|
|
49
54
|
env: NodeJS.ProcessEnv = process.env,
|
|
50
55
|
): ProjectMcpServerConfig {
|
|
56
|
+
return buildProjectWorkflowMcpServerSpec(projectRoot, env).server;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function buildProjectWorkflowMcpServerSpec(
|
|
60
|
+
projectRoot: string,
|
|
61
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
62
|
+
): ProjectWorkflowMcpServerSpec {
|
|
51
63
|
const resolvedProjectRoot = resolve(projectRoot);
|
|
52
64
|
const gsdCliPath = resolveBundledGsdCliPath(env);
|
|
53
65
|
const launch = detectWorkflowMcpLaunchConfig(resolvedProjectRoot, {
|
|
@@ -62,10 +74,13 @@ export function buildProjectWorkflowMcpServerConfig(
|
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
return {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
serverName: launch.name || GSD_WORKFLOW_MCP_SERVER_NAME,
|
|
78
|
+
server: {
|
|
79
|
+
command: launch.command,
|
|
80
|
+
...(launch.args && launch.args.length > 0 ? { args: launch.args } : {}),
|
|
81
|
+
...(launch.cwd ? { cwd: launch.cwd } : {}),
|
|
82
|
+
...(launch.env ? { env: launch.env } : {}),
|
|
83
|
+
},
|
|
69
84
|
};
|
|
70
85
|
}
|
|
71
86
|
|
|
@@ -92,23 +107,23 @@ export function ensureProjectWorkflowMcpConfig(
|
|
|
92
107
|
|
|
93
108
|
const configPath = resolve(resolvedProjectRoot, ".mcp.json");
|
|
94
109
|
const existing = readExistingConfig(configPath);
|
|
95
|
-
const desiredServer =
|
|
110
|
+
const { serverName, server: desiredServer } = buildProjectWorkflowMcpServerSpec(resolvedProjectRoot, env);
|
|
96
111
|
const previousServers = existing.mcpServers ?? {};
|
|
97
112
|
const nextServers = {
|
|
98
113
|
...previousServers,
|
|
99
|
-
[
|
|
114
|
+
[serverName]: desiredServer,
|
|
100
115
|
};
|
|
101
116
|
|
|
102
117
|
const alreadyPresent = existsSync(configPath);
|
|
103
118
|
const unchanged =
|
|
104
|
-
JSON.stringify(previousServers[
|
|
119
|
+
JSON.stringify(previousServers[serverName] ?? null)
|
|
105
120
|
=== JSON.stringify(desiredServer)
|
|
106
121
|
&& existing.mcpServers !== undefined;
|
|
107
122
|
|
|
108
123
|
if (unchanged) {
|
|
109
124
|
return {
|
|
110
125
|
configPath,
|
|
111
|
-
serverName
|
|
126
|
+
serverName,
|
|
112
127
|
status: "unchanged",
|
|
113
128
|
};
|
|
114
129
|
}
|
|
@@ -122,7 +137,7 @@ export function ensureProjectWorkflowMcpConfig(
|
|
|
122
137
|
|
|
123
138
|
return {
|
|
124
139
|
configPath,
|
|
125
|
-
serverName
|
|
140
|
+
serverName,
|
|
126
141
|
status: alreadyPresent ? "updated" : "created",
|
|
127
142
|
};
|
|
128
143
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
getMilestoneSlices,
|
|
7
7
|
getSliceTasks,
|
|
8
8
|
isDbAvailable,
|
|
9
|
+
refreshOpenDatabaseFromDisk,
|
|
9
10
|
} from "./gsd-db.js";
|
|
10
11
|
import { parsePlan, parseRoadmap } from "./parsers-legacy.js";
|
|
11
12
|
import {
|
|
@@ -100,6 +101,11 @@ export async function checkMarkdownHierarchyAgainstDb(
|
|
|
100
101
|
throw new Error(`failed to open or create the GSD database at ${basePath}`);
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
// The markdown projections may have just been written by a workflow/MCP
|
|
105
|
+
// server in another process. Reopen before comparing so startup does not
|
|
106
|
+
// warn from a stale long-lived SQLite handle.
|
|
107
|
+
refreshOpenDatabaseFromDisk();
|
|
108
|
+
|
|
103
109
|
const beforeDb = countDbHierarchy();
|
|
104
110
|
if (sameCounts(markdown, beforeDb)) {
|
|
105
111
|
return { action: "none", reason: "in-sync", markdown, beforeDb, afterDb: beforeDb };
|
|
@@ -162,6 +162,8 @@ export function discardMilestone(basePath: string, milestoneId: string): boolean
|
|
|
162
162
|
} catch (err) {
|
|
163
163
|
logWarning("engine", `discardMilestone DB cleanup failed for ${milestoneId}: ${(err as Error).message}`);
|
|
164
164
|
}
|
|
165
|
+
} else {
|
|
166
|
+
logWarning("engine", `discardMilestone DB cleanup skipped for ${milestoneId}: database unavailable`);
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
invalidateAllCaches();
|