@opengsd/gsd-pi 1.0.2-dev.e9a1b49 → 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 +36 -55
- 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-post-create-hook.js +117 -0
- 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/dist/worktree-cli.d.ts +0 -2
- package/dist/worktree-cli.js +21 -9
- package/package.json +5 -2
- package/packages/cloud-mcp-gateway/bin/gsd-cloud-mcp-gateway.js +14 -0
- package/packages/cloud-mcp-gateway/package.json +4 -3
- 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/bin/gsd-mcp-server.js +14 -0
- 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 +5 -4
- 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/bin/pi-ai.js +14 -0
- 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 +73 -226
- 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 +3 -2
- 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/deps.js +10 -0
- 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 +47 -57
- 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-post-create-hook.test.ts +141 -1
- 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-post-create-hook.ts +127 -0
- 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/tsconfig.extensions.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
import type { ExtensionContext } from "@gsd/pi-coding-agent";
|
|
12
12
|
import { type Theme } from "@gsd/pi-coding-agent";
|
|
13
13
|
import { Key, matchesKey, truncateToWidth, type TUI } from "@gsd/pi-tui";
|
|
14
|
-
import { makeUI } from "../shared/tui.js";
|
|
15
14
|
import { GLYPH } from "../shared/mod.js";
|
|
16
15
|
import { validateQueueOrder, type DependencyValidation } from "./queue-order.js";
|
|
16
|
+
import { renderDialogFrame, renderKeyHints } from "./tui/render-kit.js";
|
|
17
17
|
|
|
18
18
|
export interface ReorderItem {
|
|
19
19
|
id: string;
|
|
@@ -45,6 +45,7 @@ export async function showQueueReorder(
|
|
|
45
45
|
let grabbed = false;
|
|
46
46
|
let scrollOffset = 0;
|
|
47
47
|
let cachedLines: string[] | undefined;
|
|
48
|
+
let cachedWidth: number | undefined;
|
|
48
49
|
let validation: DependencyValidation;
|
|
49
50
|
|
|
50
51
|
// Mutable deps map — tracks removals during this session
|
|
@@ -66,6 +67,7 @@ export async function showQueueReorder(
|
|
|
66
67
|
|
|
67
68
|
function refresh() {
|
|
68
69
|
cachedLines = undefined;
|
|
70
|
+
cachedWidth = undefined;
|
|
69
71
|
tui.requestRender();
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -151,17 +153,15 @@ export async function showQueueReorder(
|
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
function render(width: number): string[] {
|
|
154
|
-
if (cachedLines) return cachedLines;
|
|
156
|
+
if (cachedLines && cachedWidth === width) return cachedLines;
|
|
155
157
|
|
|
156
|
-
const
|
|
158
|
+
const contentWidth = Math.max(1, width - 4);
|
|
157
159
|
const lines: string[] = [];
|
|
158
160
|
const queueRows: string[] = [];
|
|
159
|
-
const
|
|
160
|
-
const add = (s: string) => truncateToWidth(s, width);
|
|
161
|
+
const add = (s: string) => truncateToWidth(s, contentWidth);
|
|
161
162
|
let cursorQueueRow = 0;
|
|
162
163
|
|
|
163
|
-
const headerText = grabbed ? "
|
|
164
|
-
push(ui.bar(), ui.blank(), ui.header(headerText), ui.blank());
|
|
164
|
+
const headerText = grabbed ? "Queue Reorder - Moving Item" : "Queue Reorder";
|
|
165
165
|
|
|
166
166
|
// Completed milestones (dimmed)
|
|
167
167
|
if (completed.length > 0) {
|
|
@@ -170,7 +170,7 @@ export async function showQueueReorder(
|
|
|
170
170
|
const label = m.title && m.title !== m.id ? `${m.id} ${m.title}` : m.id;
|
|
171
171
|
lines.push(add(` ${theme.fg("dim", `${GLYPH.statusDone} ${label}`)}`));
|
|
172
172
|
}
|
|
173
|
-
push(
|
|
173
|
+
lines.push("");
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// Pending milestones
|
|
@@ -223,7 +223,7 @@ export async function showQueueReorder(
|
|
|
223
223
|
// Removed deps feedback
|
|
224
224
|
const trailingLines: string[] = [];
|
|
225
225
|
if (removedDeps.length > 0) {
|
|
226
|
-
trailingLines.push(
|
|
226
|
+
trailingLines.push("");
|
|
227
227
|
for (const r of removedDeps) {
|
|
228
228
|
trailingLines.push(add(` ${theme.fg("success", `${GLYPH.statusDone} Removed: ${r.milestone} depends_on ${r.dep}`)}`));
|
|
229
229
|
}
|
|
@@ -232,12 +232,10 @@ export async function showQueueReorder(
|
|
|
232
232
|
// Circular warning
|
|
233
233
|
const circ = validation.violations.find(v => v.type === 'circular');
|
|
234
234
|
if (circ) {
|
|
235
|
-
trailingLines.push(
|
|
235
|
+
trailingLines.push("");
|
|
236
236
|
trailingLines.push(add(` ${theme.fg("error", `${GLYPH.statusWarning} ${circ.message}`)}`));
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
trailingLines.push(...ui.blank());
|
|
240
|
-
|
|
241
239
|
// Hints — context-sensitive based on grab state
|
|
242
240
|
const hints: string[] = [];
|
|
243
241
|
if (grabbed) {
|
|
@@ -256,10 +254,9 @@ export async function showQueueReorder(
|
|
|
256
254
|
}
|
|
257
255
|
hints.push("esc");
|
|
258
256
|
|
|
259
|
-
trailingLines.push(...ui.hints(hints), ...ui.bar());
|
|
260
|
-
|
|
261
257
|
const maxOverlayRows = Math.max(10, process.stdout.rows ? Math.floor(process.stdout.rows * 0.8) : 24);
|
|
262
|
-
const
|
|
258
|
+
const frameRows = 4;
|
|
259
|
+
const availableQueueRows = Math.max(1, maxOverlayRows - frameRows - lines.length - trailingLines.length);
|
|
263
260
|
const maxScroll = Math.max(0, queueRows.length - availableQueueRows);
|
|
264
261
|
if (cursorQueueRow < scrollOffset) {
|
|
265
262
|
scrollOffset = cursorQueueRow;
|
|
@@ -268,13 +265,25 @@ export async function showQueueReorder(
|
|
|
268
265
|
}
|
|
269
266
|
scrollOffset = Math.min(Math.max(scrollOffset, 0), maxScroll);
|
|
270
267
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
const queueStartRow = lines.length;
|
|
269
|
+
const visibleQueueRows = queueRows.slice(scrollOffset, scrollOffset + availableQueueRows);
|
|
270
|
+
lines.push(...visibleQueueRows, ...trailingLines);
|
|
271
|
+
|
|
272
|
+
cachedLines = renderDialogFrame(theme, headerText, lines, width, {
|
|
273
|
+
footer: renderKeyHints(theme, hints, contentWidth),
|
|
274
|
+
scroll: {
|
|
275
|
+
offset: scrollOffset,
|
|
276
|
+
visibleRows: availableQueueRows,
|
|
277
|
+
totalRows: queueRows.length,
|
|
278
|
+
trackOffset: queueStartRow,
|
|
279
|
+
trackRows: visibleQueueRows.length,
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
cachedWidth = width;
|
|
283
|
+
return cachedLines;
|
|
275
284
|
}
|
|
276
285
|
|
|
277
|
-
return { render, invalidate: () => { cachedLines = undefined; }, handleInput };
|
|
286
|
+
return { render, invalidate: () => { cachedLines = undefined; cachedWidth = undefined; }, handleInput };
|
|
278
287
|
}, {
|
|
279
288
|
overlay: true,
|
|
280
289
|
overlayOptions: { width: "70%", minWidth: 50, maxHeight: "80%", anchor: "center" },
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
resolveExternalStateProjectGsdFromWorktreePath,
|
|
17
17
|
resolveExternalStateProjectIdentityFromWorktreePath,
|
|
18
18
|
} from "./worktree-root.js";
|
|
19
|
+
import { logWarning } from "./workflow-logger.js";
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
// ─── Repo Metadata ───────────────────────────────────────────────────────────
|
|
@@ -188,10 +189,12 @@ function isProjectGsd(gsdPath: string): boolean {
|
|
|
188
189
|
// ─── Repo Identity ──────────────────────────────────────────────────────────
|
|
189
190
|
|
|
190
191
|
/**
|
|
191
|
-
* Get the git remote URL for "origin", or
|
|
192
|
+
* Get the git remote URL for "origin", or:
|
|
193
|
+
* - "" when git cleanly reports no remote
|
|
194
|
+
* - null when git command failed (transient/unknown)
|
|
192
195
|
* Uses `git config` rather than `git remote get-url` for broader compat.
|
|
193
196
|
*/
|
|
194
|
-
function getRemoteUrl(basePath: string): string {
|
|
197
|
+
function getRemoteUrl(basePath: string): string | null {
|
|
195
198
|
try {
|
|
196
199
|
return execFileSync("git", ["config", "--get", "remote.origin.url"], {
|
|
197
200
|
cwd: basePath,
|
|
@@ -199,8 +202,24 @@ function getRemoteUrl(basePath: string): string {
|
|
|
199
202
|
stdio: ["ignore", "pipe", "ignore"],
|
|
200
203
|
timeout: 5_000,
|
|
201
204
|
}).trim();
|
|
202
|
-
} catch {
|
|
203
|
-
|
|
205
|
+
} catch (error) {
|
|
206
|
+
const status = typeof error === "object" && error !== null && "status" in error
|
|
207
|
+
? (error as { status?: number }).status
|
|
208
|
+
: undefined;
|
|
209
|
+
if (status === 1) {
|
|
210
|
+
try {
|
|
211
|
+
if (existsSync(join(resolveGitCommonDir(basePath), "config"))) return "";
|
|
212
|
+
} catch {
|
|
213
|
+
// Fall through to report unknown git/config failures.
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Keep transient git failures distinct from "no remote configured".
|
|
218
|
+
logWarning("state", "repo-identity: failed to resolve remote.origin.url", {
|
|
219
|
+
basePath,
|
|
220
|
+
error: String(error),
|
|
221
|
+
});
|
|
222
|
+
return null;
|
|
204
223
|
}
|
|
205
224
|
}
|
|
206
225
|
|
|
@@ -300,6 +319,15 @@ export function repoIdentity(basePath: string): string {
|
|
|
300
319
|
// This makes moves transparent for repos with remotes (#2750).
|
|
301
320
|
return createHash("sha256").update(remoteUrl).digest("hex").slice(0, 12);
|
|
302
321
|
}
|
|
322
|
+
if (remoteUrl === null) {
|
|
323
|
+
// Unknown remote status (transient git failure): prefer persisted identity.
|
|
324
|
+
const markerRoot = resolveGitRoot(basePath);
|
|
325
|
+
const markerId = readGsdIdMarker(markerRoot);
|
|
326
|
+
if (markerId) {
|
|
327
|
+
const markerPath = join(process.env.GSD_STATE_DIR || gsdHome(), "projects", markerId);
|
|
328
|
+
if (hasProjectState(markerPath) || readRepoMeta(markerPath)) return markerId;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
303
331
|
// Local-only repo: include git root since there's no remote to anchor identity.
|
|
304
332
|
const root = resolveGitRoot(basePath);
|
|
305
333
|
const input = `\n${root}`;
|
|
@@ -315,8 +343,7 @@ export function repoIdentity(basePath: string): string {
|
|
|
315
343
|
* otherwise `~/.gsd/projects/<hash>`.
|
|
316
344
|
*/
|
|
317
345
|
export function externalGsdRoot(basePath: string): string {
|
|
318
|
-
|
|
319
|
-
return join(base, "projects", repoIdentity(basePath));
|
|
346
|
+
return resolveExternalPathWithRecovery(basePath).path;
|
|
320
347
|
}
|
|
321
348
|
|
|
322
349
|
/**
|
|
@@ -495,6 +522,7 @@ function resolveExternalPathWithRecovery(projectPath: string): { path: string; i
|
|
|
495
522
|
}
|
|
496
523
|
// Clean up old directory after successful migration.
|
|
497
524
|
try { rmSync(markerPath, { recursive: true, force: true }); } catch { /* non-fatal */ }
|
|
525
|
+
writeGsdIdMarker(projectPath, computedId);
|
|
498
526
|
} catch {
|
|
499
527
|
// If migration fails, just point at the old directory.
|
|
500
528
|
return { path: markerPath, identity: markerId };
|
|
@@ -596,7 +624,7 @@ function ensureGsdSymlinkCore(projectPath: string): { path: string; identity: st
|
|
|
596
624
|
// Write repo metadata once so cleanup commands can identify this directory later.
|
|
597
625
|
// Skip refresh for external-state worktrees — parent store already has metadata.
|
|
598
626
|
if (!(isGsdWorktreePath(projectPath) && resolveExternalStateProjectGsdFromWorktreePath(projectPath))) {
|
|
599
|
-
writeRepoMeta(externalPath, getRemoteUrl(projectPath), resolveGitRoot(projectPath));
|
|
627
|
+
writeRepoMeta(externalPath, getRemoteUrl(projectPath) ?? "", resolveGitRoot(projectPath));
|
|
600
628
|
}
|
|
601
629
|
|
|
602
630
|
const replaceWithSymlink = (): { path: string; identity: string } => {
|
|
@@ -77,7 +77,9 @@ export function createRepositoryRegistry(
|
|
|
77
77
|
workspacePrefs?: WorkspacePreferences,
|
|
78
78
|
): RepositoryRegistry {
|
|
79
79
|
const contract = resolveGsdPathContract(basePath);
|
|
80
|
-
const projectRoot =
|
|
80
|
+
const projectRoot = contract.isWorktree
|
|
81
|
+
? resolveGitWorkingTreeRoot(contract.workRoot) ?? contract.projectRoot
|
|
82
|
+
: contract.projectRoot;
|
|
81
83
|
const mode = workspacePrefs?.mode ?? "project";
|
|
82
84
|
const repoMap = new Map<string, RegisteredRepository>();
|
|
83
85
|
|
|
@@ -51,15 +51,15 @@ export interface FileEditEvidence {
|
|
|
51
51
|
export type EvidenceEntry = BashEvidence | FileWriteEvidence | FileEditEvidence;
|
|
52
52
|
|
|
53
53
|
const EXECUTION_TOOL_NAMES = new Set([
|
|
54
|
-
"bash",
|
|
55
|
-
"Bash",
|
|
56
|
-
"PowerShell",
|
|
57
54
|
"async_bash",
|
|
55
|
+
"bash",
|
|
56
|
+
"exec_command",
|
|
57
|
+
"functions.exec_command",
|
|
58
58
|
"gsd_exec",
|
|
59
59
|
"gsd_exec_search",
|
|
60
|
-
"
|
|
61
|
-
"mcp__gsd-workflow__gsd_exec_search",
|
|
60
|
+
"powershell",
|
|
62
61
|
]);
|
|
62
|
+
const MCP_EXECUTION_TOOL_RE = /^mcp__.+__gsd_exec(?:_search)?$/;
|
|
63
63
|
|
|
64
64
|
// ─── Module State ───────────────────────────────────────────────────────────
|
|
65
65
|
|
|
@@ -89,6 +89,13 @@ export function getFilePaths(): string[] {
|
|
|
89
89
|
.map(e => e.path);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
/** True when a tool name represents a shell/command execution surface. */
|
|
93
|
+
export function isExecutionToolName(name: unknown): boolean {
|
|
94
|
+
if (typeof name !== "string") return false;
|
|
95
|
+
const normalized = name.trim().toLowerCase();
|
|
96
|
+
return EXECUTION_TOOL_NAMES.has(normalized) || MCP_EXECUTION_TOOL_RE.test(normalized);
|
|
97
|
+
}
|
|
98
|
+
|
|
92
99
|
// ─── Persistence (Bug #4385 — evidence must survive session restarts) ────────
|
|
93
100
|
|
|
94
101
|
/**
|
|
@@ -199,7 +206,7 @@ export function clearEvidenceFromDisk(
|
|
|
199
206
|
* Exit codes and output are filled in by recordToolResult after execution.
|
|
200
207
|
*/
|
|
201
208
|
export function recordToolCall(toolCallId: string, toolName: string, input: Record<string, unknown>): void {
|
|
202
|
-
if (
|
|
209
|
+
if (isExecutionToolName(toolName)) {
|
|
203
210
|
unitEvidence.push({
|
|
204
211
|
kind: "bash",
|
|
205
212
|
toolCallId,
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill activation and discovery prompt blocks for GSD auto-mode units.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { basename } from "node:path";
|
|
6
|
+
import type { Skill } from "@gsd/pi-coding-agent";
|
|
7
|
+
import { parseTaskPlanFile } from "./files.js";
|
|
8
|
+
import {
|
|
9
|
+
loadEffectiveGSDPreferences,
|
|
10
|
+
resolveAllSkillReferences,
|
|
11
|
+
resolveSkillDiscoveryMode,
|
|
12
|
+
} from "./preferences.js";
|
|
13
|
+
import type { GSDPreferences } from "./preferences.js";
|
|
14
|
+
import { filterSkillsByManifest, resolveSkillManifest, warnIfManifestHasMissingSkills } from "./skill-manifest.js";
|
|
15
|
+
import { getInstalledSkills } from "./skills.js";
|
|
16
|
+
import { logWarning } from "./workflow-logger.js";
|
|
17
|
+
|
|
18
|
+
function normalizeSkillReference(ref: string): string {
|
|
19
|
+
const normalized = ref.replace(/\\/g, "/").trim();
|
|
20
|
+
const base = basename(normalized).replace(/\.md$/i, "");
|
|
21
|
+
const name = /^SKILL$/i.test(base)
|
|
22
|
+
? basename(normalized.replace(/\/SKILL(?:\.md)?$/i, ""))
|
|
23
|
+
: base;
|
|
24
|
+
return name.trim().toLowerCase();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function tokenizeSkillContext(...parts: Array<string | null | undefined>): Set<string> {
|
|
28
|
+
const tokens = new Set<string>();
|
|
29
|
+
const addVariants = (raw: string) => {
|
|
30
|
+
const value = raw.trim().toLowerCase();
|
|
31
|
+
if (!value || value.length < 2) return;
|
|
32
|
+
tokens.add(value);
|
|
33
|
+
tokens.add(value.replace(/[-_]+/g, " "));
|
|
34
|
+
tokens.add(value.replace(/\s+/g, "-"));
|
|
35
|
+
tokens.add(value.replace(/\s+/g, ""));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
for (const part of parts) {
|
|
39
|
+
if (!part) continue;
|
|
40
|
+
const text = part.toLowerCase();
|
|
41
|
+
const phraseMatches = text.match(/[a-z0-9][a-z0-9+.#/_-]{1,}/g) ?? [];
|
|
42
|
+
for (const match of phraseMatches) {
|
|
43
|
+
addVariants(match);
|
|
44
|
+
for (const piece of match.split(/[^a-z0-9+.#]+/g)) {
|
|
45
|
+
if (piece.length >= 3) addVariants(piece);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return tokens;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function skillMatchesContext(skill: Skill, contextTokens: Set<string>): boolean {
|
|
54
|
+
const haystacks = [
|
|
55
|
+
skill.name.toLowerCase(),
|
|
56
|
+
skill.name.toLowerCase().replace(/[-_]+/g, " "),
|
|
57
|
+
skill.description.toLowerCase(),
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
return [...contextTokens].some(token =>
|
|
61
|
+
token.length >= 3 && haystacks.some(haystack => haystack.includes(token)),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function resolvePreferenceSkillNames(refs: string[], base: string): string[] {
|
|
66
|
+
if (refs.length === 0) return [];
|
|
67
|
+
const prefs: GSDPreferences = { always_use_skills: refs };
|
|
68
|
+
const report = resolveAllSkillReferences(prefs, base);
|
|
69
|
+
return refs.map(ref => {
|
|
70
|
+
const resolution = report.resolutions.get(ref);
|
|
71
|
+
return normalizeSkillReference(resolution?.resolvedPath ?? ref);
|
|
72
|
+
}).filter(Boolean);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function ruleMatchesContext(when: string, contextTokens: Set<string>): boolean {
|
|
76
|
+
const whenTokens = tokenizeSkillContext(when);
|
|
77
|
+
return [...whenTokens].some(token =>
|
|
78
|
+
contextTokens.has(token) || [...contextTokens].some(ctx => ctx.includes(token) || token.includes(ctx)),
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function resolveSkillRuleMatches(
|
|
83
|
+
prefs: GSDPreferences | undefined,
|
|
84
|
+
contextTokens: Set<string>,
|
|
85
|
+
base: string,
|
|
86
|
+
): { include: string[]; avoid: string[] } {
|
|
87
|
+
if (!prefs?.skill_rules?.length) return { include: [], avoid: [] };
|
|
88
|
+
|
|
89
|
+
const include: string[] = [];
|
|
90
|
+
const avoid: string[] = [];
|
|
91
|
+
for (const rule of prefs.skill_rules) {
|
|
92
|
+
if (!ruleMatchesContext(rule.when, contextTokens)) continue;
|
|
93
|
+
include.push(...resolvePreferenceSkillNames([...(rule.use ?? []), ...(rule.prefer ?? [])], base));
|
|
94
|
+
avoid.push(...resolvePreferenceSkillNames(rule.avoid ?? [], base));
|
|
95
|
+
}
|
|
96
|
+
return { include, avoid };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function resolvePreferredSkillNames(
|
|
100
|
+
prefs: GSDPreferences | undefined,
|
|
101
|
+
visibleSkills: Skill[],
|
|
102
|
+
contextTokens: Set<string>,
|
|
103
|
+
base: string,
|
|
104
|
+
): string[] {
|
|
105
|
+
if (!prefs?.prefer_skills?.length) return [];
|
|
106
|
+
const preferred = new Set(resolvePreferenceSkillNames(prefs.prefer_skills, base));
|
|
107
|
+
return visibleSkills
|
|
108
|
+
.filter(skill => preferred.has(normalizeSkillReference(skill.name)) && skillMatchesContext(skill, contextTokens))
|
|
109
|
+
.map(skill => normalizeSkillReference(skill.name));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Skill names must be lowercase alphanumeric with hyphens — reject anything else
|
|
113
|
+
* to prevent prompt injection via crafted directory names. */
|
|
114
|
+
const SAFE_SKILL_NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
115
|
+
|
|
116
|
+
function formatSkillActivationBlock(skillNames: string[]): string {
|
|
117
|
+
const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
|
|
118
|
+
if (safe.length === 0) return "";
|
|
119
|
+
// Use explicit parameter syntax so LLMs pass { skill: "..." } instead of { name: "..." }.
|
|
120
|
+
// The function-call-like syntax `Skill('name')` led LLMs to infer a positional
|
|
121
|
+
// parameter name, causing tool validation failures — see #2224.
|
|
122
|
+
const calls = safe.map(name => `Call Skill({ skill: '${name}' })`).join('. ');
|
|
123
|
+
return `<skill_activation>${calls}.</skill_activation>`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Manifest-driven recommendations block — informational only, does NOT
|
|
128
|
+
* auto-invoke. Lists per-unit-type skills that are installed but not already
|
|
129
|
+
* activated by explicit user intent (always_use_skills / prefer_skills /
|
|
130
|
+
* skill_rules / task-plan skills_used). Surfaces relevant skills to the
|
|
131
|
+
* model so they can be invoked when the model judges them useful.
|
|
132
|
+
*
|
|
133
|
+
* This is the additive complement to the existing activation directive:
|
|
134
|
+
* activation force-invokes (explicit intent), recommendations remind
|
|
135
|
+
* (manifest defaults). User intent is preserved as the stronger signal
|
|
136
|
+
* (RFC #4779 design principle); this block only adds visibility.
|
|
137
|
+
*/
|
|
138
|
+
function formatSkillRecommendationsBlock(unitType: string | undefined, skillNames: string[]): string {
|
|
139
|
+
if (!unitType) return "";
|
|
140
|
+
const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
|
|
141
|
+
if (safe.length === 0) return "";
|
|
142
|
+
return `<skill_recommendations unit="${unitType}">For this unit type, also consider invoking: ${safe.join(", ")}. Use Skill({ skill: 'name' }) when relevant — these are recommendations, not requirements.</skill_recommendations>`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function buildSkillActivationBlock(params: {
|
|
146
|
+
base: string;
|
|
147
|
+
milestoneId: string;
|
|
148
|
+
milestoneTitle?: string;
|
|
149
|
+
sliceId?: string;
|
|
150
|
+
sliceTitle?: string;
|
|
151
|
+
taskId?: string;
|
|
152
|
+
taskTitle?: string;
|
|
153
|
+
extraContext?: string[];
|
|
154
|
+
taskPlanContent?: string | null;
|
|
155
|
+
preferences?: GSDPreferences;
|
|
156
|
+
/**
|
|
157
|
+
* Unit type dispatching this prompt. When provided, skills are filtered
|
|
158
|
+
* through the per-unit-type manifest (see `skill-manifest.ts`). Unknown
|
|
159
|
+
* or omitted values retain the pre-manifest behavior (all skills eligible).
|
|
160
|
+
*/
|
|
161
|
+
unitType?: string;
|
|
162
|
+
/** Installed skills from resourceLoader; defaults to loader cache via skills facade. */
|
|
163
|
+
skills?: Skill[];
|
|
164
|
+
}): string {
|
|
165
|
+
const prefs = params.preferences ?? loadEffectiveGSDPreferences(params.base)?.preferences;
|
|
166
|
+
const contextTokens = tokenizeSkillContext(
|
|
167
|
+
params.milestoneId,
|
|
168
|
+
params.milestoneTitle,
|
|
169
|
+
params.sliceId,
|
|
170
|
+
params.sliceTitle,
|
|
171
|
+
params.taskId,
|
|
172
|
+
params.taskTitle,
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
const loaded = getInstalledSkills(params.skills).filter(skill => !skill.disableModelInvocation);
|
|
176
|
+
|
|
177
|
+
// Skill activation here is driven entirely by explicit sources
|
|
178
|
+
// (always_use_skills, prefer_skills, skill_rules, task-plan skills_used).
|
|
179
|
+
// Every match is an explicit user/project intent and must not be dropped
|
|
180
|
+
// by the unit-type manifest — user intent is stronger signal than
|
|
181
|
+
// defaults. The manifest's real home is the skill catalog rendering
|
|
182
|
+
// layer (pi-coding-agent `formatSkillsForPrompt`); that wiring is tracked
|
|
183
|
+
// as the "load-time short-circuit" follow-up to RFC #4779.
|
|
184
|
+
//
|
|
185
|
+
// `unitType` stays plumbed so the strict-mode warning can surface
|
|
186
|
+
// manifest entries that reference uninstalled skills, and so the
|
|
187
|
+
// activation-block site is ready to opt in once PR B lands.
|
|
188
|
+
const visibleSkills = loaded;
|
|
189
|
+
const manifestScopedSkills = filterSkillsByManifest(visibleSkills, params.unitType);
|
|
190
|
+
const installedNames = new Set(visibleSkills.map(skill => normalizeSkillReference(skill.name)));
|
|
191
|
+
warnIfManifestHasMissingSkills(params.unitType, installedNames);
|
|
192
|
+
const avoided = new Set(resolvePreferenceSkillNames(prefs?.avoid_skills ?? [], params.base));
|
|
193
|
+
const matched = new Set<string>();
|
|
194
|
+
|
|
195
|
+
for (const name of resolvePreferenceSkillNames(prefs?.always_use_skills ?? [], params.base)) {
|
|
196
|
+
matched.add(name);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const ruleMatches = resolveSkillRuleMatches(prefs, contextTokens, params.base);
|
|
200
|
+
for (const name of ruleMatches.include) matched.add(name);
|
|
201
|
+
for (const name of ruleMatches.avoid) avoided.add(name);
|
|
202
|
+
|
|
203
|
+
for (const name of resolvePreferredSkillNames(prefs, visibleSkills, contextTokens, params.base)) {
|
|
204
|
+
matched.add(name);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (params.taskPlanContent) {
|
|
208
|
+
try {
|
|
209
|
+
const taskPlan = parseTaskPlanFile(params.taskPlanContent);
|
|
210
|
+
for (const skillName of taskPlan.frontmatter.skills_used) {
|
|
211
|
+
matched.add(normalizeSkillReference(skillName));
|
|
212
|
+
}
|
|
213
|
+
} catch (err) {
|
|
214
|
+
logWarning("prompt", `parseTaskPlanFile failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Heuristic auto-match (gated on skill_discovery: "auto").
|
|
219
|
+
// For each installed skill, check if its name or description appears in the
|
|
220
|
+
// unit's context tokens (milestone/slice/task titles). Only consider skills
|
|
221
|
+
// already on the unit-type manifest allowlist — this keeps the heuristic
|
|
222
|
+
// narrow and avoids wildly off-topic activations.
|
|
223
|
+
// Users who set `skill_discovery: "off"` or "suggest" do not get
|
|
224
|
+
// auto-matched skills (the recommendations block still surfaces manifest
|
|
225
|
+
// skills passively); only "auto" actually adds them to the activation
|
|
226
|
+
// directive set. Default `skill_discovery` is "suggest", so this is opt-in.
|
|
227
|
+
if ((prefs?.skill_discovery ?? "suggest") === "auto") {
|
|
228
|
+
for (const skill of manifestScopedSkills) {
|
|
229
|
+
const normalized = normalizeSkillReference(skill.name);
|
|
230
|
+
if (matched.has(normalized) || avoided.has(normalized)) continue;
|
|
231
|
+
if (skillMatchesContext(skill, contextTokens)) {
|
|
232
|
+
matched.add(normalized);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const ordered = [...matched]
|
|
238
|
+
.filter(name => installedNames.has(name) && !avoided.has(name))
|
|
239
|
+
.sort();
|
|
240
|
+
const activationBlock = formatSkillActivationBlock(ordered);
|
|
241
|
+
|
|
242
|
+
// Omit recommendations when the system catalog is manifest-scoped for this
|
|
243
|
+
// unit — skill names are already listed in <available_skills>.
|
|
244
|
+
let recommendationsBlock = "";
|
|
245
|
+
if (resolveSkillManifest(params.unitType) === null) {
|
|
246
|
+
const matchedSet = new Set(ordered);
|
|
247
|
+
const recommendations = (resolveSkillManifest(params.unitType) ?? [])
|
|
248
|
+
.filter(name => installedNames.has(name) && !avoided.has(name) && !matchedSet.has(name))
|
|
249
|
+
.sort();
|
|
250
|
+
recommendationsBlock = formatSkillRecommendationsBlock(params.unitType, recommendations);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (!activationBlock && !recommendationsBlock) return "";
|
|
254
|
+
if (!activationBlock) return recommendationsBlock;
|
|
255
|
+
if (!recommendationsBlock) return activationBlock;
|
|
256
|
+
return `${activationBlock}\n${recommendationsBlock}`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Build the skill discovery template variables for research prompts.
|
|
261
|
+
* Returns { skillDiscoveryMode, skillDiscoveryInstructions } for template substitution.
|
|
262
|
+
*/
|
|
263
|
+
export function buildSkillDiscoveryVars(): { skillDiscoveryMode: string; skillDiscoveryInstructions: string } {
|
|
264
|
+
const mode = resolveSkillDiscoveryMode();
|
|
265
|
+
|
|
266
|
+
if (mode === "off") {
|
|
267
|
+
return {
|
|
268
|
+
skillDiscoveryMode: "off",
|
|
269
|
+
skillDiscoveryInstructions: " Skill discovery is disabled. Skip this step.",
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (mode === "suggest") {
|
|
274
|
+
return {
|
|
275
|
+
skillDiscoveryMode: mode,
|
|
276
|
+
skillDiscoveryInstructions: `
|
|
277
|
+
Check \`<available_skills>\` for installed skills matching core technologies. For gaps, run \`npx skills find "<technology>"\` and note promising install commands in your research output — do NOT install.`,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const autoInstall = mode === "auto";
|
|
282
|
+
const instructions = autoInstall
|
|
283
|
+
? `
|
|
284
|
+
Check \`<available_skills>\` first. For missing core-technology skills, run \`npx skills find "<technology>"\`, install relevant matches with \`npx skills add <owner/repo@skill> -g -y\`, and record them in "Skills Discovered".`
|
|
285
|
+
: `
|
|
286
|
+
Check \`<available_skills>\` first. For missing core-technology skills, run \`npx skills find "<technology>"\` and note install commands in your research output — do NOT install.`;
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
skillDiscoveryMode: mode,
|
|
290
|
+
skillDiscoveryInstructions: instructions,
|
|
291
|
+
};
|
|
292
|
+
}
|