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
|
@@ -16,19 +16,20 @@ import type {
|
|
|
16
16
|
ExtensionCommandContext,
|
|
17
17
|
} from "@gsd/pi-coding-agent";
|
|
18
18
|
|
|
19
|
-
import { deriveState } from "./state.js";
|
|
19
|
+
import { deriveState, invalidateStateCache } from "./state.js";
|
|
20
20
|
import type { GSDState } from "./types.js";
|
|
21
|
-
import { loadFile, parseContinue, parsePlan, parseRoadmap, parseSummary, extractUatType, inlinePriorMilestoneSummary, getManifestStatus } from "./files.js";
|
|
21
|
+
import { loadFile, parseContinue, parsePlan, parseRoadmap, parseSummary, extractUatType, inlinePriorMilestoneSummary, getManifestStatus, clearParseCache } from "./files.js";
|
|
22
22
|
export { inlinePriorMilestoneSummary };
|
|
23
23
|
import type { UatType } from "./files.js";
|
|
24
24
|
import { collectSecretsFromManifest } from "../get-secrets-from-user.js";
|
|
25
|
-
import { loadPrompt } from "./prompt-loader.js";
|
|
25
|
+
import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
|
|
26
26
|
import {
|
|
27
27
|
gsdRoot, resolveMilestoneFile, resolveSliceFile, resolveSlicePath,
|
|
28
28
|
resolveMilestonePath, resolveDir, resolveTasksDir, resolveTaskFiles, resolveTaskFile,
|
|
29
29
|
relMilestoneFile, relSliceFile, relTaskFile, relSlicePath, relMilestonePath,
|
|
30
30
|
milestonesDir, resolveGsdRootFile, relGsdRootFile,
|
|
31
31
|
buildMilestoneFileName, buildSliceFileName, buildTaskFileName,
|
|
32
|
+
clearPathCache,
|
|
32
33
|
} from "./paths.js";
|
|
33
34
|
import { saveActivityLog } from "./activity-log.js";
|
|
34
35
|
import { synthesizeCrashRecovery, getDeepDiagnostic } from "./session-forensics.js";
|
|
@@ -42,6 +43,18 @@ import {
|
|
|
42
43
|
} from "./unit-runtime.js";
|
|
43
44
|
import { resolveAutoSupervisorConfig, resolveModelForUnit, resolveModelWithFallbacksForUnit, resolveSkillDiscoveryMode, loadEffectiveGSDPreferences } from "./preferences.js";
|
|
44
45
|
import type { GSDPreferences } from "./preferences.js";
|
|
46
|
+
import {
|
|
47
|
+
checkPostUnitHooks,
|
|
48
|
+
getActiveHook,
|
|
49
|
+
resetHookState,
|
|
50
|
+
isRetryPending,
|
|
51
|
+
consumeRetryTrigger,
|
|
52
|
+
runPreDispatchHooks,
|
|
53
|
+
persistHookState,
|
|
54
|
+
restoreHookState,
|
|
55
|
+
clearPersistedHookState,
|
|
56
|
+
formatHookStatus,
|
|
57
|
+
} from "./post-unit-hooks.js";
|
|
45
58
|
import {
|
|
46
59
|
validatePlanBoundary,
|
|
47
60
|
validateExecuteBoundary,
|
|
@@ -71,6 +84,7 @@ import {
|
|
|
71
84
|
mergeSliceToMain,
|
|
72
85
|
} from "./worktree.js";
|
|
73
86
|
import { GitServiceImpl, runGit } from "./git-service.js";
|
|
87
|
+
import { nativeCommitCountBetween } from "./native-git-bridge.js";
|
|
74
88
|
import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
|
|
75
89
|
import type { GitPreferences } from "./git-service.js";
|
|
76
90
|
import { truncateToWidth, visibleWidth } from "@gsd/pi-tui";
|
|
@@ -164,6 +178,14 @@ let unitTimeoutHandle: ReturnType<typeof setTimeout> | null = null;
|
|
|
164
178
|
let wrapupWarningHandle: ReturnType<typeof setTimeout> | null = null;
|
|
165
179
|
let idleWatchdogHandle: ReturnType<typeof setInterval> | null = null;
|
|
166
180
|
|
|
181
|
+
/** Dispatch gap watchdog — detects when the state machine stalls between units.
|
|
182
|
+
* After handleAgentEnd completes, if auto-mode is still active but no new unit
|
|
183
|
+
* has been dispatched (sendMessage not called), this timer fires to force a
|
|
184
|
+
* re-evaluation. Covers the case where dispatchNextUnit silently fails or
|
|
185
|
+
* an unhandled error kills the dispatch chain. */
|
|
186
|
+
let dispatchGapHandle: ReturnType<typeof setTimeout> | null = null;
|
|
187
|
+
const DISPATCH_GAP_TIMEOUT_MS = 5_000; // 5 seconds
|
|
188
|
+
|
|
167
189
|
/** SIGTERM handler registered while auto-mode is active — cleared on stop/pause. */
|
|
168
190
|
let _sigtermHandler: (() => void) | null = null;
|
|
169
191
|
|
|
@@ -269,6 +291,48 @@ function clearUnitTimeout(): void {
|
|
|
269
291
|
clearInterval(idleWatchdogHandle);
|
|
270
292
|
idleWatchdogHandle = null;
|
|
271
293
|
}
|
|
294
|
+
clearDispatchGapWatchdog();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function clearDispatchGapWatchdog(): void {
|
|
298
|
+
if (dispatchGapHandle) {
|
|
299
|
+
clearTimeout(dispatchGapHandle);
|
|
300
|
+
dispatchGapHandle = null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Start a watchdog that fires if no new unit is dispatched within DISPATCH_GAP_TIMEOUT_MS
|
|
306
|
+
* after handleAgentEnd completes. This catches the case where the dispatch chain silently
|
|
307
|
+
* breaks (e.g., unhandled exception in dispatchNextUnit) and auto-mode is left active but idle.
|
|
308
|
+
*
|
|
309
|
+
* The watchdog is cleared on the next successful unit dispatch (clearUnitTimeout is called
|
|
310
|
+
* at the start of handleAgentEnd, which calls clearDispatchGapWatchdog).
|
|
311
|
+
*/
|
|
312
|
+
function startDispatchGapWatchdog(ctx: ExtensionContext, pi: ExtensionAPI): void {
|
|
313
|
+
clearDispatchGapWatchdog();
|
|
314
|
+
dispatchGapHandle = setTimeout(async () => {
|
|
315
|
+
dispatchGapHandle = null;
|
|
316
|
+
if (!active || !cmdCtx) return;
|
|
317
|
+
|
|
318
|
+
// Auto-mode is active but no unit was dispatched — the state machine stalled.
|
|
319
|
+
// Re-derive state and attempt a fresh dispatch.
|
|
320
|
+
ctx.ui.notify(
|
|
321
|
+
"Dispatch gap detected — no unit dispatched after previous unit completed. Re-evaluating state.",
|
|
322
|
+
"warning",
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
try {
|
|
326
|
+
await dispatchNextUnit(ctx, pi);
|
|
327
|
+
} catch (retryErr) {
|
|
328
|
+
const message = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
329
|
+
ctx.ui.notify(
|
|
330
|
+
`Dispatch gap recovery failed: ${message}. Stopping auto-mode.`,
|
|
331
|
+
"error",
|
|
332
|
+
);
|
|
333
|
+
await stopAuto(ctx, pi);
|
|
334
|
+
}
|
|
335
|
+
}, DISPATCH_GAP_TIMEOUT_MS);
|
|
272
336
|
}
|
|
273
337
|
|
|
274
338
|
export async function stopAuto(ctx?: ExtensionContext, pi?: ExtensionAPI): Promise<void> {
|
|
@@ -296,6 +360,8 @@ export async function stopAuto(ctx?: ExtensionContext, pi?: ExtensionAPI): Promi
|
|
|
296
360
|
}
|
|
297
361
|
|
|
298
362
|
resetMetrics();
|
|
363
|
+
resetHookState();
|
|
364
|
+
if (basePath) clearPersistedHookState(basePath);
|
|
299
365
|
active = false;
|
|
300
366
|
paused = false;
|
|
301
367
|
stepMode = false;
|
|
@@ -423,12 +489,8 @@ async function mergeOrphanedSliceBranches(
|
|
|
423
489
|
|
|
424
490
|
// Skip if already merged (no commits ahead of main)
|
|
425
491
|
const mainBranch = getMainBranch(base);
|
|
426
|
-
const aheadCount =
|
|
427
|
-
|
|
428
|
-
["rev-list", "--count", `${mainBranch}..${branch}`],
|
|
429
|
-
{ allowFailure: true },
|
|
430
|
-
);
|
|
431
|
-
if (!aheadCount || aheadCount === "0") continue;
|
|
492
|
+
const aheadCount = nativeCommitCountBetween(base, mainBranch, branch);
|
|
493
|
+
if (aheadCount === 0) continue;
|
|
432
494
|
|
|
433
495
|
// Read the roadmap from the slice branch to check if the slice is done.
|
|
434
496
|
// relMilestoneFile resolves the actual directory name on disk (handles
|
|
@@ -517,6 +579,8 @@ export async function startAuto(
|
|
|
517
579
|
ctx.ui.setStatus("gsd-auto", stepMode ? "next" : "auto");
|
|
518
580
|
ctx.ui.setFooter(hideFooter);
|
|
519
581
|
ctx.ui.notify(stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "info");
|
|
582
|
+
// Restore hook state from disk in case session was interrupted
|
|
583
|
+
restoreHookState(base);
|
|
520
584
|
// Rebuild disk state before resuming — user interaction during pause may have changed files
|
|
521
585
|
try { await rebuildState(base); } catch { /* non-fatal */ }
|
|
522
586
|
try {
|
|
@@ -527,6 +591,9 @@ export async function startAuto(
|
|
|
527
591
|
} catch { /* non-fatal */ }
|
|
528
592
|
// Self-heal: clear stale runtime records where artifacts already exist
|
|
529
593
|
await selfHealRuntimeRecords(base, ctx);
|
|
594
|
+
invalidateStateCache();
|
|
595
|
+
clearParseCache();
|
|
596
|
+
clearPathCache();
|
|
530
597
|
await dispatchNextUnit(ctx, pi);
|
|
531
598
|
return;
|
|
532
599
|
}
|
|
@@ -622,6 +689,8 @@ export async function startAuto(
|
|
|
622
689
|
unitRecoveryCount.clear();
|
|
623
690
|
completedKeySet.clear();
|
|
624
691
|
loadPersistedKeys(base, completedKeySet);
|
|
692
|
+
resetHookState();
|
|
693
|
+
restoreHookState(base);
|
|
625
694
|
autoStartTime = Date.now();
|
|
626
695
|
completedUnits = [];
|
|
627
696
|
currentUnit = null;
|
|
@@ -716,6 +785,12 @@ export async function handleAgentEnd(
|
|
|
716
785
|
// Unit completed — clear its timeout
|
|
717
786
|
clearUnitTimeout();
|
|
718
787
|
|
|
788
|
+
// Invalidate deriveState() cache — the unit just completed and may have
|
|
789
|
+
// written planning files (task summaries, roadmap checkboxes, etc.)
|
|
790
|
+
invalidateStateCache();
|
|
791
|
+
clearParseCache();
|
|
792
|
+
clearPathCache();
|
|
793
|
+
|
|
719
794
|
// Small delay to let files settle (git commits, file writes)
|
|
720
795
|
await new Promise(r => setTimeout(r, 500));
|
|
721
796
|
|
|
@@ -754,13 +829,109 @@ export async function handleAgentEnd(
|
|
|
754
829
|
}
|
|
755
830
|
}
|
|
756
831
|
|
|
832
|
+
// ── Post-unit hooks: check if a configured hook should run before normal dispatch ──
|
|
833
|
+
if (currentUnit && !stepMode) {
|
|
834
|
+
const hookUnit = checkPostUnitHooks(currentUnit.type, currentUnit.id, basePath);
|
|
835
|
+
if (hookUnit) {
|
|
836
|
+
// Dispatch the hook unit instead of normal flow
|
|
837
|
+
const hookStartedAt = Date.now();
|
|
838
|
+
if (currentUnit) {
|
|
839
|
+
const modelId = ctx.model?.id ?? "unknown";
|
|
840
|
+
snapshotUnitMetrics(ctx, currentUnit.type, currentUnit.id, currentUnit.startedAt, modelId);
|
|
841
|
+
saveActivityLog(ctx, basePath, currentUnit.type, currentUnit.id);
|
|
842
|
+
}
|
|
843
|
+
currentUnit = { type: hookUnit.unitType, id: hookUnit.unitId, startedAt: hookStartedAt };
|
|
844
|
+
writeUnitRuntimeRecord(basePath, hookUnit.unitType, hookUnit.unitId, hookStartedAt, {
|
|
845
|
+
phase: "dispatched",
|
|
846
|
+
wrapupWarningSent: false,
|
|
847
|
+
timeoutAt: null,
|
|
848
|
+
lastProgressAt: hookStartedAt,
|
|
849
|
+
progressCount: 0,
|
|
850
|
+
lastProgressKind: "dispatch",
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
const state = await deriveState(basePath);
|
|
854
|
+
updateProgressWidget(ctx, hookUnit.unitType, hookUnit.unitId, state);
|
|
855
|
+
const hookState = getActiveHook();
|
|
856
|
+
ctx.ui.notify(
|
|
857
|
+
`Running post-unit hook: ${hookUnit.hookName} (cycle ${hookState?.cycle ?? 1})`,
|
|
858
|
+
"info",
|
|
859
|
+
);
|
|
860
|
+
|
|
861
|
+
// Switch model if the hook specifies one
|
|
862
|
+
if (hookUnit.model) {
|
|
863
|
+
const availableModels = ctx.modelRegistry.getAvailable();
|
|
864
|
+
const match = availableModels.find(m =>
|
|
865
|
+
m.id === hookUnit.model || `${m.provider}/${m.id}` === hookUnit.model,
|
|
866
|
+
);
|
|
867
|
+
if (match) {
|
|
868
|
+
try {
|
|
869
|
+
await pi.setModel(match);
|
|
870
|
+
} catch { /* non-fatal — use current model */ }
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
const result = await cmdCtx!.newSession();
|
|
875
|
+
if (result.cancelled) {
|
|
876
|
+
resetHookState();
|
|
877
|
+
await stopAuto(ctx, pi);
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
const sessionFile = ctx.sessionManager.getSessionFile();
|
|
881
|
+
writeLock(basePath, hookUnit.unitType, hookUnit.unitId, completedUnits.length, sessionFile);
|
|
882
|
+
// Persist hook state so cycle counts survive crashes
|
|
883
|
+
persistHookState(basePath);
|
|
884
|
+
pi.sendMessage(
|
|
885
|
+
{ customType: "gsd-auto", content: hookUnit.prompt, display: verbose },
|
|
886
|
+
{ triggerTurn: true },
|
|
887
|
+
);
|
|
888
|
+
return; // handleAgentEnd will fire again when hook session completes
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// Check if a hook requested a retry of the trigger unit
|
|
892
|
+
if (isRetryPending()) {
|
|
893
|
+
const trigger = consumeRetryTrigger();
|
|
894
|
+
if (trigger) {
|
|
895
|
+
ctx.ui.notify(
|
|
896
|
+
`Hook requested retry of ${trigger.unitType} ${trigger.unitId}.`,
|
|
897
|
+
"info",
|
|
898
|
+
);
|
|
899
|
+
// Fall through to normal dispatchNextUnit — state derivation will
|
|
900
|
+
// re-select the same unit since it hasn't been marked complete
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
757
905
|
// In step mode, pause and show a wizard instead of immediately dispatching
|
|
758
906
|
if (stepMode) {
|
|
759
907
|
await showStepWizard(ctx, pi);
|
|
760
908
|
return;
|
|
761
909
|
}
|
|
762
910
|
|
|
763
|
-
|
|
911
|
+
try {
|
|
912
|
+
await dispatchNextUnit(ctx, pi);
|
|
913
|
+
} catch (dispatchErr) {
|
|
914
|
+
// dispatchNextUnit threw — without this catch the error would propagate
|
|
915
|
+
// to the pi event emitter which may silently swallow async rejections,
|
|
916
|
+
// leaving auto-mode active but permanently stalled (see #381).
|
|
917
|
+
const message = dispatchErr instanceof Error ? dispatchErr.message : String(dispatchErr);
|
|
918
|
+
ctx.ui.notify(
|
|
919
|
+
`Dispatch error after unit completion: ${message}. Retrying in ${DISPATCH_GAP_TIMEOUT_MS / 1000}s.`,
|
|
920
|
+
"error",
|
|
921
|
+
);
|
|
922
|
+
|
|
923
|
+
// Start the dispatch gap watchdog to retry after a delay.
|
|
924
|
+
// This gives transient issues (dirty working tree, branch state) time to settle.
|
|
925
|
+
startDispatchGapWatchdog(ctx, pi);
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
// If dispatchNextUnit returned normally but auto-mode is still active and
|
|
930
|
+
// no new unit timeout was set (meaning sendMessage was never called), start
|
|
931
|
+
// the dispatch gap watchdog as a safety net.
|
|
932
|
+
if (active && !unitTimeoutHandle && !wrapupWarningHandle) {
|
|
933
|
+
startDispatchGapWatchdog(ctx, pi);
|
|
934
|
+
}
|
|
764
935
|
|
|
765
936
|
} finally {
|
|
766
937
|
_handlingAgentEnd = false;
|
|
@@ -874,6 +1045,7 @@ export function describeNextUnit(state: GSDState): { label: string; description:
|
|
|
874
1045
|
// ─── Progress Widget ──────────────────────────────────────────────────────
|
|
875
1046
|
|
|
876
1047
|
function unitVerb(unitType: string): string {
|
|
1048
|
+
if (unitType.startsWith("hook/")) return `hook: ${unitType.slice(5)}`;
|
|
877
1049
|
switch (unitType) {
|
|
878
1050
|
case "research-milestone":
|
|
879
1051
|
case "research-slice": return "researching";
|
|
@@ -890,6 +1062,7 @@ function unitVerb(unitType: string): string {
|
|
|
890
1062
|
}
|
|
891
1063
|
|
|
892
1064
|
function unitPhaseLabel(unitType: string): string {
|
|
1065
|
+
if (unitType.startsWith("hook/")) return "HOOK";
|
|
893
1066
|
switch (unitType) {
|
|
894
1067
|
case "research-milestone": return "RESEARCH";
|
|
895
1068
|
case "research-slice": return "RESEARCH";
|
|
@@ -906,7 +1079,14 @@ function unitPhaseLabel(unitType: string): string {
|
|
|
906
1079
|
}
|
|
907
1080
|
|
|
908
1081
|
function peekNext(unitType: string, state: GSDState): string {
|
|
1082
|
+
// Show active hook info in progress display
|
|
1083
|
+
const activeHookState = getActiveHook();
|
|
1084
|
+
if (activeHookState) {
|
|
1085
|
+
return `hook: ${activeHookState.hookName} (cycle ${activeHookState.cycle})`;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
909
1088
|
const sid = state.activeSlice?.id ?? "";
|
|
1089
|
+
if (unitType.startsWith("hook/")) return `continue ${sid}`;
|
|
910
1090
|
switch (unitType) {
|
|
911
1091
|
case "research-milestone": return "plan milestone roadmap";
|
|
912
1092
|
case "plan-milestone": return "plan or execute first slice";
|
|
@@ -1092,7 +1272,14 @@ function updateProgressWidget(
|
|
|
1092
1272
|
.join(theme.fg("dim", " "));
|
|
1093
1273
|
|
|
1094
1274
|
const modelId = cmdCtx?.model?.id ?? "";
|
|
1095
|
-
const
|
|
1275
|
+
const modelProvider = cmdCtx?.model?.provider ?? "";
|
|
1276
|
+
const modelPhase = phaseLabel ? theme.fg("dim", `[${phaseLabel}] `) : "";
|
|
1277
|
+
const modelDisplay = modelProvider && modelId
|
|
1278
|
+
? `${modelProvider}/${modelId}`
|
|
1279
|
+
: modelId;
|
|
1280
|
+
const sRight = modelDisplay
|
|
1281
|
+
? `${modelPhase}${theme.fg("dim", modelDisplay)}`
|
|
1282
|
+
: "";
|
|
1096
1283
|
lines.push(rightAlign(`${pad}${sLeft}`, sRight, width));
|
|
1097
1284
|
}
|
|
1098
1285
|
|
|
@@ -1193,6 +1380,9 @@ async function dispatchNextUnit(
|
|
|
1193
1380
|
return;
|
|
1194
1381
|
}
|
|
1195
1382
|
|
|
1383
|
+
// Clear stale directory listing cache so deriveState sees fresh disk state (#431)
|
|
1384
|
+
clearPathCache();
|
|
1385
|
+
|
|
1196
1386
|
let state = await deriveState(basePath);
|
|
1197
1387
|
let mid = state.activeMilestone?.id;
|
|
1198
1388
|
let midTitle = state.activeMilestone?.title;
|
|
@@ -1255,6 +1445,9 @@ async function dispatchNextUnit(
|
|
|
1255
1445
|
}
|
|
1256
1446
|
}
|
|
1257
1447
|
// Re-derive state from the now-merged working tree
|
|
1448
|
+
invalidateStateCache();
|
|
1449
|
+
clearParseCache();
|
|
1450
|
+
clearPathCache();
|
|
1258
1451
|
state = await deriveState(basePath);
|
|
1259
1452
|
mid = state.activeMilestone?.id;
|
|
1260
1453
|
midTitle = state.activeMilestone?.title;
|
|
@@ -1319,6 +1512,9 @@ async function dispatchNextUnit(
|
|
|
1319
1512
|
"info",
|
|
1320
1513
|
);
|
|
1321
1514
|
// Re-derive state from main so downstream logic sees merged state
|
|
1515
|
+
invalidateStateCache();
|
|
1516
|
+
clearParseCache();
|
|
1517
|
+
clearPathCache();
|
|
1322
1518
|
state = await deriveState(basePath);
|
|
1323
1519
|
mid = state.activeMilestone?.id;
|
|
1324
1520
|
midTitle = state.activeMilestone?.title;
|
|
@@ -1631,6 +1827,28 @@ async function dispatchNextUnit(
|
|
|
1631
1827
|
}
|
|
1632
1828
|
}
|
|
1633
1829
|
|
|
1830
|
+
// ── Pre-dispatch hooks: modify, skip, or replace the unit before dispatch ──
|
|
1831
|
+
const preDispatchResult = runPreDispatchHooks(unitType, unitId, prompt, basePath);
|
|
1832
|
+
if (preDispatchResult.firedHooks.length > 0) {
|
|
1833
|
+
ctx.ui.notify(
|
|
1834
|
+
`Pre-dispatch hook${preDispatchResult.firedHooks.length > 1 ? "s" : ""}: ${preDispatchResult.firedHooks.join(", ")}`,
|
|
1835
|
+
"info",
|
|
1836
|
+
);
|
|
1837
|
+
}
|
|
1838
|
+
if (preDispatchResult.action === "skip") {
|
|
1839
|
+
ctx.ui.notify(`Skipping ${unitType} ${unitId} (pre-dispatch hook).`, "info");
|
|
1840
|
+
// Yield then re-dispatch to advance to next unit
|
|
1841
|
+
await new Promise(r => setImmediate(r));
|
|
1842
|
+
await dispatchNextUnit(ctx, pi);
|
|
1843
|
+
return;
|
|
1844
|
+
}
|
|
1845
|
+
if (preDispatchResult.action === "replace") {
|
|
1846
|
+
prompt = preDispatchResult.prompt ?? prompt;
|
|
1847
|
+
if (preDispatchResult.unitType) unitType = preDispatchResult.unitType;
|
|
1848
|
+
} else if (preDispatchResult.prompt) {
|
|
1849
|
+
prompt = preDispatchResult.prompt;
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1634
1852
|
const priorSliceBlocker = getPriorSliceCompletionBlocker(basePath, getMainBranch(basePath), unitType, unitId);
|
|
1635
1853
|
if (priorSliceBlocker) {
|
|
1636
1854
|
await stopAuto(ctx, pi);
|
|
@@ -1870,16 +2088,37 @@ async function dispatchNextUnit(
|
|
|
1870
2088
|
let modelSet = false;
|
|
1871
2089
|
|
|
1872
2090
|
for (const modelId of modelsToTry) {
|
|
1873
|
-
//
|
|
2091
|
+
// Resolve model from available models.
|
|
2092
|
+
// Handles multiple formats:
|
|
2093
|
+
// "provider/model" → explicit provider targeting (e.g. "anthropic/claude-opus-4-6")
|
|
2094
|
+
// "bare-id" → match by ID across providers
|
|
2095
|
+
// "org/model-name" → OpenRouter-style IDs where the full string is the model ID
|
|
2096
|
+
// "openrouter/org/model" → explicit provider + OpenRouter model ID
|
|
1874
2097
|
const slashIdx = modelId.indexOf("/");
|
|
1875
2098
|
let model;
|
|
1876
2099
|
if (slashIdx !== -1) {
|
|
1877
|
-
const
|
|
2100
|
+
const maybeProvider = modelId.substring(0, slashIdx);
|
|
1878
2101
|
const id = modelId.substring(slashIdx + 1);
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
)
|
|
2102
|
+
|
|
2103
|
+
// Check if the prefix before the first slash is a known provider
|
|
2104
|
+
const knownProviders = new Set(availableModels.map(m => m.provider.toLowerCase()));
|
|
2105
|
+
if (knownProviders.has(maybeProvider.toLowerCase())) {
|
|
2106
|
+
// Explicit "provider/model" format (handles "openrouter/org/model" too)
|
|
2107
|
+
model = availableModels.find(
|
|
2108
|
+
m => m.provider.toLowerCase() === maybeProvider.toLowerCase()
|
|
2109
|
+
&& m.id.toLowerCase() === id.toLowerCase(),
|
|
2110
|
+
);
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
// If the prefix wasn't a known provider, or no match was found within that provider,
|
|
2114
|
+
// try matching the full string as a model ID (OpenRouter-style IDs like "org/model-name")
|
|
2115
|
+
if (!model) {
|
|
2116
|
+
const lower = modelId.toLowerCase();
|
|
2117
|
+
model = availableModels.find(
|
|
2118
|
+
m => m.id.toLowerCase() === lower
|
|
2119
|
+
|| `${m.provider}/${m.id}`.toLowerCase() === lower,
|
|
2120
|
+
);
|
|
2121
|
+
}
|
|
1883
2122
|
} else {
|
|
1884
2123
|
// For bare IDs, prefer the current session's provider, then first available match
|
|
1885
2124
|
const currentProvider = ctx.model?.provider;
|
|
@@ -1913,7 +2152,8 @@ async function dispatchNextUnit(
|
|
|
1913
2152
|
const fallbackNote = modelId === modelConfig.primary
|
|
1914
2153
|
? ""
|
|
1915
2154
|
: ` (fallback from ${modelConfig.primary})`;
|
|
1916
|
-
|
|
2155
|
+
const phase = unitPhaseLabel(unitType);
|
|
2156
|
+
ctx.ui.notify(`Model [${phase}]: ${model.provider}/${model.id}${fallbackNote}`, "info");
|
|
1917
2157
|
modelSet = true;
|
|
1918
2158
|
break;
|
|
1919
2159
|
} else {
|
|
@@ -2136,7 +2376,10 @@ async function inlineDependencySummaries(
|
|
|
2136
2376
|
if (!sliceEntry || sliceEntry.depends.length === 0) return "- (no dependencies)";
|
|
2137
2377
|
|
|
2138
2378
|
const sections: string[] = [];
|
|
2379
|
+
const seen = new Set<string>();
|
|
2139
2380
|
for (const dep of sliceEntry.depends) {
|
|
2381
|
+
if (seen.has(dep)) continue;
|
|
2382
|
+
seen.add(dep);
|
|
2140
2383
|
const summaryFile = resolveSliceFile(base, mid, dep, "SUMMARY");
|
|
2141
2384
|
const summaryContent = summaryFile ? await loadFile(summaryFile) : null;
|
|
2142
2385
|
const relPath = relSliceFile(base, mid, dep, "SUMMARY");
|
|
@@ -2176,6 +2419,7 @@ async function buildResearchMilestonePrompt(mid: string, midTitle: string, base:
|
|
|
2176
2419
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
2177
2420
|
const decisionsInline = await inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
2178
2421
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
2422
|
+
inlined.push(inlineTemplate("research", "Research"));
|
|
2179
2423
|
|
|
2180
2424
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
2181
2425
|
|
|
@@ -2208,6 +2452,11 @@ async function buildPlanMilestonePrompt(mid: string, midTitle: string, base: str
|
|
|
2208
2452
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
2209
2453
|
const decisionsInline = await inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
2210
2454
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
2455
|
+
inlined.push(inlineTemplate("roadmap", "Roadmap"));
|
|
2456
|
+
inlined.push(inlineTemplate("decisions", "Decisions"));
|
|
2457
|
+
inlined.push(inlineTemplate("plan", "Slice Plan"));
|
|
2458
|
+
inlined.push(inlineTemplate("task-plan", "Task Plan"));
|
|
2459
|
+
inlined.push(inlineTemplate("secrets-manifest", "Secrets Manifest"));
|
|
2211
2460
|
|
|
2212
2461
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
2213
2462
|
|
|
@@ -2244,6 +2493,7 @@ async function buildResearchSlicePrompt(
|
|
|
2244
2493
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
2245
2494
|
const requirementsInline = await inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
2246
2495
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
2496
|
+
inlined.push(inlineTemplate("research", "Research"));
|
|
2247
2497
|
|
|
2248
2498
|
const depContent = await inlineDependencySummaries(mid, sid, base);
|
|
2249
2499
|
|
|
@@ -2279,6 +2529,8 @@ async function buildPlanSlicePrompt(
|
|
|
2279
2529
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
2280
2530
|
const requirementsInline = await inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
2281
2531
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
2532
|
+
inlined.push(inlineTemplate("plan", "Slice Plan"));
|
|
2533
|
+
inlined.push(inlineTemplate("task-plan", "Task Plan"));
|
|
2282
2534
|
|
|
2283
2535
|
const depContent = await inlineDependencySummaries(mid, sid, base);
|
|
2284
2536
|
|
|
@@ -2340,6 +2592,10 @@ async function buildExecuteTaskPrompt(
|
|
|
2340
2592
|
);
|
|
2341
2593
|
|
|
2342
2594
|
const carryForwardSection = await buildCarryForwardSection(priorSummaries, base);
|
|
2595
|
+
const inlinedTemplates = [
|
|
2596
|
+
inlineTemplate("task-summary", "Task Summary"),
|
|
2597
|
+
inlineTemplate("decisions", "Decisions"),
|
|
2598
|
+
].join("\n\n---\n\n");
|
|
2343
2599
|
|
|
2344
2600
|
const taskSummaryPath = `${relSlicePath(base, mid, sid)}/tasks/${tid}-SUMMARY.md`;
|
|
2345
2601
|
|
|
@@ -2354,6 +2610,7 @@ async function buildExecuteTaskPrompt(
|
|
|
2354
2610
|
resumeSection,
|
|
2355
2611
|
priorTaskLines: priorLines,
|
|
2356
2612
|
taskSummaryPath,
|
|
2613
|
+
inlinedTemplates,
|
|
2357
2614
|
});
|
|
2358
2615
|
}
|
|
2359
2616
|
|
|
@@ -2386,6 +2643,8 @@ async function buildCompleteSlicePrompt(
|
|
|
2386
2643
|
}
|
|
2387
2644
|
}
|
|
2388
2645
|
}
|
|
2646
|
+
inlined.push(inlineTemplate("slice-summary", "Slice Summary"));
|
|
2647
|
+
inlined.push(inlineTemplate("uat", "UAT"));
|
|
2389
2648
|
|
|
2390
2649
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
2391
2650
|
|
|
@@ -2412,11 +2671,14 @@ async function buildCompleteMilestonePrompt(
|
|
|
2412
2671
|
const inlined: string[] = [];
|
|
2413
2672
|
inlined.push(await inlineFile(roadmapPath, roadmapRel, "Milestone Roadmap"));
|
|
2414
2673
|
|
|
2415
|
-
// Inline all slice summaries
|
|
2674
|
+
// Inline all slice summaries (deduplicated by slice ID)
|
|
2416
2675
|
const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
|
|
2417
2676
|
if (roadmapContent) {
|
|
2418
2677
|
const roadmap = parseRoadmap(roadmapContent);
|
|
2678
|
+
const seenSlices = new Set<string>();
|
|
2419
2679
|
for (const slice of roadmap.slices) {
|
|
2680
|
+
if (seenSlices.has(slice.id)) continue;
|
|
2681
|
+
seenSlices.add(slice.id);
|
|
2420
2682
|
const summaryPath = resolveSliceFile(base, mid, slice.id, "SUMMARY");
|
|
2421
2683
|
const summaryRel = relSliceFile(base, mid, slice.id, "SUMMARY");
|
|
2422
2684
|
inlined.push(await inlineFile(summaryPath, summaryRel, `${slice.id} Summary`));
|
|
@@ -2435,6 +2697,7 @@ async function buildCompleteMilestonePrompt(
|
|
|
2435
2697
|
const contextRel = relMilestoneFile(base, mid, "CONTEXT");
|
|
2436
2698
|
const contextInline = await inlineFileOptional(contextPath, contextRel, "Milestone Context");
|
|
2437
2699
|
if (contextInline) inlined.push(contextInline);
|
|
2700
|
+
inlined.push(inlineTemplate("milestone-summary", "Milestone Summary"));
|
|
2438
2701
|
|
|
2439
2702
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
2440
2703
|
|
|
@@ -2881,6 +3144,9 @@ async function collectObservabilityWarnings(
|
|
|
2881
3144
|
unitType: string,
|
|
2882
3145
|
unitId: string,
|
|
2883
3146
|
): Promise<import("./observability-validator.ts").ValidationIssue[]> {
|
|
3147
|
+
// Hook units have custom artifacts — skip standard observability checks
|
|
3148
|
+
if (unitType.startsWith("hook/")) return [];
|
|
3149
|
+
|
|
2884
3150
|
const parts = unitId.split("/");
|
|
2885
3151
|
const mid = parts[0];
|
|
2886
3152
|
const sid = parts[1];
|
|
@@ -3292,6 +3558,9 @@ export function resolveExpectedArtifactPath(unitType: string, unitId: string, ba
|
|
|
3292
3558
|
* skipped writing the UAT file (see #176).
|
|
3293
3559
|
*/
|
|
3294
3560
|
export function verifyExpectedArtifact(unitType: string, unitId: string, base: string): boolean {
|
|
3561
|
+
// Clear stale directory listing cache so artifact checks see fresh disk state (#431)
|
|
3562
|
+
clearPathCache();
|
|
3563
|
+
|
|
3295
3564
|
// fix-merge has no file artifact — verify by checking git state
|
|
3296
3565
|
if (unitType === "fix-merge") {
|
|
3297
3566
|
const unmerged = runGit(base, ["diff", "--name-only", "--diff-filter=U"], { allowFailure: true });
|
|
@@ -53,10 +53,10 @@ function dispatchDoctorHeal(pi: ExtensionAPI, scope: string | undefined, reportT
|
|
|
53
53
|
|
|
54
54
|
export function registerGSDCommand(pi: ExtensionAPI): void {
|
|
55
55
|
pi.registerCommand("gsd", {
|
|
56
|
-
description: "GSD — Get Shit Done: /gsd next|auto|stop|status|queue|prefs|doctor|migrate|remote",
|
|
56
|
+
description: "GSD — Get Shit Done: /gsd next|auto|stop|status|queue|prefs|hooks|doctor|migrate|remote",
|
|
57
57
|
|
|
58
58
|
getArgumentCompletions: (prefix: string) => {
|
|
59
|
-
const subcommands = ["next", "auto", "stop", "status", "queue", "discuss", "prefs", "doctor", "migrate", "remote"];
|
|
59
|
+
const subcommands = ["next", "auto", "stop", "status", "queue", "discuss", "prefs", "hooks", "doctor", "migrate", "remote"];
|
|
60
60
|
const parts = prefix.trim().split(/\s+/);
|
|
61
61
|
|
|
62
62
|
if (parts.length <= 1) {
|
|
@@ -151,6 +151,12 @@ export function registerGSDCommand(pi: ExtensionAPI): void {
|
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
if (trimmed === "hooks") {
|
|
155
|
+
const { formatHookStatus } = await import("./post-unit-hooks.js");
|
|
156
|
+
ctx.ui.notify(formatHookStatus(), "info");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
154
160
|
if (trimmed === "migrate" || trimmed.startsWith("migrate ")) {
|
|
155
161
|
await handleMigrate(trimmed.replace(/^migrate\s*/, "").trim(), ctx, pi);
|
|
156
162
|
return;
|
|
@@ -168,7 +174,7 @@ export function registerGSDCommand(pi: ExtensionAPI): void {
|
|
|
168
174
|
}
|
|
169
175
|
|
|
170
176
|
ctx.ui.notify(
|
|
171
|
-
`Unknown: /gsd ${trimmed}. Use /gsd, /gsd next, /gsd auto, /gsd stop, /gsd status, /gsd queue, /gsd discuss, /gsd prefs [global|project|status|wizard|setup], /gsd doctor [audit|fix|heal] [M###/S##], /gsd migrate <path>, or /gsd remote [slack|discord|status|disconnect].`,
|
|
177
|
+
`Unknown: /gsd ${trimmed}. Use /gsd, /gsd next, /gsd auto, /gsd stop, /gsd status, /gsd queue, /gsd discuss, /gsd prefs [global|project|status|wizard|setup], /gsd hooks, /gsd doctor [audit|fix|heal] [M###/S##], /gsd migrate <path>, or /gsd remote [slack|discord|status|disconnect].`,
|
|
172
178
|
"warning",
|
|
173
179
|
);
|
|
174
180
|
},
|