gsd-pi 2.10.12 → 2.12.0
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/dist/bundled-extension-paths.d.ts +2 -0
- package/dist/bundled-extension-paths.js +10 -0
- package/dist/loader.js +45 -28
- package/dist/onboarding.js +100 -0
- package/dist/resource-loader.js +12 -3
- package/dist/resources/GSD-WORKFLOW.md +661 -0
- package/dist/resources/agents/researcher.md +29 -0
- package/dist/resources/agents/scout.md +56 -0
- package/dist/resources/agents/worker.md +31 -0
- package/dist/resources/extensions/ask-user-questions.ts +289 -0
- package/dist/resources/extensions/async-jobs/async-bash-tool.ts +211 -0
- package/dist/resources/extensions/async-jobs/await-tool.ts +101 -0
- package/dist/resources/extensions/async-jobs/cancel-job-tool.ts +34 -0
- package/dist/resources/extensions/async-jobs/index.ts +133 -0
- package/dist/resources/extensions/async-jobs/job-manager.ts +211 -0
- package/dist/resources/extensions/bg-shell/index.ts +3179 -0
- package/dist/resources/extensions/browser-tools/BROWSER-TOOLS-V2-PROPOSAL.md +1277 -0
- package/dist/resources/extensions/browser-tools/capture.ts +165 -0
- package/dist/resources/extensions/browser-tools/core.d.ts +205 -0
- package/dist/resources/extensions/browser-tools/core.js +1057 -0
- package/dist/resources/extensions/browser-tools/evaluate-helpers.ts +184 -0
- package/dist/resources/extensions/browser-tools/index.ts +51 -0
- package/dist/resources/extensions/browser-tools/lifecycle.ts +270 -0
- package/dist/resources/extensions/browser-tools/package.json +24 -0
- package/dist/resources/extensions/browser-tools/refs.ts +264 -0
- package/dist/resources/extensions/browser-tools/settle.ts +197 -0
- package/dist/resources/extensions/browser-tools/state.ts +408 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +652 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +614 -0
- package/dist/resources/extensions/browser-tools/tools/assertions.ts +342 -0
- package/dist/resources/extensions/browser-tools/tools/forms.ts +801 -0
- package/dist/resources/extensions/browser-tools/tools/inspection.ts +492 -0
- package/dist/resources/extensions/browser-tools/tools/intent.ts +614 -0
- package/dist/resources/extensions/browser-tools/tools/interaction.ts +865 -0
- package/dist/resources/extensions/browser-tools/tools/navigation.ts +232 -0
- package/dist/resources/extensions/browser-tools/tools/pages.ts +303 -0
- package/dist/resources/extensions/browser-tools/tools/refs.ts +541 -0
- package/dist/resources/extensions/browser-tools/tools/screenshot.ts +83 -0
- package/dist/resources/extensions/browser-tools/tools/session.ts +400 -0
- package/dist/resources/extensions/browser-tools/tools/wait.ts +247 -0
- package/dist/resources/extensions/browser-tools/utils.ts +660 -0
- package/dist/resources/extensions/context7/index.ts +428 -0
- package/dist/resources/extensions/context7/package.json +11 -0
- package/dist/resources/extensions/get-secrets-from-user.ts +625 -0
- package/dist/resources/extensions/google-search/index.ts +336 -0
- package/dist/resources/extensions/google-search/package.json +9 -0
- package/dist/resources/extensions/gsd/activity-log.ts +116 -0
- package/dist/resources/extensions/gsd/auto.ts +3732 -0
- package/dist/resources/extensions/gsd/commands.ts +544 -0
- package/dist/resources/extensions/gsd/crash-recovery.ts +105 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.ts +564 -0
- package/dist/resources/extensions/gsd/dispatch-guard.ts +78 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +278 -0
- package/dist/resources/extensions/gsd/doctor.ts +766 -0
- package/dist/resources/extensions/gsd/exit-command.ts +18 -0
- package/dist/resources/extensions/gsd/files.ts +857 -0
- package/dist/resources/extensions/gsd/git-service.ts +904 -0
- package/dist/resources/extensions/gsd/gitignore.ts +200 -0
- package/dist/resources/extensions/gsd/guided-flow.ts +1054 -0
- package/dist/resources/extensions/gsd/index.ts +735 -0
- package/dist/resources/extensions/gsd/metrics.ts +374 -0
- package/dist/resources/extensions/gsd/migrate/command.ts +218 -0
- package/dist/resources/extensions/gsd/migrate/index.ts +42 -0
- package/dist/resources/extensions/gsd/migrate/parser.ts +323 -0
- package/dist/resources/extensions/gsd/migrate/parsers.ts +624 -0
- package/dist/resources/extensions/gsd/migrate/preview.ts +48 -0
- package/dist/resources/extensions/gsd/migrate/transformer.ts +346 -0
- package/dist/resources/extensions/gsd/migrate/types.ts +370 -0
- package/dist/resources/extensions/gsd/migrate/validator.ts +55 -0
- package/dist/resources/extensions/gsd/migrate/writer.ts +539 -0
- package/dist/resources/extensions/gsd/native-git-bridge.ts +181 -0
- package/dist/resources/extensions/gsd/native-parser-bridge.ts +135 -0
- package/dist/resources/extensions/gsd/observability-validator.ts +408 -0
- package/dist/resources/extensions/gsd/package.json +11 -0
- package/dist/resources/extensions/gsd/paths.ts +339 -0
- package/dist/resources/extensions/gsd/post-unit-hooks.ts +449 -0
- package/dist/resources/extensions/gsd/preferences.ts +988 -0
- package/dist/resources/extensions/gsd/prompt-loader.ts +92 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +25 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +27 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +237 -0
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +29 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +63 -0
- package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +3 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +61 -0
- package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +3 -0
- package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +29 -0
- package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +3 -0
- package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +13 -0
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -0
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +78 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +55 -0
- package/dist/resources/extensions/gsd/prompts/queue.md +100 -0
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +48 -0
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +39 -0
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +37 -0
- package/dist/resources/extensions/gsd/prompts/research-slice.md +28 -0
- package/dist/resources/extensions/gsd/prompts/review-migration.md +66 -0
- package/dist/resources/extensions/gsd/prompts/run-uat.md +109 -0
- package/dist/resources/extensions/gsd/prompts/system.md +190 -0
- package/dist/resources/extensions/gsd/prompts/worktree-merge.md +123 -0
- package/dist/resources/extensions/gsd/roadmap-slices.ts +50 -0
- package/dist/resources/extensions/gsd/session-forensics.ts +500 -0
- package/dist/resources/extensions/gsd/skill-discovery.ts +137 -0
- package/dist/resources/extensions/gsd/state.ts +569 -0
- package/dist/resources/extensions/gsd/templates/context.md +76 -0
- package/dist/resources/extensions/gsd/templates/decisions.md +8 -0
- package/dist/resources/extensions/gsd/templates/milestone-summary.md +73 -0
- package/dist/resources/extensions/gsd/templates/plan.md +131 -0
- package/dist/resources/extensions/gsd/templates/preferences.md +23 -0
- package/dist/resources/extensions/gsd/templates/project.md +31 -0
- package/dist/resources/extensions/gsd/templates/reassessment.md +28 -0
- package/dist/resources/extensions/gsd/templates/requirements.md +81 -0
- package/dist/resources/extensions/gsd/templates/research.md +46 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +118 -0
- package/dist/resources/extensions/gsd/templates/secrets-manifest.md +22 -0
- package/dist/resources/extensions/gsd/templates/slice-context.md +58 -0
- package/dist/resources/extensions/gsd/templates/slice-summary.md +99 -0
- package/dist/resources/extensions/gsd/templates/state.md +19 -0
- package/dist/resources/extensions/gsd/templates/task-plan.md +52 -0
- package/dist/resources/extensions/gsd/templates/task-summary.md +57 -0
- package/dist/resources/extensions/gsd/templates/uat.md +54 -0
- package/dist/resources/extensions/gsd/tests/activity-log-prune.test.ts +297 -0
- package/dist/resources/extensions/gsd/tests/activity-log-save.test.ts +127 -0
- package/dist/resources/extensions/gsd/tests/auto-draft-pause.test.ts +109 -0
- package/dist/resources/extensions/gsd/tests/auto-preflight.test.ts +45 -0
- package/dist/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +196 -0
- package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +53 -0
- package/dist/resources/extensions/gsd/tests/collect-from-manifest.test.ts +469 -0
- package/dist/resources/extensions/gsd/tests/complete-milestone.test.ts +200 -0
- package/dist/resources/extensions/gsd/tests/cost-projection.test.ts +134 -0
- package/dist/resources/extensions/gsd/tests/derive-state-deps.test.ts +312 -0
- package/dist/resources/extensions/gsd/tests/derive-state-draft.test.ts +299 -0
- package/dist/resources/extensions/gsd/tests/derive-state.test.ts +660 -0
- package/dist/resources/extensions/gsd/tests/discuss-prompt.test.ts +27 -0
- package/dist/resources/extensions/gsd/tests/dispatch-guard.test.ts +91 -0
- package/dist/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +170 -0
- package/dist/resources/extensions/gsd/tests/doctor.test.ts +594 -0
- package/dist/resources/extensions/gsd/tests/draft-promotion.test.ts +169 -0
- package/dist/resources/extensions/gsd/tests/exit-command.test.ts +50 -0
- package/dist/resources/extensions/gsd/tests/git-service.test.ts +1788 -0
- package/dist/resources/extensions/gsd/tests/idle-recovery.test.ts +577 -0
- package/dist/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +580 -0
- package/dist/resources/extensions/gsd/tests/manifest-status.test.ts +283 -0
- package/dist/resources/extensions/gsd/tests/metrics-io.test.ts +176 -0
- package/dist/resources/extensions/gsd/tests/metrics.test.ts +188 -0
- package/dist/resources/extensions/gsd/tests/migrate-command.test.ts +369 -0
- package/dist/resources/extensions/gsd/tests/migrate-parser.test.ts +757 -0
- package/dist/resources/extensions/gsd/tests/migrate-transformer.test.ts +635 -0
- package/dist/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +414 -0
- package/dist/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +297 -0
- package/dist/resources/extensions/gsd/tests/migrate-writer.test.ts +398 -0
- package/dist/resources/extensions/gsd/tests/must-have-parser.test.ts +291 -0
- package/dist/resources/extensions/gsd/tests/network-error-fallback.test.ts +54 -0
- package/dist/resources/extensions/gsd/tests/next-milestone-id.test.ts +66 -0
- package/dist/resources/extensions/gsd/tests/orphaned-branch.test.ts +353 -0
- package/dist/resources/extensions/gsd/tests/parsers.test.ts +1664 -0
- package/dist/resources/extensions/gsd/tests/plan-milestone.test.ts +133 -0
- package/dist/resources/extensions/gsd/tests/plan-quality-validator.test.ts +363 -0
- package/dist/resources/extensions/gsd/tests/post-unit-hooks.test.ts +297 -0
- package/dist/resources/extensions/gsd/tests/preferences-hooks.test.ts +226 -0
- package/dist/resources/extensions/gsd/tests/queue-draft-detection.test.ts +126 -0
- package/dist/resources/extensions/gsd/tests/reassess-prompt.test.ts +142 -0
- package/dist/resources/extensions/gsd/tests/regex-hardening.test.ts +281 -0
- package/dist/resources/extensions/gsd/tests/remote-questions.test.ts +155 -0
- package/dist/resources/extensions/gsd/tests/remote-status.test.ts +99 -0
- package/dist/resources/extensions/gsd/tests/replan-slice.test.ts +493 -0
- package/dist/resources/extensions/gsd/tests/requirements.test.ts +106 -0
- package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +35 -0
- package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +11 -0
- package/dist/resources/extensions/gsd/tests/roadmap-slices.test.ts +41 -0
- package/dist/resources/extensions/gsd/tests/run-uat.test.ts +316 -0
- package/dist/resources/extensions/gsd/tests/secure-env-collect.test.ts +185 -0
- package/dist/resources/extensions/gsd/tests/smart-entry-draft.test.ts +123 -0
- package/dist/resources/extensions/gsd/tests/test-helpers.ts +61 -0
- package/dist/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +219 -0
- package/dist/resources/extensions/gsd/tests/unit-runtime.test.ts +234 -0
- package/dist/resources/extensions/gsd/tests/workspace-index.test.ts +75 -0
- package/dist/resources/extensions/gsd/tests/worktree-integration.test.ts +234 -0
- package/dist/resources/extensions/gsd/tests/worktree-manager.test.ts +141 -0
- package/dist/resources/extensions/gsd/tests/worktree.test.ts +597 -0
- package/dist/resources/extensions/gsd/tests/write-gate.test.ts +122 -0
- package/dist/resources/extensions/gsd/types.ts +296 -0
- package/dist/resources/extensions/gsd/unit-runtime.ts +184 -0
- package/dist/resources/extensions/gsd/workspace-index.ts +189 -0
- package/dist/resources/extensions/gsd/worktree-command.ts +845 -0
- package/dist/resources/extensions/gsd/worktree-manager.ts +459 -0
- package/dist/resources/extensions/gsd/{worktree.js → worktree.ts} +92 -61
- package/dist/resources/extensions/mac-tools/index.ts +852 -0
- package/dist/resources/extensions/mac-tools/swift-cli/Package.swift +22 -0
- package/dist/resources/extensions/mac-tools/swift-cli/Sources/main.swift +1318 -0
- package/dist/resources/extensions/mcporter/index.ts +429 -0
- package/dist/resources/extensions/remote-questions/config.ts +81 -0
- package/dist/resources/extensions/remote-questions/discord-adapter.ts +128 -0
- package/dist/resources/extensions/remote-questions/format.ts +163 -0
- package/dist/resources/extensions/remote-questions/manager.ts +192 -0
- package/dist/resources/extensions/remote-questions/remote-command.ts +361 -0
- package/dist/resources/extensions/remote-questions/slack-adapter.ts +92 -0
- package/dist/resources/extensions/remote-questions/status.ts +31 -0
- package/dist/resources/extensions/remote-questions/store.ts +77 -0
- package/dist/resources/extensions/remote-questions/types.ts +75 -0
- package/dist/resources/extensions/search-the-web/cache.ts +78 -0
- package/dist/resources/extensions/search-the-web/command-search-provider.ts +99 -0
- package/dist/resources/extensions/search-the-web/format.ts +258 -0
- package/dist/resources/extensions/search-the-web/http.ts +238 -0
- package/dist/resources/extensions/search-the-web/index.ts +65 -0
- package/dist/resources/extensions/search-the-web/native-search.ts +165 -0
- package/dist/resources/extensions/search-the-web/provider.ts +136 -0
- package/dist/resources/extensions/search-the-web/tavily.ts +116 -0
- package/dist/resources/extensions/search-the-web/tool-fetch-page.ts +581 -0
- package/dist/resources/extensions/search-the-web/tool-llm-context.ts +620 -0
- package/dist/resources/extensions/search-the-web/tool-search.ts +635 -0
- package/dist/resources/extensions/search-the-web/url-utils.ts +91 -0
- package/dist/resources/extensions/shared/bundled-extension-paths.ts +11 -0
- package/dist/resources/extensions/shared/confirm-ui.ts +126 -0
- package/dist/resources/extensions/shared/interview-ui.ts +613 -0
- package/dist/resources/extensions/shared/next-action-ui.ts +197 -0
- package/dist/resources/extensions/shared/progress-widget.ts +282 -0
- package/dist/resources/extensions/shared/terminal.ts +23 -0
- package/dist/resources/extensions/shared/thinking-widget.ts +107 -0
- package/dist/resources/extensions/shared/ui.ts +400 -0
- package/dist/resources/extensions/shared/wizard-ui.ts +551 -0
- package/dist/resources/extensions/slash-commands/audit.ts +88 -0
- package/dist/resources/extensions/slash-commands/clear.ts +10 -0
- package/dist/resources/extensions/slash-commands/create-extension.ts +297 -0
- package/dist/resources/extensions/slash-commands/create-slash-command.ts +234 -0
- package/dist/resources/extensions/slash-commands/index.ts +12 -0
- package/dist/resources/extensions/subagent/agents.ts +126 -0
- package/dist/resources/extensions/subagent/index.ts +1072 -0
- package/dist/resources/extensions/subagent/isolation.ts +498 -0
- package/dist/resources/extensions/ttsr/index.ts +163 -0
- package/dist/resources/extensions/ttsr/rule-loader.ts +121 -0
- package/dist/resources/extensions/ttsr/ttsr-interrupt.md +6 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.ts +430 -0
- package/dist/resources/extensions/universal-config/discovery.ts +78 -0
- package/dist/resources/extensions/universal-config/format.ts +160 -0
- package/dist/resources/extensions/universal-config/index.ts +118 -0
- package/dist/resources/extensions/universal-config/package.json +11 -0
- package/dist/resources/extensions/universal-config/scanners.ts +579 -0
- package/dist/resources/extensions/universal-config/tests/discovery.test.ts +111 -0
- package/dist/resources/extensions/universal-config/tests/format.test.ts +111 -0
- package/dist/resources/extensions/universal-config/tests/scanners.test.ts +438 -0
- package/dist/resources/extensions/universal-config/tools.ts +60 -0
- package/dist/resources/extensions/universal-config/types.ts +116 -0
- package/dist/resources/extensions/voice/index.ts +271 -0
- package/dist/resources/extensions/voice/speech-recognizer.py +504 -0
- package/dist/resources/extensions/voice/speech-recognizer.swift +154 -0
- package/dist/resources/skills/debug-like-expert/SKILL.md +231 -0
- package/dist/resources/skills/debug-like-expert/references/debugging-mindset.md +253 -0
- package/dist/resources/skills/debug-like-expert/references/hypothesis-testing.md +373 -0
- package/dist/resources/skills/debug-like-expert/references/investigation-techniques.md +337 -0
- package/dist/resources/skills/debug-like-expert/references/verification-patterns.md +425 -0
- package/dist/resources/skills/debug-like-expert/references/when-to-research.md +361 -0
- package/dist/resources/skills/frontend-design/SKILL.md +45 -0
- package/dist/resources/skills/github-workflows/SKILL.md +92 -0
- package/dist/resources/skills/github-workflows/references/gh/SKILL.md +255 -0
- package/dist/resources/skills/github-workflows/references/gh/references/issue-stories.md +204 -0
- package/dist/resources/skills/github-workflows/references/gh/references/labels.md +170 -0
- package/dist/resources/skills/github-workflows/references/gh/references/milestones.md +158 -0
- package/dist/resources/skills/github-workflows/references/gh/references/projects-v2.md +177 -0
- package/dist/resources/skills/github-workflows/references/gh/scripts/experiment_cleanup.py +191 -0
- package/dist/resources/skills/github-workflows/references/gh/scripts/github_project_setup.py +799 -0
- package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
- package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +608 -0
- package/dist/resources/skills/swiftui/SKILL.md +208 -0
- package/dist/resources/skills/swiftui/references/animations.md +921 -0
- package/dist/resources/skills/swiftui/references/architecture.md +1561 -0
- package/dist/resources/skills/swiftui/references/layout-system.md +1186 -0
- package/dist/resources/skills/swiftui/references/navigation.md +1492 -0
- package/dist/resources/skills/swiftui/references/networking-async.md +214 -0
- package/dist/resources/skills/swiftui/references/performance.md +1706 -0
- package/dist/resources/skills/swiftui/references/platform-integration.md +204 -0
- package/dist/resources/skills/swiftui/references/state-management.md +1443 -0
- package/dist/resources/skills/swiftui/references/swiftdata.md +297 -0
- package/dist/resources/skills/swiftui/references/testing-debugging.md +247 -0
- package/dist/resources/skills/swiftui/references/uikit-appkit-interop.md +218 -0
- package/dist/resources/skills/swiftui/workflows/add-feature.md +191 -0
- package/dist/resources/skills/swiftui/workflows/build-new-app.md +311 -0
- package/dist/resources/skills/swiftui/workflows/debug-swiftui.md +192 -0
- package/dist/resources/skills/swiftui/workflows/optimize-performance.md +197 -0
- package/dist/resources/skills/swiftui/workflows/ship-app.md +203 -0
- package/dist/resources/skills/swiftui/workflows/write-tests.md +235 -0
- package/dist/wizard.js +1 -0
- package/package.json +8 -6
- package/packages/native/dist/fd/index.d.ts +1 -0
- package/packages/native/dist/fd/index.js +1 -0
- package/packages/native/dist/grep/index.d.ts +2 -1
- package/packages/native/dist/grep/index.js +1 -0
- package/packages/native/src/__tests__/fd.test.mjs +35 -0
- package/packages/native/src/__tests__/grep.test.mjs +26 -9
- package/packages/native/src/fd/index.ts +1 -0
- package/packages/native/src/grep/index.ts +3 -2
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +169 -55
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +13 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +16 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +91 -1
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +273 -63
- package/packages/pi-agent-core/src/agent.ts +24 -0
- package/packages/pi-agent-core/src/types.ts +98 -0
- package/packages/pi-ai/dist/env-api-keys.js +2 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +314 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +236 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +6 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +2 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +1 -1
- 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/src/env-api-keys.ts +2 -0
- package/packages/pi-ai/src/models.generated.ts +236 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +8 -0
- package/packages/pi-ai/src/providers/openai-completions.ts +3 -0
- package/packages/pi-ai/src/types.ts +2 -1
- package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/cli/args.js +1 -0
- package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +26 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +137 -22
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +43 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts +51 -0
- package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/fallback-resolver.js +119 -0
- package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/fallback-resolver.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/fallback-resolver.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +183 -0
- package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts +12 -1
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +37 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/session-manager.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +61 -0
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +47 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.js +1 -0
- package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +6 -15
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +18 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +46 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +25 -2
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/cli/args.ts +1 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +167 -22
- package/packages/pi-coding-agent/src/core/auth-storage.ts +45 -0
- package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +229 -0
- package/packages/pi-coding-agent/src/core/fallback-resolver.ts +165 -0
- package/packages/pi-coding-agent/src/core/index.ts +1 -0
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -0
- package/packages/pi-coding-agent/src/core/session-manager.ts +51 -1
- package/packages/pi-coding-agent/src/core/settings-manager.ts +66 -0
- package/packages/pi-coding-agent/src/core/tools/find.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +6 -16
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +49 -4
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -2
- package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
- package/packages/pi-tui/dist/autocomplete.js +3 -4
- package/packages/pi-tui/dist/autocomplete.js.map +1 -1
- package/packages/pi-tui/dist/components/editor.d.ts +7 -0
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +57 -50
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/src/autocomplete.ts +3 -5
- package/packages/pi-tui/src/components/editor.ts +70 -49
- package/pkg/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/pkg/dist/core/export-html/ansi-to-html.js +249 -0
- package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/pkg/dist/core/export-html/index.d.ts +37 -0
- package/pkg/dist/core/export-html/index.d.ts.map +1 -0
- package/pkg/dist/core/export-html/index.js +223 -0
- package/pkg/dist/core/export-html/index.js.map +1 -0
- package/pkg/dist/core/export-html/template.css +971 -0
- package/pkg/dist/core/export-html/template.html +54 -0
- package/pkg/dist/core/export-html/template.js +1583 -0
- package/pkg/dist/core/export-html/tool-renderer.d.ts +38 -0
- package/pkg/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/pkg/dist/core/export-html/tool-renderer.js +70 -0
- package/pkg/dist/core/export-html/tool-renderer.js.map +1 -0
- package/pkg/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/pkg/dist/core/export-html/vendor/marked.min.js +6 -0
- package/scripts/postinstall.js +30 -17
- package/src/resources/extensions/bg-shell/index.ts +51 -7
- package/src/resources/extensions/gsd/activity-log.ts +61 -14
- package/src/resources/extensions/gsd/auto.ts +288 -19
- package/src/resources/extensions/gsd/commands.ts +9 -3
- package/src/resources/extensions/gsd/dashboard-overlay.ts +55 -12
- package/src/resources/extensions/gsd/docs/preferences-reference.md +25 -0
- package/src/resources/extensions/gsd/doctor.ts +60 -3
- package/src/resources/extensions/gsd/files.ts +45 -1
- package/src/resources/extensions/gsd/git-service.ts +46 -41
- package/src/resources/extensions/gsd/guided-flow.ts +81 -9
- package/src/resources/extensions/gsd/index.ts +62 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +181 -0
- package/src/resources/extensions/gsd/paths.ts +35 -4
- package/src/resources/extensions/gsd/post-unit-hooks.ts +449 -0
- package/src/resources/extensions/gsd/preferences.ts +232 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +45 -3
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -3
- package/src/resources/extensions/gsd/prompts/discuss.md +10 -8
- package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +3 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
- package/src/resources/extensions/gsd/prompts/guided-execute-task.md +3 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +4 -2
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +3 -1
- package/src/resources/extensions/gsd/prompts/guided-research-slice.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +9 -12
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -3
- package/src/resources/extensions/gsd/prompts/queue.md +3 -1
- package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/state.ts +130 -18
- package/src/resources/extensions/gsd/templates/context.md +1 -1
- package/src/resources/extensions/gsd/templates/state.md +3 -3
- package/src/resources/extensions/gsd/tests/activity-log-save.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/doctor.test.ts +115 -1
- package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/git-service.test.ts +35 -35
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +8 -8
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/network-error-fallback.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/orphaned-branch.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/preferences-hooks.test.ts +226 -0
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree.test.ts +19 -19
- package/src/resources/extensions/gsd/types.ts +109 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +72 -13
- package/src/resources/extensions/gsd/worktree.ts +5 -4
- package/src/resources/extensions/search-the-web/command-search-provider.ts +8 -4
- package/src/resources/extensions/search-the-web/native-search.ts +32 -23
- package/src/resources/extensions/search-the-web/provider.ts +19 -2
- package/src/resources/extensions/search-the-web/tool-fetch-page.ts +62 -0
- package/src/resources/extensions/search-the-web/tool-llm-context.ts +62 -3
- package/src/resources/extensions/search-the-web/tool-search.ts +62 -3
- package/src/resources/extensions/shared/bundled-extension-paths.ts +11 -0
- package/src/resources/extensions/subagent/index.ts +2 -1
- package/src/resources/skills/github-workflows/SKILL.md +5 -0
- package/dist/resources/extensions/gsd/git-service.d.ts +0 -225
- package/dist/resources/extensions/gsd/git-service.js +0 -756
- package/dist/resources/extensions/gsd/preferences.d.ts +0 -122
- package/dist/resources/extensions/gsd/preferences.js +0 -616
- package/dist/resources/extensions/gsd/worktree.d.ts +0 -106
- package/dist/resources/extensions/remote-questions/config.d.ts +0 -14
- package/dist/resources/extensions/remote-questions/config.js +0 -68
- package/dist/resources/extensions/remote-questions/discord-adapter.d.ts +0 -17
- package/dist/resources/extensions/remote-questions/discord-adapter.js +0 -118
- package/dist/resources/extensions/remote-questions/format.d.ts +0 -38
- package/dist/resources/extensions/remote-questions/format.js +0 -119
- package/dist/resources/extensions/remote-questions/manager.d.ts +0 -23
- package/dist/resources/extensions/remote-questions/manager.js +0 -161
- package/dist/resources/extensions/remote-questions/remote-command.d.ts +0 -6
- package/dist/resources/extensions/remote-questions/remote-command.js +0 -358
- package/dist/resources/extensions/remote-questions/slack-adapter.d.ts +0 -15
- package/dist/resources/extensions/remote-questions/slack-adapter.js +0 -82
- package/dist/resources/extensions/remote-questions/status.d.ts +0 -9
- package/dist/resources/extensions/remote-questions/status.js +0 -25
- package/dist/resources/extensions/remote-questions/store.d.ts +0 -11
- package/dist/resources/extensions/remote-questions/store.js +0 -66
- package/dist/resources/extensions/remote-questions/types.d.ts +0 -68
- package/dist/resources/extensions/remote-questions/types.js +0 -4
|
@@ -31,14 +31,14 @@ function run(command: string, cwd: string): string {
|
|
|
31
31
|
|
|
32
32
|
const base = mkdtempSync(join(tmpdir(), "gsd-branch-test-"));
|
|
33
33
|
run("git init -b main", base);
|
|
34
|
-
run(
|
|
35
|
-
run(
|
|
34
|
+
run('git config user.name "Pi Test"', base);
|
|
35
|
+
run('git config user.email "pi@example.com"', base);
|
|
36
36
|
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
|
|
37
37
|
writeFileSync(join(base, "README.md"), "hello\n", "utf-8");
|
|
38
38
|
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), `# M001: Demo\n\n## Slices\n- [ ] **S01: Slice One** \`risk:low\` \`depends:[]\`\n > After this: demo works\n`, "utf-8");
|
|
39
39
|
writeFileSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md"), `# S01: Slice One\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Must-Haves\n- done\n\n## Tasks\n- [ ] **T01: Implement** \`est:10m\`\n do it\n`, "utf-8");
|
|
40
40
|
run("git add .", base);
|
|
41
|
-
run(
|
|
41
|
+
run('git commit -m "chore: init"', base);
|
|
42
42
|
|
|
43
43
|
async function main(): Promise<void> {
|
|
44
44
|
console.log("\n=== ensureSliceBranch ===");
|
|
@@ -85,7 +85,7 @@ async function main(): Promise<void> {
|
|
|
85
85
|
ensureSliceBranch(base, "M001", "S01");
|
|
86
86
|
writeFileSync(join(base, "README.md"), "hello from slice\n", "utf-8");
|
|
87
87
|
run("git add README.md", base);
|
|
88
|
-
run(
|
|
88
|
+
run('git commit -m "feat: slice change"', base);
|
|
89
89
|
switchToMain(base);
|
|
90
90
|
|
|
91
91
|
const merge = mergeSliceToMain(base, "M001", "S01", "Slice One");
|
|
@@ -107,7 +107,7 @@ async function main(): Promise<void> {
|
|
|
107
107
|
"- [ ] **S02: Slice Two** `risk:low` `depends:[]`", " > Demo 2",
|
|
108
108
|
].join("\n") + "\n", "utf-8");
|
|
109
109
|
run("git add .", base);
|
|
110
|
-
run(
|
|
110
|
+
run('git commit -m "chore: add S02"', base);
|
|
111
111
|
|
|
112
112
|
ensureSliceBranch(base, "M001", "S02");
|
|
113
113
|
writeFileSync(join(base, "feature.txt"), "new feature\n", "utf-8");
|
|
@@ -168,11 +168,11 @@ async function main(): Promise<void> {
|
|
|
168
168
|
console.log("\n=== ensureSliceBranch from non-main working branch ===");
|
|
169
169
|
const base2 = mkdtempSync(join(tmpdir(), "gsd-branch-base-test-"));
|
|
170
170
|
run("git init -b main", base2);
|
|
171
|
-
run(
|
|
172
|
-
run(
|
|
171
|
+
run('git config user.name "Pi Test"', base2);
|
|
172
|
+
run('git config user.email "pi@example.com"', base2);
|
|
173
173
|
writeFileSync(join(base2, "README.md"), "hello\n", "utf-8");
|
|
174
174
|
run("git add .", base2);
|
|
175
|
-
run(
|
|
175
|
+
run('git commit -m "chore: init"', base2);
|
|
176
176
|
|
|
177
177
|
// Create a "developer" branch with planning artifacts (like the real scenario)
|
|
178
178
|
run("git checkout -b developer", base2);
|
|
@@ -183,7 +183,7 @@ async function main(): Promise<void> {
|
|
|
183
183
|
"- [ ] **S01: Config Fix** `risk:low` `depends:[]`", " > Fix config",
|
|
184
184
|
].join("\n") + "\n", "utf-8");
|
|
185
185
|
run("git add .", base2);
|
|
186
|
-
run(
|
|
186
|
+
run('git commit -m "docs(M001): context and roadmap"', base2);
|
|
187
187
|
|
|
188
188
|
// Verify main does NOT have the artifacts
|
|
189
189
|
const mainRoadmap = run("git show main:.gsd/milestones/M001/M001-ROADMAP.md 2>&1 || echo MISSING", base2);
|
|
@@ -211,8 +211,8 @@ async function main(): Promise<void> {
|
|
|
211
211
|
console.log("\n=== ensureSliceBranch from slice branch falls back to main ===");
|
|
212
212
|
const base3 = mkdtempSync(join(tmpdir(), "gsd-branch-chain-test-"));
|
|
213
213
|
run("git init -b main", base3);
|
|
214
|
-
run(
|
|
215
|
-
run(
|
|
214
|
+
run('git config user.name "Pi Test"', base3);
|
|
215
|
+
run('git config user.email "pi@example.com"', base3);
|
|
216
216
|
mkdirSync(join(base3, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
|
|
217
217
|
mkdirSync(join(base3, ".gsd", "milestones", "M001", "slices", "S02", "tasks"), { recursive: true });
|
|
218
218
|
writeFileSync(join(base3, "README.md"), "hello\n", "utf-8");
|
|
@@ -222,7 +222,7 @@ async function main(): Promise<void> {
|
|
|
222
222
|
"- [ ] **S02: Second** `risk:low` `depends:[]`", " > second",
|
|
223
223
|
].join("\n") + "\n", "utf-8");
|
|
224
224
|
run("git add .", base3);
|
|
225
|
-
run(
|
|
225
|
+
run('git commit -m "chore: init"', base3);
|
|
226
226
|
|
|
227
227
|
ensureSliceBranch(base3, "M001", "S01");
|
|
228
228
|
assertEq(getCurrentBranch(base3), "gsd/M001/S01", "on S01 slice branch");
|
|
@@ -379,7 +379,7 @@ async function main(): Promise<void> {
|
|
|
379
379
|
// User creates feature branch
|
|
380
380
|
run("git checkout -b feature/big-change", repo);
|
|
381
381
|
writeFileSync(join(repo, "setup.txt"), "feature setup\n");
|
|
382
|
-
run(
|
|
382
|
+
run('git add -A && git commit -m "feat: initial setup"', repo);
|
|
383
383
|
|
|
384
384
|
// auto.ts startup: capture + set milestone
|
|
385
385
|
captureIntegrationBranch(repo, "M001");
|
|
@@ -397,7 +397,7 @@ async function main(): Promise<void> {
|
|
|
397
397
|
"multi: S01 inherited feature branch content");
|
|
398
398
|
|
|
399
399
|
writeFileSync(join(repo, "s01-work.txt"), "s01 output\n");
|
|
400
|
-
run(
|
|
400
|
+
run('git add -A && git commit -m "feat(S01): work"', repo);
|
|
401
401
|
|
|
402
402
|
switchToMain(repo);
|
|
403
403
|
assertEq(getCurrentBranch(repo), "feature/big-change",
|
|
@@ -428,7 +428,7 @@ async function main(): Promise<void> {
|
|
|
428
428
|
"multi: S02 has S01 output (inherited via feature branch)");
|
|
429
429
|
|
|
430
430
|
writeFileSync(join(repo, "s02-work.txt"), "s02 output\n");
|
|
431
|
-
run(
|
|
431
|
+
run('git add -A && git commit -m "feat(S02): work"', repo);
|
|
432
432
|
|
|
433
433
|
switchToMain(repo);
|
|
434
434
|
assertEq(getCurrentBranch(repo), "feature/big-change",
|
|
@@ -479,7 +479,7 @@ async function main(): Promise<void> {
|
|
|
479
479
|
// Create a slice and do some work
|
|
480
480
|
ensureSliceBranch(repo, "M001", "S01");
|
|
481
481
|
writeFileSync(join(repo, "work.txt"), "wip\n");
|
|
482
|
-
run(
|
|
482
|
+
run('git add -A && git commit -m "wip"', repo);
|
|
483
483
|
|
|
484
484
|
// Simulate "restart" — clear milestone ID (fresh service instance)
|
|
485
485
|
setActiveMilestoneId(repo, null);
|
|
@@ -530,7 +530,7 @@ async function main(): Promise<void> {
|
|
|
530
530
|
// Full lifecycle on main still works
|
|
531
531
|
ensureSliceBranch(repo, "M001", "S01");
|
|
532
532
|
writeFileSync(join(repo, "feature.txt"), "new\n");
|
|
533
|
-
run(
|
|
533
|
+
run('git add -A && git commit -m "feat: work"', repo);
|
|
534
534
|
|
|
535
535
|
switchToMain(repo);
|
|
536
536
|
assertEq(getCurrentBranch(repo), "main",
|
|
@@ -564,7 +564,7 @@ async function main(): Promise<void> {
|
|
|
564
564
|
|
|
565
565
|
run("git checkout -b dev-branch", repo);
|
|
566
566
|
writeFileSync(join(repo, "dev-only.txt"), "from dev\n");
|
|
567
|
-
run(
|
|
567
|
+
run('git add -A && git commit -m "dev setup"', repo);
|
|
568
568
|
|
|
569
569
|
captureIntegrationBranch(repo, "M001");
|
|
570
570
|
setActiveMilestoneId(repo, "M001");
|
|
@@ -572,7 +572,7 @@ async function main(): Promise<void> {
|
|
|
572
572
|
// Create S01 (from dev-branch)
|
|
573
573
|
ensureSliceBranch(repo, "M001", "S01");
|
|
574
574
|
writeFileSync(join(repo, "s01.txt"), "s01\n");
|
|
575
|
-
run(
|
|
575
|
+
run('git add -A && git commit -m "s01 work"', repo);
|
|
576
576
|
|
|
577
577
|
// While on S01, create S02 — should fall back to integration branch
|
|
578
578
|
ensureSliceBranch(repo, "M001", "S02");
|
|
@@ -185,3 +185,112 @@ export interface GSDState {
|
|
|
185
185
|
tasks?: { done: number; total: number };
|
|
186
186
|
};
|
|
187
187
|
}
|
|
188
|
+
|
|
189
|
+
// ─── Post-Unit Hook Types ─────────────────────────────────────────────────
|
|
190
|
+
|
|
191
|
+
export interface PostUnitHookConfig {
|
|
192
|
+
/** Unique hook identifier — used in idempotency keys and logging. */
|
|
193
|
+
name: string;
|
|
194
|
+
/** Unit types that trigger this hook (e.g., ["execute-task"]). */
|
|
195
|
+
after: string[];
|
|
196
|
+
/** Prompt sent to the LLM session. Supports {milestoneId}, {sliceId}, {taskId} substitutions. */
|
|
197
|
+
prompt: string;
|
|
198
|
+
/** Max times this hook can fire for the same trigger unit. Default 1, max 10. */
|
|
199
|
+
max_cycles?: number;
|
|
200
|
+
/** Model override for hook sessions. */
|
|
201
|
+
model?: string;
|
|
202
|
+
/** Expected output file name (relative to task/slice dir). Used for idempotency — skip if exists. */
|
|
203
|
+
artifact?: string;
|
|
204
|
+
/** If this file is produced instead of artifact, re-run the trigger unit then re-run hooks. */
|
|
205
|
+
retry_on?: string;
|
|
206
|
+
/** Agent definition file to use. */
|
|
207
|
+
agent?: string;
|
|
208
|
+
/** Set false to disable without removing config. Default true. */
|
|
209
|
+
enabled?: boolean;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface HookExecutionState {
|
|
213
|
+
/** Hook name. */
|
|
214
|
+
hookName: string;
|
|
215
|
+
/** The unit type that triggered this hook. */
|
|
216
|
+
triggerUnitType: string;
|
|
217
|
+
/** The unit ID that triggered this hook. */
|
|
218
|
+
triggerUnitId: string;
|
|
219
|
+
/** Current cycle (1-based). */
|
|
220
|
+
cycle: number;
|
|
221
|
+
/** Whether the hook completed with a retry signal (retry_on artifact found). */
|
|
222
|
+
pendingRetry: boolean;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface HookDispatchResult {
|
|
226
|
+
/** Hook name for display. */
|
|
227
|
+
hookName: string;
|
|
228
|
+
/** The prompt to send. */
|
|
229
|
+
prompt: string;
|
|
230
|
+
/** Model override, if configured. */
|
|
231
|
+
model?: string;
|
|
232
|
+
/** Synthetic unit type, e.g. "hook/code-review". */
|
|
233
|
+
unitType: string;
|
|
234
|
+
/** The trigger unit's ID, reused for the hook. */
|
|
235
|
+
unitId: string;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// ─── Pre-Dispatch Hook Types ──────────────────────────────────────────────
|
|
239
|
+
|
|
240
|
+
export interface PreDispatchHookConfig {
|
|
241
|
+
/** Unique hook identifier. */
|
|
242
|
+
name: string;
|
|
243
|
+
/** Unit types this hook intercepts before dispatch (e.g., ["execute-task"]). */
|
|
244
|
+
before: string[];
|
|
245
|
+
/** Action to take: "modify" mutates the prompt, "skip" skips the unit, "replace" swaps it. */
|
|
246
|
+
action: 'modify' | 'skip' | 'replace';
|
|
247
|
+
/** For "modify": text prepended to the unit prompt. Supports {milestoneId}, {sliceId}, {taskId}. */
|
|
248
|
+
prepend?: string;
|
|
249
|
+
/** For "modify": text appended to the unit prompt. Supports {milestoneId}, {sliceId}, {taskId}. */
|
|
250
|
+
append?: string;
|
|
251
|
+
/** For "replace": the replacement prompt. Supports {milestoneId}, {sliceId}, {taskId}. */
|
|
252
|
+
prompt?: string;
|
|
253
|
+
/** For "replace": override the unit type label. */
|
|
254
|
+
unit_type?: string;
|
|
255
|
+
/** For "skip": optional condition file — only skip if this file exists (relative to unit dir). */
|
|
256
|
+
skip_if?: string;
|
|
257
|
+
/** Model override when this hook fires. */
|
|
258
|
+
model?: string;
|
|
259
|
+
/** Set false to disable without removing config. Default true. */
|
|
260
|
+
enabled?: boolean;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export interface PreDispatchResult {
|
|
264
|
+
/** What happened: the unit proceeds with modifications, was skipped, or was replaced. */
|
|
265
|
+
action: 'proceed' | 'skip' | 'replace';
|
|
266
|
+
/** Modified/replacement prompt (for "proceed" and "replace"). */
|
|
267
|
+
prompt?: string;
|
|
268
|
+
/** Override unit type (for "replace"). */
|
|
269
|
+
unitType?: string;
|
|
270
|
+
/** Model override. */
|
|
271
|
+
model?: string;
|
|
272
|
+
/** Names of hooks that fired, for logging. */
|
|
273
|
+
firedHooks: string[];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ─── Hook State Persistence Types ─────────────────────────────────────────
|
|
277
|
+
|
|
278
|
+
export interface PersistedHookState {
|
|
279
|
+
/** Cycle counts keyed as "hookName/triggerUnitType/triggerUnitId". */
|
|
280
|
+
cycleCounts: Record<string, number>;
|
|
281
|
+
/** Timestamp of last state save. */
|
|
282
|
+
savedAt: string;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface HookStatusEntry {
|
|
286
|
+
/** Hook name. */
|
|
287
|
+
name: string;
|
|
288
|
+
/** Hook type: "post" or "pre". */
|
|
289
|
+
type: 'post' | 'pre';
|
|
290
|
+
/** Whether hook is enabled. */
|
|
291
|
+
enabled: boolean;
|
|
292
|
+
/** What unit types it targets. */
|
|
293
|
+
targets: string[];
|
|
294
|
+
/** Current cycle counts for active triggers. */
|
|
295
|
+
activeCycles: Record<string, number>;
|
|
296
|
+
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { existsSync, mkdirSync, realpathSync } from "node:fs";
|
|
19
19
|
import { execSync } from "node:child_process";
|
|
20
|
-
import { join,
|
|
20
|
+
import { join, resolve } from "node:path";
|
|
21
21
|
|
|
22
22
|
// ─── Types ─────────────────────────────────────────────────────────────────
|
|
23
23
|
|
|
@@ -46,13 +46,27 @@ export interface WorktreeDiffSummary {
|
|
|
46
46
|
|
|
47
47
|
// ─── Git Helpers ───────────────────────────────────────────────────────────
|
|
48
48
|
|
|
49
|
-
/** Env overlay that suppresses
|
|
49
|
+
/** Env overlay that suppresses interactive git credential prompts and git-svn noise. */
|
|
50
50
|
const GIT_NO_PROMPT_ENV = {
|
|
51
51
|
...process.env,
|
|
52
52
|
GIT_TERMINAL_PROMPT: "0",
|
|
53
53
|
GIT_ASKPASS: "",
|
|
54
|
+
GIT_SVN_ID: "",
|
|
54
55
|
};
|
|
55
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Strip git-svn noise from error messages.
|
|
59
|
+
* Some systems have a buggy git-svn Perl module that emits warnings
|
|
60
|
+
* on every git invocation. See #404.
|
|
61
|
+
*/
|
|
62
|
+
function filterGitSvnNoise(message: string): string {
|
|
63
|
+
return message
|
|
64
|
+
.replace(/Duplicate specification "[^"]*" for option "[^"]*"\n?/g, "")
|
|
65
|
+
.replace(/Unable to determine upstream SVN information from .*\n?/g, "")
|
|
66
|
+
.replace(/Perhaps the repository is empty\. at .*git-svn.*\n?/g, "")
|
|
67
|
+
.trim();
|
|
68
|
+
}
|
|
69
|
+
|
|
56
70
|
function runGit(cwd: string, args: string[], opts: { allowFailure?: boolean } = {}): string {
|
|
57
71
|
try {
|
|
58
72
|
return execSync(`git ${args.join(" ")}`, {
|
|
@@ -64,10 +78,18 @@ function runGit(cwd: string, args: string[], opts: { allowFailure?: boolean } =
|
|
|
64
78
|
} catch (error) {
|
|
65
79
|
if (opts.allowFailure) return "";
|
|
66
80
|
const message = error instanceof Error ? error.message : String(error);
|
|
67
|
-
throw new Error(`git ${args.join(" ")} failed in ${cwd}: ${message}`);
|
|
81
|
+
throw new Error(`git ${args.join(" ")} failed in ${cwd}: ${filterGitSvnNoise(message)}`);
|
|
68
82
|
}
|
|
69
83
|
}
|
|
70
84
|
|
|
85
|
+
function normalizePathForComparison(path: string): string {
|
|
86
|
+
const normalized = path
|
|
87
|
+
.replaceAll("\\", "/")
|
|
88
|
+
.replace(/^\/\/\?\//, "")
|
|
89
|
+
.replace(/\/+$/, "");
|
|
90
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
91
|
+
}
|
|
92
|
+
|
|
71
93
|
export function getMainBranch(basePath: string): string {
|
|
72
94
|
const symbolic = runGit(basePath, ["symbolic-ref", "refs/remotes/origin/HEAD"], { allowFailure: true });
|
|
73
95
|
if (symbolic) {
|
|
@@ -156,15 +178,29 @@ export function createWorktree(basePath: string, name: string): WorktreeInfo {
|
|
|
156
178
|
* Parses `git worktree list` and filters to those under .gsd/worktrees/.
|
|
157
179
|
*/
|
|
158
180
|
export function listWorktrees(basePath: string): WorktreeInfo[] {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
181
|
+
const baseVariants = [resolve(basePath)];
|
|
182
|
+
if (existsSync(basePath)) {
|
|
183
|
+
baseVariants.push(realpathSync(basePath));
|
|
184
|
+
}
|
|
185
|
+
const seenRoots = new Set<string>();
|
|
186
|
+
const worktreeRoots = baseVariants
|
|
187
|
+
.map(baseVariant => {
|
|
188
|
+
const path = join(baseVariant, ".gsd", "worktrees");
|
|
189
|
+
return {
|
|
190
|
+
normalized: normalizePathForComparison(path),
|
|
191
|
+
};
|
|
192
|
+
})
|
|
193
|
+
.filter(root => {
|
|
194
|
+
if (seenRoots.has(root.normalized)) return false;
|
|
195
|
+
seenRoots.add(root.normalized);
|
|
196
|
+
return true;
|
|
197
|
+
});
|
|
162
198
|
const rawList = runGit(basePath, ["worktree", "list", "--porcelain"]);
|
|
163
199
|
|
|
164
200
|
if (!rawList.trim()) return [];
|
|
165
201
|
|
|
166
202
|
const worktrees: WorktreeInfo[] = [];
|
|
167
|
-
const entries = rawList.split("\n\n").filter(Boolean);
|
|
203
|
+
const entries = rawList.replaceAll("\r\n", "\n").split("\n\n").filter(Boolean);
|
|
168
204
|
|
|
169
205
|
for (const entry of entries) {
|
|
170
206
|
const lines = entry.split("\n");
|
|
@@ -175,19 +211,42 @@ export function listWorktrees(basePath: string): WorktreeInfo[] {
|
|
|
175
211
|
|
|
176
212
|
const entryPath = wtLine.replace("worktree ", "");
|
|
177
213
|
const branch = branchLine.replace("branch refs/heads/", "");
|
|
214
|
+
const branchWorktreeName = branch.startsWith("worktree/") ? branch.slice("worktree/".length) : null;
|
|
215
|
+
const entryVariants = [resolve(entryPath)];
|
|
216
|
+
if (existsSync(entryPath)) {
|
|
217
|
+
entryVariants.push(realpathSync(entryPath));
|
|
218
|
+
}
|
|
219
|
+
const normalizedEntryVariants = [...new Set(entryVariants.map(normalizePathForComparison))];
|
|
220
|
+
const matchedRoot = worktreeRoots.find(root =>
|
|
221
|
+
normalizedEntryVariants.some(entryVariant => entryVariant.startsWith(`${root.normalized}/`)),
|
|
222
|
+
);
|
|
223
|
+
const matchesBranchLeaf = branchWorktreeName
|
|
224
|
+
? normalizedEntryVariants.some(entryVariant => entryVariant.split("/").pop() === branchWorktreeName)
|
|
225
|
+
: false;
|
|
178
226
|
|
|
179
227
|
// Only include worktrees under .gsd/worktrees/
|
|
180
|
-
if (!
|
|
228
|
+
if (!matchedRoot && !matchesBranchLeaf) continue;
|
|
229
|
+
|
|
230
|
+
const matchedEntryPath = normalizedEntryVariants.find(entryVariant =>
|
|
231
|
+
matchedRoot ? entryVariant.startsWith(`${matchedRoot.normalized}/`) : false,
|
|
232
|
+
);
|
|
233
|
+
let name = matchedRoot ? matchedEntryPath?.slice(matchedRoot.normalized.length + 1) ?? "" : "";
|
|
234
|
+
|
|
235
|
+
// Git on Windows can report a path form that does not map cleanly back to the
|
|
236
|
+
// repo root even when the branch naming is still authoritative.
|
|
237
|
+
if ((!name || name.includes("/")) && branchWorktreeName && matchesBranchLeaf) {
|
|
238
|
+
name = branchWorktreeName;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (!name || name.includes("/")) continue;
|
|
181
242
|
|
|
182
|
-
const
|
|
183
|
-
// Skip nested paths — only direct children
|
|
184
|
-
if (name.includes("/") || name.includes("\\")) continue;
|
|
243
|
+
const resolvedEntryPath = existsSync(entryPath) ? realpathSync(entryPath) : resolve(entryPath);
|
|
185
244
|
|
|
186
245
|
worktrees.push({
|
|
187
246
|
name,
|
|
188
|
-
path:
|
|
247
|
+
path: resolvedEntryPath,
|
|
189
248
|
branch,
|
|
190
|
-
exists: existsSync(
|
|
249
|
+
exists: existsSync(resolvedEntryPath),
|
|
191
250
|
});
|
|
192
251
|
}
|
|
193
252
|
|
|
@@ -72,11 +72,12 @@ export function captureIntegrationBranch(basePath: string, milestoneId: string):
|
|
|
72
72
|
* Returns null if not inside a GSD worktree (.gsd/worktrees/<name>/).
|
|
73
73
|
*/
|
|
74
74
|
export function detectWorktreeName(basePath: string): string | null {
|
|
75
|
-
const
|
|
76
|
-
const
|
|
75
|
+
const normalizedPath = basePath.replaceAll("\\", "/");
|
|
76
|
+
const marker = "/.gsd/worktrees/";
|
|
77
|
+
const idx = normalizedPath.indexOf(marker);
|
|
77
78
|
if (idx === -1) return null;
|
|
78
|
-
const afterMarker =
|
|
79
|
-
const name = afterMarker.split(
|
|
79
|
+
const afterMarker = normalizedPath.slice(idx + marker.length);
|
|
80
|
+
const name = afterMarker.split("/")[0];
|
|
80
81
|
return name || null;
|
|
81
82
|
}
|
|
82
83
|
|
|
@@ -13,16 +13,18 @@ import type { AutocompleteItem } from '@gsd/pi-tui'
|
|
|
13
13
|
import {
|
|
14
14
|
getTavilyApiKey,
|
|
15
15
|
getBraveApiKey,
|
|
16
|
+
getOllamaApiKey,
|
|
16
17
|
getSearchProviderPreference,
|
|
17
18
|
setSearchProviderPreference,
|
|
18
19
|
resolveSearchProvider,
|
|
19
20
|
type SearchProviderPreference,
|
|
20
21
|
} from './provider.ts'
|
|
21
22
|
|
|
22
|
-
const VALID_PREFERENCES: SearchProviderPreference[] = ['tavily', 'brave', 'auto']
|
|
23
|
+
const VALID_PREFERENCES: SearchProviderPreference[] = ['tavily', 'brave', 'ollama', 'auto']
|
|
23
24
|
|
|
24
|
-
function keyStatus(provider: 'tavily' | 'brave'): string {
|
|
25
|
+
function keyStatus(provider: 'tavily' | 'brave' | 'ollama'): string {
|
|
25
26
|
if (provider === 'tavily') return getTavilyApiKey() ? '✓' : '✗'
|
|
27
|
+
if (provider === 'ollama') return getOllamaApiKey() ? '✓' : '✗'
|
|
26
28
|
return getBraveApiKey() ? '✓' : '✗'
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -30,6 +32,7 @@ function buildSelectOptions(): string[] {
|
|
|
30
32
|
return [
|
|
31
33
|
`tavily (key: ${keyStatus('tavily')})`,
|
|
32
34
|
`brave (key: ${keyStatus('brave')})`,
|
|
35
|
+
`ollama (key: ${keyStatus('ollama')})`,
|
|
33
36
|
`auto`,
|
|
34
37
|
]
|
|
35
38
|
}
|
|
@@ -37,12 +40,13 @@ function buildSelectOptions(): string[] {
|
|
|
37
40
|
function parseSelectChoice(choice: string): SearchProviderPreference {
|
|
38
41
|
if (choice.startsWith('tavily')) return 'tavily'
|
|
39
42
|
if (choice.startsWith('brave')) return 'brave'
|
|
43
|
+
if (choice.startsWith('ollama')) return 'ollama'
|
|
40
44
|
return 'auto'
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
export function registerSearchProviderCommand(pi: ExtensionAPI): void {
|
|
44
48
|
pi.registerCommand('search-provider', {
|
|
45
|
-
description: 'Switch search provider (tavily, brave, auto)',
|
|
49
|
+
description: 'Switch search provider (tavily, brave, ollama, auto)',
|
|
46
50
|
|
|
47
51
|
getArgumentCompletions(prefix: string): AutocompleteItem[] | null {
|
|
48
52
|
const trimmed = prefix.trim().toLowerCase()
|
|
@@ -51,7 +55,7 @@ export function registerSearchProviderCommand(pi: ExtensionAPI): void {
|
|
|
51
55
|
.map((p) => {
|
|
52
56
|
let description: string
|
|
53
57
|
if (p === 'auto') {
|
|
54
|
-
description = `Auto-select (tavily: ${keyStatus('tavily')}, brave: ${keyStatus('brave')})`
|
|
58
|
+
description = `Auto-select (tavily: ${keyStatus('tavily')}, brave: ${keyStatus('brave')}, ollama: ${keyStatus('ollama')})`
|
|
55
59
|
} else {
|
|
56
60
|
description = `key: ${keyStatus(p)}`
|
|
57
61
|
}
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
/** Tool names for the Brave-backed custom search tools */
|
|
9
9
|
export const BRAVE_TOOL_NAMES = ["search-the-web", "search_and_read"];
|
|
10
10
|
|
|
11
|
+
/** All custom search tool names that should be disabled when native search is active */
|
|
12
|
+
export const CUSTOM_SEARCH_TOOL_NAMES = ["search-the-web", "search_and_read", "google_search"];
|
|
13
|
+
|
|
11
14
|
/** Thinking block types that require signature validation by the API */
|
|
12
15
|
const THINKING_TYPES = new Set(["thinking", "redacted_thinking"]);
|
|
13
16
|
|
|
@@ -57,27 +60,30 @@ export function stripThinkingFromHistory(
|
|
|
57
60
|
*/
|
|
58
61
|
export function registerNativeSearchHooks(pi: NativeSearchPI): { getIsAnthropic: () => boolean } {
|
|
59
62
|
let isAnthropicProvider = false;
|
|
63
|
+
let modelSelectFired = false;
|
|
60
64
|
|
|
61
65
|
// Track provider changes via model selection — also handles diagnostics
|
|
62
66
|
// since model_select fires AFTER session_start and knows the provider.
|
|
63
67
|
pi.on("model_select", async (event: any, ctx: any) => {
|
|
68
|
+
modelSelectFired = true;
|
|
64
69
|
const wasAnthropic = isAnthropicProvider;
|
|
65
70
|
isAnthropicProvider = event.model.provider === "anthropic";
|
|
66
71
|
|
|
67
72
|
const hasBrave = !!process.env.BRAVE_API_KEY;
|
|
68
73
|
|
|
69
|
-
// When Anthropic
|
|
70
|
-
|
|
74
|
+
// When Anthropic: disable all custom search tools — native web_search is
|
|
75
|
+
// server-side and more reliable. Custom tools cause confusion and failures.
|
|
76
|
+
if (isAnthropicProvider) {
|
|
71
77
|
const active = pi.getActiveTools();
|
|
72
78
|
pi.setActiveTools(
|
|
73
|
-
active.filter((t: string) => !
|
|
79
|
+
active.filter((t: string) => !CUSTOM_SEARCH_TOOL_NAMES.includes(t))
|
|
74
80
|
);
|
|
75
|
-
} else if (!isAnthropicProvider && wasAnthropic
|
|
76
|
-
// Switching away from Anthropic
|
|
77
|
-
//
|
|
78
|
-
//
|
|
81
|
+
} else if (!isAnthropicProvider && wasAnthropic) {
|
|
82
|
+
// Switching away from Anthropic — re-enable custom search tools (they
|
|
83
|
+
// were disabled while native search was active). If keys are missing,
|
|
84
|
+
// user sees the error rather than tools silently vanishing.
|
|
79
85
|
const active = pi.getActiveTools();
|
|
80
|
-
const toAdd =
|
|
86
|
+
const toAdd = CUSTOM_SEARCH_TOOL_NAMES.filter((t) => !active.includes(t));
|
|
81
87
|
if (toAdd.length > 0) {
|
|
82
88
|
pi.setActiveTools([...active, ...toAdd]);
|
|
83
89
|
}
|
|
@@ -99,11 +105,17 @@ export function registerNativeSearchHooks(pi: NativeSearchPI): { getIsAnthropic:
|
|
|
99
105
|
const payload = event.payload as Record<string, unknown>;
|
|
100
106
|
if (!payload) return;
|
|
101
107
|
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
|
|
108
|
+
// Detect Anthropic provider. Prefer the model_select flag when available,
|
|
109
|
+
// but fall back to checking the model name in the payload. model_select
|
|
110
|
+
// may not fire when the session restores with the same model already set
|
|
111
|
+
// (modelsAreEqual guard in the SDK suppresses the event). When model_select
|
|
112
|
+
// HAS fired and said "not Anthropic" (e.g. Copilot serving claude-*),
|
|
113
|
+
// respect that — don't override with model name heuristic.
|
|
114
|
+
const modelName = typeof payload.model === "string" ? payload.model : "";
|
|
115
|
+
const isAnthropic = modelSelectFired
|
|
116
|
+
? isAnthropicProvider
|
|
117
|
+
: modelName.startsWith("claude-");
|
|
118
|
+
if (!isAnthropic) return;
|
|
107
119
|
|
|
108
120
|
// Strip thinking blocks from history to avoid signature validation errors
|
|
109
121
|
// caused by the SDK dropping server_tool_use/web_search_tool_result blocks.
|
|
@@ -119,16 +131,13 @@ export function registerNativeSearchHooks(pi: NativeSearchPI): { getIsAnthropic:
|
|
|
119
131
|
// Don't double-inject if already present
|
|
120
132
|
if (tools.some((t) => t.type === "web_search_20250305")) return;
|
|
121
133
|
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
payload.tools = tools;
|
|
131
|
-
}
|
|
134
|
+
// Always remove custom search tool definitions from Anthropic requests.
|
|
135
|
+
// Native web_search is server-side and more reliable — keeping both confuses
|
|
136
|
+
// the model and causes it to pick custom tools which can fail with network errors.
|
|
137
|
+
tools = tools.filter(
|
|
138
|
+
(t) => !CUSTOM_SEARCH_TOOL_NAMES.includes(t.name as string)
|
|
139
|
+
);
|
|
140
|
+
payload.tools = tools;
|
|
132
141
|
|
|
133
142
|
tools.push({
|
|
134
143
|
type: "web_search_20250305",
|
|
@@ -18,10 +18,10 @@ import { join } from 'path'
|
|
|
18
18
|
// where the relative import '../../../app-paths.ts' doesn't resolve.
|
|
19
19
|
const authFilePath = join(homedir(), '.gsd', 'agent', 'auth.json')
|
|
20
20
|
|
|
21
|
-
export type SearchProvider = 'tavily' | 'brave'
|
|
21
|
+
export type SearchProvider = 'tavily' | 'brave' | 'ollama'
|
|
22
22
|
export type SearchProviderPreference = SearchProvider | 'auto'
|
|
23
23
|
|
|
24
|
-
const VALID_PREFERENCES = new Set<string>(['tavily', 'brave', 'auto'])
|
|
24
|
+
const VALID_PREFERENCES = new Set<string>(['tavily', 'brave', 'ollama', 'auto'])
|
|
25
25
|
const PREFERENCE_KEY = 'search_provider'
|
|
26
26
|
|
|
27
27
|
/** Returns the Tavily API key from the environment, or empty string if not set. */
|
|
@@ -34,6 +34,11 @@ export function getBraveApiKey(): string {
|
|
|
34
34
|
return process.env.BRAVE_API_KEY || ''
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/** Returns the Ollama API key from the environment, or empty string if not set. */
|
|
38
|
+
export function getOllamaApiKey(): string {
|
|
39
|
+
return process.env.OLLAMA_API_KEY || ''
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
/**
|
|
38
43
|
* Read the user's search provider preference from auth.json.
|
|
39
44
|
* Returns 'auto' if no preference is stored or the stored value is invalid.
|
|
@@ -78,9 +83,11 @@ export function setSearchProviderPreference(pref: SearchProviderPreference, auth
|
|
|
78
83
|
export function resolveSearchProvider(overridePreference?: string): SearchProvider | null {
|
|
79
84
|
const tavilyKey = getTavilyApiKey()
|
|
80
85
|
const braveKey = getBraveApiKey()
|
|
86
|
+
const ollamaKey = getOllamaApiKey()
|
|
81
87
|
|
|
82
88
|
const hasTavily = tavilyKey.length > 0
|
|
83
89
|
const hasBrave = braveKey.length > 0
|
|
90
|
+
const hasOllama = ollamaKey.length > 0
|
|
84
91
|
|
|
85
92
|
// Determine effective preference
|
|
86
93
|
let pref: SearchProviderPreference
|
|
@@ -100,18 +107,28 @@ export function resolveSearchProvider(overridePreference?: string): SearchProvid
|
|
|
100
107
|
if (pref === 'auto') {
|
|
101
108
|
if (hasTavily) return 'tavily'
|
|
102
109
|
if (hasBrave) return 'brave'
|
|
110
|
+
if (hasOllama) return 'ollama'
|
|
103
111
|
return null
|
|
104
112
|
}
|
|
105
113
|
|
|
106
114
|
if (pref === 'tavily') {
|
|
107
115
|
if (hasTavily) return 'tavily'
|
|
108
116
|
if (hasBrave) return 'brave'
|
|
117
|
+
if (hasOllama) return 'ollama'
|
|
109
118
|
return null
|
|
110
119
|
}
|
|
111
120
|
|
|
112
121
|
if (pref === 'brave') {
|
|
113
122
|
if (hasBrave) return 'brave'
|
|
114
123
|
if (hasTavily) return 'tavily'
|
|
124
|
+
if (hasOllama) return 'ollama'
|
|
125
|
+
return null
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (pref === 'ollama') {
|
|
129
|
+
if (hasOllama) return 'ollama'
|
|
130
|
+
if (hasTavily) return 'tavily'
|
|
131
|
+
if (hasBrave) return 'brave'
|
|
115
132
|
return null
|
|
116
133
|
}
|
|
117
134
|
|