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
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
// Instead of trying to mock out the entire `index.ts` extension initialization which touches
|
|
5
|
+
// the disk and parses files, we test the logic via the standard test methods, or we can
|
|
6
|
+
// just test that `resolveModelWithFallbacksForUnit` returns the correct format since
|
|
7
|
+
// the fallback rotation logic itself was verified manually.
|
|
8
|
+
|
|
9
|
+
import { getNextFallbackModel } from "../preferences.ts";
|
|
10
|
+
|
|
11
|
+
test("getNextFallbackModel selects next fallback if current is a fallback", () => {
|
|
12
|
+
const modelConfig = { primary: "model-a", fallbacks: ["model-b", "model-c"] };
|
|
13
|
+
const currentModelId = "model-b";
|
|
14
|
+
|
|
15
|
+
const nextModelId = getNextFallbackModel(currentModelId, modelConfig);
|
|
16
|
+
|
|
17
|
+
assert.equal(nextModelId, "model-c", "should select next model after current fallback");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("getNextFallbackModel returns undefined if fallbacks exhausted", () => {
|
|
21
|
+
const modelConfig = { primary: "model-a", fallbacks: ["model-b", "model-c"] };
|
|
22
|
+
const currentModelId = "model-c";
|
|
23
|
+
|
|
24
|
+
const nextModelId = getNextFallbackModel(currentModelId, modelConfig);
|
|
25
|
+
|
|
26
|
+
assert.equal(nextModelId, undefined, "should return undefined when exhausted");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("getNextFallbackModel finds current model when formatted with provider", () => {
|
|
30
|
+
const modelConfig = { primary: "p/model-a", fallbacks: ["p/model-b"] };
|
|
31
|
+
const currentModelId = "model-a"; // context model doesn't always have provider in ID
|
|
32
|
+
|
|
33
|
+
const nextModelId = getNextFallbackModel(currentModelId, modelConfig);
|
|
34
|
+
|
|
35
|
+
assert.equal(nextModelId, "p/model-b", "should select next model after current with provider format");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("getNextFallbackModel returns primary if current model is not in the list", () => {
|
|
39
|
+
const modelConfig = { primary: "model-a", fallbacks: ["model-b", "model-c"] };
|
|
40
|
+
const currentModelId = "model-x"; // completely different model manually selected
|
|
41
|
+
|
|
42
|
+
const nextModelId = getNextFallbackModel(currentModelId, modelConfig);
|
|
43
|
+
|
|
44
|
+
assert.equal(nextModelId, "model-a", "should default to primary if current is unknown");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("getNextFallbackModel returns primary if current model is undefined", () => {
|
|
48
|
+
const modelConfig = { primary: "model-a", fallbacks: ["model-b", "model-c"] };
|
|
49
|
+
const currentModelId = undefined;
|
|
50
|
+
|
|
51
|
+
const nextModelId = getNextFallbackModel(currentModelId, modelConfig);
|
|
52
|
+
|
|
53
|
+
assert.equal(nextModelId, "model-a", "should default to primary if current is undefined");
|
|
54
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Tests for nextMilestoneId and maxMilestoneNum — milestone ID generation
|
|
2
|
+
// using max-based approach to avoid collisions after deletions.
|
|
3
|
+
//
|
|
4
|
+
// Sections:
|
|
5
|
+
// (a) Empty array returns M001
|
|
6
|
+
// (b) Sequential IDs return next in sequence
|
|
7
|
+
// (c) IDs with gaps (deletion) use max, not fill
|
|
8
|
+
// (d) Non-numeric directory names mixed in are ignored
|
|
9
|
+
|
|
10
|
+
import { nextMilestoneId, maxMilestoneNum } from '../guided-flow.ts';
|
|
11
|
+
import { createTestContext } from './test-helpers.ts';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const { assertEq, report } = createTestContext();
|
|
15
|
+
// ─── Tests ─────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
async function main(): Promise<void> {
|
|
18
|
+
console.log('nextMilestoneId / maxMilestoneNum tests');
|
|
19
|
+
|
|
20
|
+
// (a) Empty array → M001
|
|
21
|
+
{
|
|
22
|
+
assertEq(maxMilestoneNum([]), 0, 'maxMilestoneNum([]) === 0');
|
|
23
|
+
assertEq(nextMilestoneId([]), 'M001', 'nextMilestoneId([]) === "M001"');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// (b) Sequential IDs → next in sequence
|
|
27
|
+
{
|
|
28
|
+
assertEq(
|
|
29
|
+
nextMilestoneId(['M001', 'M002', 'M003']),
|
|
30
|
+
'M004',
|
|
31
|
+
'sequential IDs return M004',
|
|
32
|
+
);
|
|
33
|
+
assertEq(maxMilestoneNum(['M001', 'M002', 'M003']), 3, 'max of sequential is 3');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// (c) IDs with gaps (deletion scenario) → uses max, not fill
|
|
37
|
+
{
|
|
38
|
+
assertEq(
|
|
39
|
+
nextMilestoneId(['M001', 'M003']),
|
|
40
|
+
'M004',
|
|
41
|
+
'gap scenario returns M004, not M002',
|
|
42
|
+
);
|
|
43
|
+
assertEq(maxMilestoneNum(['M001', 'M003']), 3, 'max with gap is 3');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// (d) Non-numeric directory names mixed in are ignored
|
|
47
|
+
{
|
|
48
|
+
assertEq(
|
|
49
|
+
nextMilestoneId(['M001', 'notes', '.DS_Store', 'M003']),
|
|
50
|
+
'M004',
|
|
51
|
+
'non-numeric names ignored, returns M004',
|
|
52
|
+
);
|
|
53
|
+
assertEq(
|
|
54
|
+
maxMilestoneNum(['M001', 'notes', '.DS_Store', 'M003']),
|
|
55
|
+
3,
|
|
56
|
+
'max ignores non-numeric entries',
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
report();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
main().catch((error) => {
|
|
64
|
+
console.error(error);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for orphaned completed slice branch detection.
|
|
3
|
+
*
|
|
4
|
+
* Verifies the git operations and detection logic that mergeOrphanedSliceBranches
|
|
5
|
+
* in auto.ts relies on — without importing auto.ts (which requires @gsd/pi-coding-agent).
|
|
6
|
+
* Uses execSync directly and roadmap-slices.ts (no pi-coding-agent dep) to replicate
|
|
7
|
+
* the detection logic.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync } from "node:fs";
|
|
11
|
+
import { execSync, execFileSync } from "node:child_process";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { tmpdir } from "node:os";
|
|
14
|
+
|
|
15
|
+
import { relMilestoneFile } from "../paths.ts";
|
|
16
|
+
import { parseRoadmapSlices } from "../roadmap-slices.ts";
|
|
17
|
+
|
|
18
|
+
// Inline SLICE_BRANCH_RE and parseSliceBranch to avoid importing worktree.ts,
|
|
19
|
+
// which transitively imports preferences.ts → @gsd/pi-coding-agent (not available in tests).
|
|
20
|
+
const SLICE_BRANCH_RE = /^gsd\/(?:([a-zA-Z0-9_-]+)\/)?(M\d+)\/(S\d+)$/;
|
|
21
|
+
|
|
22
|
+
function parseSliceBranch(
|
|
23
|
+
branchName: string,
|
|
24
|
+
): { worktreeName: string | null; milestoneId: string; sliceId: string } | null {
|
|
25
|
+
const match = branchName.match(SLICE_BRANCH_RE);
|
|
26
|
+
if (!match) return null;
|
|
27
|
+
return { worktreeName: match[1] ?? null, milestoneId: match[2]!, sliceId: match[3]! };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let passed = 0;
|
|
31
|
+
let failed = 0;
|
|
32
|
+
|
|
33
|
+
function assert(condition: boolean, message: string): void {
|
|
34
|
+
if (condition) {
|
|
35
|
+
passed++;
|
|
36
|
+
} else {
|
|
37
|
+
failed++;
|
|
38
|
+
console.error(` FAIL: ${message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function assertEq<T>(actual: T, expected: T, message: string): void {
|
|
43
|
+
if (JSON.stringify(actual) === JSON.stringify(expected)) {
|
|
44
|
+
passed++;
|
|
45
|
+
} else {
|
|
46
|
+
failed++;
|
|
47
|
+
console.error(
|
|
48
|
+
` FAIL: ${message} — expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function run(command: string, cwd: string): string {
|
|
54
|
+
return execSync(command, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function git(base: string, args: string[]): string {
|
|
58
|
+
try {
|
|
59
|
+
return execFileSync("git", args, {
|
|
60
|
+
cwd: base,
|
|
61
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
62
|
+
encoding: "utf-8",
|
|
63
|
+
}).trim();
|
|
64
|
+
} catch {
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Replicate the core orphan-detection logic from mergeOrphanedSliceBranches
|
|
71
|
+
* in auto.ts — using only paths.ts + roadmap-slices.ts + execSync (no pi-coding-agent deps).
|
|
72
|
+
* Returns a list of orphaned branch descriptors.
|
|
73
|
+
*/
|
|
74
|
+
function detectOrphanedSliceBranches(base: string): Array<{
|
|
75
|
+
branch: string;
|
|
76
|
+
milestoneId: string;
|
|
77
|
+
sliceId: string;
|
|
78
|
+
sliceTitle: string;
|
|
79
|
+
}> {
|
|
80
|
+
const orphans: Array<{
|
|
81
|
+
branch: string;
|
|
82
|
+
milestoneId: string;
|
|
83
|
+
sliceId: string;
|
|
84
|
+
sliceTitle: string;
|
|
85
|
+
}> = [];
|
|
86
|
+
|
|
87
|
+
const branchListRaw = git(base, ["branch", "--list", "gsd/*/*", "--format=%(refname:short)"]);
|
|
88
|
+
if (!branchListRaw) return orphans;
|
|
89
|
+
|
|
90
|
+
const branches = branchListRaw.split("\n").map(b => b.trim()).filter(Boolean);
|
|
91
|
+
for (const branch of branches) {
|
|
92
|
+
const parsed = parseSliceBranch(branch);
|
|
93
|
+
// Skip worktree-namespaced branches
|
|
94
|
+
if (!parsed || parsed.worktreeName) continue;
|
|
95
|
+
|
|
96
|
+
const { milestoneId, sliceId } = parsed;
|
|
97
|
+
|
|
98
|
+
// Skip if already merged (no commits ahead of main)
|
|
99
|
+
const aheadCount = git(base, ["rev-list", "--count", `main..${branch}`]);
|
|
100
|
+
if (!aheadCount || aheadCount === "0") continue;
|
|
101
|
+
|
|
102
|
+
// Read roadmap from the slice branch
|
|
103
|
+
const roadmapRelPath = relMilestoneFile(base, milestoneId, "ROADMAP");
|
|
104
|
+
const roadmapContent = git(base, ["show", `${branch}:${roadmapRelPath}`]);
|
|
105
|
+
if (!roadmapContent) continue;
|
|
106
|
+
|
|
107
|
+
const slices = parseRoadmapSlices(roadmapContent);
|
|
108
|
+
const sliceEntry = slices.find(s => s.id === sliceId);
|
|
109
|
+
if (!sliceEntry?.done) continue;
|
|
110
|
+
|
|
111
|
+
orphans.push({
|
|
112
|
+
branch,
|
|
113
|
+
milestoneId,
|
|
114
|
+
sliceId,
|
|
115
|
+
sliceTitle: sliceEntry.title || sliceId,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return orphans;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ─── Setup helpers ─────────────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
function initRepo(): string {
|
|
125
|
+
const repo = mkdtempSync(join(tmpdir(), "gsd-orphan-test-"));
|
|
126
|
+
run("git init -b main", repo);
|
|
127
|
+
run("git config user.email test@example.com", repo);
|
|
128
|
+
run("git config user.name Test", repo);
|
|
129
|
+
return repo;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function writeBaseArtifacts(repo: string): void {
|
|
133
|
+
mkdirSync(join(repo, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), {
|
|
134
|
+
recursive: true,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
writeFileSync(
|
|
138
|
+
join(repo, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
|
|
139
|
+
[
|
|
140
|
+
"# M001: Demo",
|
|
141
|
+
"",
|
|
142
|
+
"## Slices",
|
|
143
|
+
"- [ ] **S01: First Slice** `risk:low` `depends:[]`",
|
|
144
|
+
" > After this: feature works",
|
|
145
|
+
"",
|
|
146
|
+
].join("\n"),
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
writeFileSync(
|
|
150
|
+
join(repo, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md"),
|
|
151
|
+
"# S01: First Slice\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Must-Haves\n- done\n\n## Tasks\n- [x] **T01: Task** `est:5m`\n do it\n",
|
|
152
|
+
);
|
|
153
|
+
run("git add .", repo);
|
|
154
|
+
run('git commit -m "chore: milestone base"', repo);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function writeCompletedArtifactsOnBranch(repo: string): void {
|
|
158
|
+
writeFileSync(
|
|
159
|
+
join(repo, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
|
|
160
|
+
[
|
|
161
|
+
"# M001: Demo",
|
|
162
|
+
"",
|
|
163
|
+
"## Slices",
|
|
164
|
+
"- [x] **S01: First Slice** `risk:low` `depends:[]`",
|
|
165
|
+
" > After this: feature works",
|
|
166
|
+
"",
|
|
167
|
+
].join("\n"),
|
|
168
|
+
);
|
|
169
|
+
writeFileSync(
|
|
170
|
+
join(repo, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md"),
|
|
171
|
+
"# S01: First Slice\n\nDone.\n",
|
|
172
|
+
);
|
|
173
|
+
writeFileSync(
|
|
174
|
+
join(repo, ".gsd", "milestones", "M001", "slices", "S01", "S01-UAT.md"),
|
|
175
|
+
"# UAT\n\nPassed.\n",
|
|
176
|
+
);
|
|
177
|
+
run("git add .", repo);
|
|
178
|
+
run('git commit -m "feat(M001/S01): complete-slice"', repo);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ─── Tests ────────────────────────────────────────────────────────────────────
|
|
182
|
+
|
|
183
|
+
console.log("\n=== parseSliceBranch: plain branch ===");
|
|
184
|
+
{
|
|
185
|
+
const parsed = parseSliceBranch("gsd/M001/S01");
|
|
186
|
+
assert(parsed !== null, "plain branch parsed");
|
|
187
|
+
assertEq(parsed?.milestoneId, "M001", "milestone ID extracted");
|
|
188
|
+
assertEq(parsed?.sliceId, "S01", "slice ID extracted");
|
|
189
|
+
assertEq(parsed?.worktreeName, null, "no worktree name for plain branch");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
console.log("\n=== parseSliceBranch: worktree-namespaced branch ===");
|
|
193
|
+
{
|
|
194
|
+
const parsed = parseSliceBranch("gsd/wt1/M001/S01");
|
|
195
|
+
assert(parsed !== null, "worktree branch parsed");
|
|
196
|
+
assertEq(parsed?.milestoneId, "M001", "milestone ID extracted from worktree branch");
|
|
197
|
+
assertEq(parsed?.sliceId, "S01", "slice ID extracted from worktree branch");
|
|
198
|
+
assertEq(parsed?.worktreeName, "wt1", "worktree name extracted");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
console.log("\n=== parseSliceBranch: non-slice branch not matched ===");
|
|
202
|
+
{
|
|
203
|
+
assert(parseSliceBranch("main") === null, "main branch not matched");
|
|
204
|
+
assert(parseSliceBranch("gsd/M001") === null, "bare milestone branch not matched");
|
|
205
|
+
assert(!SLICE_BRANCH_RE.test("gsd/M001"), "bare milestone branch not matched by regex");
|
|
206
|
+
assert(SLICE_BRANCH_RE.test("gsd/M001/S01"), "standard slice branch matched by regex");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
console.log("\n=== orphan detection: no slice branches ===");
|
|
210
|
+
{
|
|
211
|
+
const repo = initRepo();
|
|
212
|
+
writeBaseArtifacts(repo);
|
|
213
|
+
|
|
214
|
+
const orphans = detectOrphanedSliceBranches(repo);
|
|
215
|
+
assertEq(orphans.length, 0, "no orphans when no slice branches exist");
|
|
216
|
+
|
|
217
|
+
rmSync(repo, { recursive: true, force: true });
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
console.log("\n=== orphan detection: slice branch not done ===");
|
|
221
|
+
{
|
|
222
|
+
const repo = initRepo();
|
|
223
|
+
writeBaseArtifacts(repo);
|
|
224
|
+
|
|
225
|
+
run("git checkout -b gsd/M001/S01", repo);
|
|
226
|
+
writeFileSync(
|
|
227
|
+
join(repo, ".gsd", "milestones", "M001", "slices", "S01", "S01-RESEARCH.md"),
|
|
228
|
+
"# Research\n",
|
|
229
|
+
);
|
|
230
|
+
run("git add .", repo);
|
|
231
|
+
run('git commit -m "feat: research"', repo);
|
|
232
|
+
run("git checkout main", repo);
|
|
233
|
+
|
|
234
|
+
const orphans = detectOrphanedSliceBranches(repo);
|
|
235
|
+
assertEq(orphans.length, 0, "incomplete slice branch is not reported as orphan");
|
|
236
|
+
|
|
237
|
+
rmSync(repo, { recursive: true, force: true });
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
console.log("\n=== orphan detection: completed slice branch (orphaned) ===");
|
|
241
|
+
{
|
|
242
|
+
const repo = initRepo();
|
|
243
|
+
writeBaseArtifacts(repo);
|
|
244
|
+
|
|
245
|
+
run("git checkout -b gsd/M001/S01", repo);
|
|
246
|
+
writeCompletedArtifactsOnBranch(repo);
|
|
247
|
+
// Return to main without merging — this is the orphaned branch scenario
|
|
248
|
+
run("git checkout main", repo);
|
|
249
|
+
|
|
250
|
+
const orphans = detectOrphanedSliceBranches(repo);
|
|
251
|
+
assertEq(orphans.length, 1, "completed but unmerged branch detected as orphan");
|
|
252
|
+
assertEq(orphans[0]?.branch, "gsd/M001/S01", "correct branch name reported");
|
|
253
|
+
assertEq(orphans[0]?.milestoneId, "M001", "correct milestone ID");
|
|
254
|
+
assertEq(orphans[0]?.sliceId, "S01", "correct slice ID");
|
|
255
|
+
assertEq(orphans[0]?.sliceTitle, "First Slice", "correct slice title");
|
|
256
|
+
|
|
257
|
+
rmSync(repo, { recursive: true, force: true });
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
console.log("\n=== orphan detection: already merged branch is not orphan ===");
|
|
261
|
+
{
|
|
262
|
+
const repo = initRepo();
|
|
263
|
+
writeBaseArtifacts(repo);
|
|
264
|
+
|
|
265
|
+
run("git checkout -b gsd/M001/S01", repo);
|
|
266
|
+
writeCompletedArtifactsOnBranch(repo);
|
|
267
|
+
run("git checkout main", repo);
|
|
268
|
+
run("git merge --squash gsd/M001/S01", repo);
|
|
269
|
+
run('git commit -m "feat(M001/S01): merge"', repo);
|
|
270
|
+
run("git branch -D gsd/M001/S01", repo);
|
|
271
|
+
|
|
272
|
+
const orphans = detectOrphanedSliceBranches(repo);
|
|
273
|
+
assertEq(orphans.length, 0, "already-merged branch is not detected as orphan");
|
|
274
|
+
|
|
275
|
+
rmSync(repo, { recursive: true, force: true });
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
console.log("\n=== orphan detection: worktree-namespaced branch is skipped ===");
|
|
279
|
+
{
|
|
280
|
+
const repo = initRepo();
|
|
281
|
+
writeBaseArtifacts(repo);
|
|
282
|
+
|
|
283
|
+
// gsd/wt1/M001/S01 — worktree-namespaced branches are managed by the worktree
|
|
284
|
+
// manager and must not be merged by the main-tree orphan check.
|
|
285
|
+
run("git checkout -b gsd/wt1/M001/S01", repo);
|
|
286
|
+
writeCompletedArtifactsOnBranch(repo);
|
|
287
|
+
run("git checkout main", repo);
|
|
288
|
+
|
|
289
|
+
const orphans = detectOrphanedSliceBranches(repo);
|
|
290
|
+
assertEq(orphans.length, 0, "worktree-namespaced branch not detected by main-tree orphan check");
|
|
291
|
+
|
|
292
|
+
rmSync(repo, { recursive: true, force: true });
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
console.log("\n=== orphan detection: relMilestoneFile resolves roadmap path for git show ===");
|
|
296
|
+
{
|
|
297
|
+
const repo = initRepo();
|
|
298
|
+
writeBaseArtifacts(repo);
|
|
299
|
+
|
|
300
|
+
run("git checkout -b gsd/M001/S01", repo);
|
|
301
|
+
writeCompletedArtifactsOnBranch(repo);
|
|
302
|
+
run("git checkout main", repo);
|
|
303
|
+
|
|
304
|
+
// Simulate what mergeOrphanedSliceBranches does: read roadmap from branch
|
|
305
|
+
const roadmapRelPath = relMilestoneFile(repo, "M001", "ROADMAP");
|
|
306
|
+
const roadmapOnBranch = git(repo, ["show", `gsd/M001/S01:${roadmapRelPath}`]);
|
|
307
|
+
assert(roadmapOnBranch.length > 0, "roadmap readable from orphaned branch via git show");
|
|
308
|
+
|
|
309
|
+
const slices = parseRoadmapSlices(roadmapOnBranch);
|
|
310
|
+
const s01 = slices.find(s => s.id === "S01");
|
|
311
|
+
assert(s01?.done === true, "slice marked done on orphaned branch");
|
|
312
|
+
|
|
313
|
+
rmSync(repo, { recursive: true, force: true });
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
console.log("\n=== orphan merge: squash-merge resolves orphan, artifacts appear on main ===");
|
|
317
|
+
{
|
|
318
|
+
const repo = initRepo();
|
|
319
|
+
writeBaseArtifacts(repo);
|
|
320
|
+
|
|
321
|
+
run("git checkout -b gsd/M001/S01", repo);
|
|
322
|
+
writeCompletedArtifactsOnBranch(repo);
|
|
323
|
+
run("git checkout main", repo);
|
|
324
|
+
|
|
325
|
+
const orphansBefore = detectOrphanedSliceBranches(repo);
|
|
326
|
+
assertEq(orphansBefore.length, 1, "orphan detected before merge");
|
|
327
|
+
|
|
328
|
+
// Perform squash-merge (as mergeOrphanedSliceBranches does via mergeSliceToMain)
|
|
329
|
+
run("git merge --squash gsd/M001/S01", repo);
|
|
330
|
+
run('git commit -m "feat(M001/S01): recover orphaned branch"', repo);
|
|
331
|
+
run("git branch -D gsd/M001/S01", repo);
|
|
332
|
+
|
|
333
|
+
// Verify artifacts are now on main
|
|
334
|
+
assert(
|
|
335
|
+
existsSync(
|
|
336
|
+
join(repo, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md"),
|
|
337
|
+
),
|
|
338
|
+
"SUMMARY merged to main after orphan recovery",
|
|
339
|
+
);
|
|
340
|
+
assert(
|
|
341
|
+
existsSync(join(repo, ".gsd", "milestones", "M001", "slices", "S01", "S01-UAT.md")),
|
|
342
|
+
"UAT merged to main after orphan recovery",
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
// Orphan no longer detected after merge + branch delete
|
|
346
|
+
const orphansAfter = detectOrphanedSliceBranches(repo);
|
|
347
|
+
assertEq(orphansAfter.length, 0, "no orphans after merge and branch deletion");
|
|
348
|
+
|
|
349
|
+
rmSync(repo, { recursive: true, force: true });
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
console.log(`\nResults: ${passed} passed, ${failed} failed`);
|
|
353
|
+
if (failed > 0) process.exit(1);
|