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,398 @@
|
|
|
1
|
+
// Migration writer format round-trip test suite
|
|
2
|
+
// Tests that format functions produce output that parses back correctly
|
|
3
|
+
// through parseRoadmap(), parsePlan(), parseSummary(), and parseRequirementCounts().
|
|
4
|
+
// Pure in-memory tests — no filesystem needed.
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
formatRoadmap,
|
|
8
|
+
formatPlan,
|
|
9
|
+
formatSliceSummary,
|
|
10
|
+
formatTaskSummary,
|
|
11
|
+
formatTaskPlan,
|
|
12
|
+
formatRequirements,
|
|
13
|
+
formatProject,
|
|
14
|
+
formatDecisions,
|
|
15
|
+
formatContext,
|
|
16
|
+
formatState,
|
|
17
|
+
} from '../migrate/writer.ts';
|
|
18
|
+
import {
|
|
19
|
+
parseRoadmap,
|
|
20
|
+
parsePlan,
|
|
21
|
+
parseSummary,
|
|
22
|
+
parseRequirementCounts,
|
|
23
|
+
} from '../files.ts';
|
|
24
|
+
import type {
|
|
25
|
+
GSDMilestone,
|
|
26
|
+
GSDSlice,
|
|
27
|
+
GSDTask,
|
|
28
|
+
GSDRequirement,
|
|
29
|
+
GSDSliceSummaryData,
|
|
30
|
+
GSDTaskSummaryData,
|
|
31
|
+
} from '../migrate/types.ts';
|
|
32
|
+
import { createTestContext } from './test-helpers.ts';
|
|
33
|
+
|
|
34
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
35
|
+
// ─── Test Data Builders ────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
function makeTask(overrides: Partial<GSDTask> = {}): GSDTask {
|
|
38
|
+
return {
|
|
39
|
+
id: 'T01',
|
|
40
|
+
title: 'Setup Auth',
|
|
41
|
+
description: 'Implement authentication',
|
|
42
|
+
done: false,
|
|
43
|
+
estimate: '30m',
|
|
44
|
+
files: ['src/auth.ts'],
|
|
45
|
+
mustHaves: ['JWT support'],
|
|
46
|
+
summary: null,
|
|
47
|
+
...overrides,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function makeSlice(overrides: Partial<GSDSlice> = {}): GSDSlice {
|
|
52
|
+
return {
|
|
53
|
+
id: 'S01',
|
|
54
|
+
title: 'Auth System',
|
|
55
|
+
risk: 'medium' as const,
|
|
56
|
+
depends: [],
|
|
57
|
+
done: false,
|
|
58
|
+
demo: 'Login flow works end-to-end',
|
|
59
|
+
goal: 'Working authentication',
|
|
60
|
+
tasks: [makeTask()],
|
|
61
|
+
research: null,
|
|
62
|
+
summary: null,
|
|
63
|
+
...overrides,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function makeMilestone(overrides: Partial<GSDMilestone> = {}): GSDMilestone {
|
|
68
|
+
return {
|
|
69
|
+
id: 'M001',
|
|
70
|
+
title: 'Core Platform',
|
|
71
|
+
vision: 'Build the core platform',
|
|
72
|
+
successCriteria: ['All tests pass', 'Deploy to staging'],
|
|
73
|
+
slices: [makeSlice()],
|
|
74
|
+
research: null,
|
|
75
|
+
boundaryMap: [],
|
|
76
|
+
...overrides,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function makeSliceSummary(overrides: Partial<GSDSliceSummaryData> = {}): GSDSliceSummaryData {
|
|
81
|
+
return {
|
|
82
|
+
completedAt: '2026-03-10',
|
|
83
|
+
provides: ['auth-flow', 'jwt-tokens'],
|
|
84
|
+
keyFiles: ['src/auth.ts', 'src/middleware.ts'],
|
|
85
|
+
keyDecisions: ['Use JWT over sessions'],
|
|
86
|
+
patternsEstablished: ['Middleware pattern'],
|
|
87
|
+
duration: '2h',
|
|
88
|
+
whatHappened: 'Implemented full auth system with JWT.',
|
|
89
|
+
...overrides,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function makeTaskSummary(overrides: Partial<GSDTaskSummaryData> = {}): GSDTaskSummaryData {
|
|
94
|
+
return {
|
|
95
|
+
completedAt: '2026-03-09',
|
|
96
|
+
provides: ['auth-endpoint'],
|
|
97
|
+
keyFiles: ['src/auth.ts'],
|
|
98
|
+
duration: '45m',
|
|
99
|
+
whatHappened: 'Built the auth endpoint.',
|
|
100
|
+
...overrides,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
105
|
+
// Scenario A: Roadmap round-trip with 2 slices (1 done, 1 not)
|
|
106
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
107
|
+
|
|
108
|
+
{
|
|
109
|
+
const milestone = makeMilestone({
|
|
110
|
+
slices: [
|
|
111
|
+
makeSlice({
|
|
112
|
+
id: 'S01',
|
|
113
|
+
title: 'Auth System',
|
|
114
|
+
risk: 'high',
|
|
115
|
+
depends: [],
|
|
116
|
+
done: true,
|
|
117
|
+
demo: 'Login flow works',
|
|
118
|
+
}),
|
|
119
|
+
makeSlice({
|
|
120
|
+
id: 'S02',
|
|
121
|
+
title: 'Dashboard',
|
|
122
|
+
risk: 'low',
|
|
123
|
+
depends: ['S01'],
|
|
124
|
+
done: false,
|
|
125
|
+
demo: 'Dashboard renders data',
|
|
126
|
+
}),
|
|
127
|
+
],
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const output = formatRoadmap(milestone);
|
|
131
|
+
const parsed = parseRoadmap(output);
|
|
132
|
+
|
|
133
|
+
assertEq(parsed.title, 'M001: Core Platform', 'roadmap: title');
|
|
134
|
+
assertEq(parsed.vision, 'Build the core platform', 'roadmap: vision');
|
|
135
|
+
assertEq(parsed.successCriteria.length, 2, 'roadmap: successCriteria count');
|
|
136
|
+
assertEq(parsed.successCriteria[0], 'All tests pass', 'roadmap: successCriteria[0]');
|
|
137
|
+
assertEq(parsed.successCriteria[1], 'Deploy to staging', 'roadmap: successCriteria[1]');
|
|
138
|
+
assertEq(parsed.slices.length, 2, 'roadmap: slices count');
|
|
139
|
+
|
|
140
|
+
assertEq(parsed.slices[0].id, 'S01', 'roadmap: S01 id');
|
|
141
|
+
assertEq(parsed.slices[0].title, 'Auth System', 'roadmap: S01 title');
|
|
142
|
+
assertEq(parsed.slices[0].done, true, 'roadmap: S01 done');
|
|
143
|
+
assertEq(parsed.slices[0].risk, 'high', 'roadmap: S01 risk');
|
|
144
|
+
assertEq(parsed.slices[0].depends.length, 0, 'roadmap: S01 depends empty');
|
|
145
|
+
assertEq(parsed.slices[0].demo, 'Login flow works', 'roadmap: S01 demo');
|
|
146
|
+
|
|
147
|
+
assertEq(parsed.slices[1].id, 'S02', 'roadmap: S02 id');
|
|
148
|
+
assertEq(parsed.slices[1].title, 'Dashboard', 'roadmap: S02 title');
|
|
149
|
+
assertEq(parsed.slices[1].done, false, 'roadmap: S02 done');
|
|
150
|
+
assertEq(parsed.slices[1].risk, 'low', 'roadmap: S02 risk');
|
|
151
|
+
assertEq(parsed.slices[1].depends, ['S01'], 'roadmap: S02 depends');
|
|
152
|
+
assertEq(parsed.slices[1].demo, 'Dashboard renders data', 'roadmap: S02 demo');
|
|
153
|
+
|
|
154
|
+
assertEq(parsed.boundaryMap.length, 0, 'roadmap: boundaryMap empty');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
158
|
+
// Scenario B: Plan round-trip with 3 tasks (mixed done)
|
|
159
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
160
|
+
|
|
161
|
+
{
|
|
162
|
+
const slice = makeSlice({
|
|
163
|
+
id: 'S01',
|
|
164
|
+
title: 'Auth System',
|
|
165
|
+
goal: 'Working authentication system',
|
|
166
|
+
demo: 'Login works with valid credentials',
|
|
167
|
+
tasks: [
|
|
168
|
+
makeTask({ id: 'T01', title: 'Setup Models', done: true, estimate: '15m', description: 'Define user model' }),
|
|
169
|
+
makeTask({ id: 'T02', title: 'Build Endpoints', done: false, estimate: '30m', description: 'REST API endpoints' }),
|
|
170
|
+
makeTask({ id: 'T03', title: 'Write Tests', done: true, estimate: '20m', description: 'Unit and integration tests' }),
|
|
171
|
+
],
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const output = formatPlan(slice);
|
|
175
|
+
const parsed = parsePlan(output);
|
|
176
|
+
|
|
177
|
+
assertEq(parsed.id, 'S01', 'plan: id');
|
|
178
|
+
assertEq(parsed.title, 'Auth System', 'plan: title');
|
|
179
|
+
assertEq(parsed.goal, 'Working authentication system', 'plan: goal');
|
|
180
|
+
assertEq(parsed.demo, 'Login works with valid credentials', 'plan: demo');
|
|
181
|
+
assertEq(parsed.tasks.length, 3, 'plan: tasks count');
|
|
182
|
+
|
|
183
|
+
assertEq(parsed.tasks[0].id, 'T01', 'plan: T01 id');
|
|
184
|
+
assertEq(parsed.tasks[0].title, 'Setup Models', 'plan: T01 title');
|
|
185
|
+
assertEq(parsed.tasks[0].done, true, 'plan: T01 done');
|
|
186
|
+
assertEq(parsed.tasks[0].estimate, '15m', 'plan: T01 estimate');
|
|
187
|
+
|
|
188
|
+
assertEq(parsed.tasks[1].id, 'T02', 'plan: T02 id');
|
|
189
|
+
assertEq(parsed.tasks[1].done, false, 'plan: T02 done');
|
|
190
|
+
assertEq(parsed.tasks[1].estimate, '30m', 'plan: T02 estimate');
|
|
191
|
+
|
|
192
|
+
assertEq(parsed.tasks[2].id, 'T03', 'plan: T03 id');
|
|
193
|
+
assertEq(parsed.tasks[2].done, true, 'plan: T03 done');
|
|
194
|
+
assertEq(parsed.tasks[2].estimate, '20m', 'plan: T03 estimate');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
198
|
+
// Scenario C: Slice summary round-trip with full data
|
|
199
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
200
|
+
|
|
201
|
+
{
|
|
202
|
+
const slice = makeSlice({
|
|
203
|
+
id: 'S01',
|
|
204
|
+
title: 'Auth System',
|
|
205
|
+
done: true,
|
|
206
|
+
summary: makeSliceSummary(),
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
const output = formatSliceSummary(slice, 'M001');
|
|
210
|
+
const parsed = parseSummary(output);
|
|
211
|
+
|
|
212
|
+
assertEq(parsed.frontmatter.id, 'S01', 'sliceSummary: id');
|
|
213
|
+
assertEq(parsed.frontmatter.parent, 'M001', 'sliceSummary: parent');
|
|
214
|
+
assertEq(parsed.frontmatter.milestone, 'M001', 'sliceSummary: milestone');
|
|
215
|
+
assertEq(parsed.frontmatter.provides, ['auth-flow', 'jwt-tokens'], 'sliceSummary: provides');
|
|
216
|
+
assertEq(parsed.frontmatter.requires.length, 0, 'sliceSummary: requires empty');
|
|
217
|
+
assertEq(parsed.frontmatter.affects.length, 0, 'sliceSummary: affects empty');
|
|
218
|
+
assertEq(parsed.frontmatter.key_files, ['src/auth.ts', 'src/middleware.ts'], 'sliceSummary: key_files');
|
|
219
|
+
assertEq(parsed.frontmatter.key_decisions, ['Use JWT over sessions'], 'sliceSummary: key_decisions');
|
|
220
|
+
assertEq(parsed.frontmatter.patterns_established, ['Middleware pattern'], 'sliceSummary: patterns_established');
|
|
221
|
+
assertEq(parsed.frontmatter.duration, '2h', 'sliceSummary: duration');
|
|
222
|
+
assertEq(parsed.frontmatter.completed_at, '2026-03-10', 'sliceSummary: completed_at');
|
|
223
|
+
assertEq(parsed.frontmatter.verification_result, 'passed', 'sliceSummary: verification_result');
|
|
224
|
+
assertEq(parsed.frontmatter.blocker_discovered, false, 'sliceSummary: blocker_discovered');
|
|
225
|
+
assertTrue(parsed.whatHappened.includes('Implemented full auth system'), 'sliceSummary: whatHappened content');
|
|
226
|
+
assertEq(parsed.title, 'S01: Auth System', 'sliceSummary: title');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
230
|
+
// Scenario D: Task summary round-trip
|
|
231
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
232
|
+
|
|
233
|
+
{
|
|
234
|
+
const task = makeTask({
|
|
235
|
+
id: 'T01',
|
|
236
|
+
title: 'Setup Auth',
|
|
237
|
+
done: true,
|
|
238
|
+
summary: makeTaskSummary(),
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const output = formatTaskSummary(task, 'S01', 'M001');
|
|
242
|
+
const parsed = parseSummary(output);
|
|
243
|
+
|
|
244
|
+
assertEq(parsed.frontmatter.id, 'T01', 'taskSummary: id');
|
|
245
|
+
assertEq(parsed.frontmatter.parent, 'S01', 'taskSummary: parent');
|
|
246
|
+
assertEq(parsed.frontmatter.milestone, 'M001', 'taskSummary: milestone');
|
|
247
|
+
assertEq(parsed.frontmatter.provides, ['auth-endpoint'], 'taskSummary: provides');
|
|
248
|
+
assertEq(parsed.frontmatter.key_files, ['src/auth.ts'], 'taskSummary: key_files');
|
|
249
|
+
assertEq(parsed.frontmatter.duration, '45m', 'taskSummary: duration');
|
|
250
|
+
assertEq(parsed.frontmatter.completed_at, '2026-03-09', 'taskSummary: completed_at');
|
|
251
|
+
assertTrue(parsed.whatHappened.includes('Built the auth endpoint'), 'taskSummary: whatHappened content');
|
|
252
|
+
assertEq(parsed.title, 'T01: Setup Auth', 'taskSummary: title');
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
256
|
+
// Scenario E: Requirements round-trip with mixed statuses
|
|
257
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
258
|
+
|
|
259
|
+
{
|
|
260
|
+
const requirements: GSDRequirement[] = [
|
|
261
|
+
{ id: 'R001', title: 'Auth Required', class: 'core-capability', status: 'active', description: 'Must have auth', source: 'spec', primarySlice: 'S01' },
|
|
262
|
+
{ id: 'R002', title: 'Logging', class: 'observability', status: 'active', description: 'Must log', source: 'spec', primarySlice: 'S02' },
|
|
263
|
+
{ id: 'R003', title: 'OAuth Support', class: 'core-capability', status: 'validated', description: 'OAuth working', source: 'testing', primarySlice: 'S01' },
|
|
264
|
+
{ id: 'R004', title: 'Dark Mode', class: 'ui', status: 'deferred', description: 'Nice to have', source: 'feedback', primarySlice: 'none' },
|
|
265
|
+
{ id: 'R005', title: 'Legacy API', class: 'compat', status: 'out-of-scope', description: 'Dropped', source: 'decision', primarySlice: 'none' },
|
|
266
|
+
];
|
|
267
|
+
|
|
268
|
+
const output = formatRequirements(requirements);
|
|
269
|
+
const counts = parseRequirementCounts(output);
|
|
270
|
+
|
|
271
|
+
assertEq(counts.active, 2, 'requirements: active count');
|
|
272
|
+
assertEq(counts.validated, 1, 'requirements: validated count');
|
|
273
|
+
assertEq(counts.deferred, 1, 'requirements: deferred count');
|
|
274
|
+
assertEq(counts.outOfScope, 1, 'requirements: outOfScope count');
|
|
275
|
+
assertEq(counts.total, 5, 'requirements: total count');
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
279
|
+
// Scenario F: Edge cases
|
|
280
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
281
|
+
|
|
282
|
+
// F1: Empty vision → fallback text
|
|
283
|
+
{
|
|
284
|
+
const milestone = makeMilestone({ vision: '' });
|
|
285
|
+
const output = formatRoadmap(milestone);
|
|
286
|
+
const parsed = parseRoadmap(output);
|
|
287
|
+
assertEq(parsed.vision, '(migrated project)', 'edge: empty vision fallback');
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// F2: Empty successCriteria → empty array
|
|
291
|
+
{
|
|
292
|
+
const milestone = makeMilestone({ successCriteria: [] });
|
|
293
|
+
const output = formatRoadmap(milestone);
|
|
294
|
+
const parsed = parseRoadmap(output);
|
|
295
|
+
assertEq(parsed.successCriteria.length, 0, 'edge: empty successCriteria');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// F3: Empty tasks → empty array in parsed plan
|
|
299
|
+
{
|
|
300
|
+
const slice = makeSlice({ tasks: [] });
|
|
301
|
+
const output = formatPlan(slice);
|
|
302
|
+
const parsed = parsePlan(output);
|
|
303
|
+
assertEq(parsed.tasks.length, 0, 'edge: empty tasks');
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// F4: Null summary → empty string from formatSliceSummary
|
|
307
|
+
{
|
|
308
|
+
const slice = makeSlice({ summary: null });
|
|
309
|
+
const output = formatSliceSummary(slice, 'M001');
|
|
310
|
+
assertEq(output, '', 'edge: null summary returns empty string');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// F5: Done=true checkbox in roadmap
|
|
314
|
+
{
|
|
315
|
+
const milestone = makeMilestone({
|
|
316
|
+
slices: [makeSlice({ id: 'S01', done: true })],
|
|
317
|
+
});
|
|
318
|
+
const output = formatRoadmap(milestone);
|
|
319
|
+
const parsed = parseRoadmap(output);
|
|
320
|
+
assertEq(parsed.slices[0].done, true, 'edge: done checkbox true');
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// F6: Done=false checkbox in roadmap
|
|
324
|
+
{
|
|
325
|
+
const milestone = makeMilestone({
|
|
326
|
+
slices: [makeSlice({ id: 'S01', done: false })],
|
|
327
|
+
});
|
|
328
|
+
const output = formatRoadmap(milestone);
|
|
329
|
+
const parsed = parseRoadmap(output);
|
|
330
|
+
assertEq(parsed.slices[0].done, false, 'edge: done checkbox false');
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// F7: Null task summary → empty string from formatTaskSummary
|
|
334
|
+
{
|
|
335
|
+
const task = makeTask({ summary: null });
|
|
336
|
+
const output = formatTaskSummary(task, 'S01', 'M001');
|
|
337
|
+
assertEq(output, '', 'edge: null task summary returns empty string');
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// F8: Empty requirements → all zeros
|
|
341
|
+
{
|
|
342
|
+
const output = formatRequirements([]);
|
|
343
|
+
const counts = parseRequirementCounts(output);
|
|
344
|
+
assertEq(counts.total, 0, 'edge: empty requirements total 0');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// F9: formatProject with empty content → produces valid stub
|
|
348
|
+
{
|
|
349
|
+
const output = formatProject('');
|
|
350
|
+
assertTrue(output.includes('# Project'), 'edge: empty project has heading');
|
|
351
|
+
assertTrue(output.length > 10, 'edge: empty project not blank');
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// F10: formatProject with existing content → passes through
|
|
355
|
+
{
|
|
356
|
+
const content = '# My Project\n\nDescription here.\n';
|
|
357
|
+
const output = formatProject(content);
|
|
358
|
+
assertEq(output, content, 'edge: project passthrough');
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// F11: formatDecisions with empty content → produces valid stub
|
|
362
|
+
{
|
|
363
|
+
const output = formatDecisions('');
|
|
364
|
+
assertTrue(output.includes('# Decisions'), 'edge: empty decisions has heading');
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// F12: formatContext produces valid content
|
|
368
|
+
{
|
|
369
|
+
const output = formatContext('M001');
|
|
370
|
+
assertTrue(output.includes('M001'), 'edge: context mentions milestone');
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// F13: formatState produces valid content
|
|
374
|
+
{
|
|
375
|
+
const milestones = [makeMilestone({
|
|
376
|
+
slices: [
|
|
377
|
+
makeSlice({ done: true }),
|
|
378
|
+
makeSlice({ id: 'S02', done: false }),
|
|
379
|
+
],
|
|
380
|
+
})];
|
|
381
|
+
const output = formatState(milestones);
|
|
382
|
+
assertTrue(output.includes('1/2'), 'edge: state shows slice progress');
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// F14: Task with no estimate → no est backtick in plan
|
|
386
|
+
{
|
|
387
|
+
const slice = makeSlice({
|
|
388
|
+
tasks: [makeTask({ id: 'T01', title: 'Quick Fix', estimate: '' })],
|
|
389
|
+
});
|
|
390
|
+
const output = formatPlan(slice);
|
|
391
|
+
const parsed = parsePlan(output);
|
|
392
|
+
assertEq(parsed.tasks[0].id, 'T01', 'edge: task no estimate id');
|
|
393
|
+
assertEq(parsed.tasks[0].estimate, '', 'edge: task no estimate empty');
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
397
|
+
|
|
398
|
+
report();
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { parseTaskPlanMustHaves } from '../files.ts';
|
|
2
|
+
import { createTestContext } from './test-helpers.ts';
|
|
3
|
+
|
|
4
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
5
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
6
|
+
// (a) Standard unchecked format: - [ ] text
|
|
7
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
8
|
+
|
|
9
|
+
console.log('\n=== parseTaskPlanMustHaves: standard unchecked ===');
|
|
10
|
+
{
|
|
11
|
+
const content = `# T01: Test Task
|
|
12
|
+
|
|
13
|
+
## Must-Haves
|
|
14
|
+
|
|
15
|
+
- [ ] First must-have item
|
|
16
|
+
- [ ] Second must-have item
|
|
17
|
+
`;
|
|
18
|
+
const result = parseTaskPlanMustHaves(content);
|
|
19
|
+
assertEq(result.length, 2, 'should return 2 items');
|
|
20
|
+
assertEq(result[0].text, 'First must-have item', 'first item text');
|
|
21
|
+
assertEq(result[0].checked, false, 'first item unchecked');
|
|
22
|
+
assertEq(result[1].text, 'Second must-have item', 'second item text');
|
|
23
|
+
assertEq(result[1].checked, false, 'second item unchecked');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
27
|
+
// (b) Checked variants: - [x] and - [X]
|
|
28
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
29
|
+
|
|
30
|
+
console.log('\n=== parseTaskPlanMustHaves: checked [x] and [X] ===');
|
|
31
|
+
{
|
|
32
|
+
const content = `## Must-Haves
|
|
33
|
+
|
|
34
|
+
- [x] Lowercase checked item
|
|
35
|
+
- [X] Uppercase checked item
|
|
36
|
+
`;
|
|
37
|
+
const result = parseTaskPlanMustHaves(content);
|
|
38
|
+
assertEq(result.length, 2, 'should return 2 items');
|
|
39
|
+
assertEq(result[0].checked, true, 'lowercase x is checked');
|
|
40
|
+
assertEq(result[0].text, 'Lowercase checked item', 'lowercase x text');
|
|
41
|
+
assertEq(result[1].checked, true, 'uppercase X is checked');
|
|
42
|
+
assertEq(result[1].text, 'Uppercase checked item', 'uppercase X text');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
46
|
+
// (c) No-checkbox bullets: - text
|
|
47
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
48
|
+
|
|
49
|
+
console.log('\n=== parseTaskPlanMustHaves: no-checkbox bullets ===');
|
|
50
|
+
{
|
|
51
|
+
const content = `## Must-Haves
|
|
52
|
+
|
|
53
|
+
- Plain bullet item
|
|
54
|
+
- Another plain item
|
|
55
|
+
`;
|
|
56
|
+
const result = parseTaskPlanMustHaves(content);
|
|
57
|
+
assertEq(result.length, 2, 'should return 2 items');
|
|
58
|
+
assertEq(result[0].text, 'Plain bullet item', 'plain bullet text');
|
|
59
|
+
assertEq(result[0].checked, false, 'plain bullet defaults to unchecked');
|
|
60
|
+
assertEq(result[1].text, 'Another plain item', 'second plain bullet text');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
64
|
+
// (d) Indented variants
|
|
65
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
66
|
+
|
|
67
|
+
console.log('\n=== parseTaskPlanMustHaves: indented variants ===');
|
|
68
|
+
{
|
|
69
|
+
const content = `## Must-Haves
|
|
70
|
+
|
|
71
|
+
- [ ] Indented unchecked item
|
|
72
|
+
- [x] Indented checked item
|
|
73
|
+
- Plain indented item
|
|
74
|
+
`;
|
|
75
|
+
const result = parseTaskPlanMustHaves(content);
|
|
76
|
+
assertEq(result.length, 3, 'should return 3 items');
|
|
77
|
+
assertEq(result[0].text, 'Indented unchecked item', 'indented unchecked text');
|
|
78
|
+
assertEq(result[0].checked, false, 'indented unchecked state');
|
|
79
|
+
assertEq(result[1].text, 'Indented checked item', 'indented checked text');
|
|
80
|
+
assertEq(result[1].checked, true, 'indented checked state');
|
|
81
|
+
assertEq(result[2].text, 'Plain indented item', 'indented plain text');
|
|
82
|
+
assertEq(result[2].checked, false, 'indented plain state');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
86
|
+
// (e) Mixed checkbox states in one section
|
|
87
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
88
|
+
|
|
89
|
+
console.log('\n=== parseTaskPlanMustHaves: mixed states ===');
|
|
90
|
+
{
|
|
91
|
+
const content = `## Must-Haves
|
|
92
|
+
|
|
93
|
+
- [ ] Unchecked one
|
|
94
|
+
- [x] Checked one
|
|
95
|
+
- [X] Also checked
|
|
96
|
+
- Plain bullet
|
|
97
|
+
- [ ] Another unchecked
|
|
98
|
+
`;
|
|
99
|
+
const result = parseTaskPlanMustHaves(content);
|
|
100
|
+
assertEq(result.length, 5, 'should return 5 items');
|
|
101
|
+
assertEq(result[0].checked, false, 'first is unchecked');
|
|
102
|
+
assertEq(result[1].checked, true, 'second is checked');
|
|
103
|
+
assertEq(result[2].checked, true, 'third is checked (uppercase)');
|
|
104
|
+
assertEq(result[3].checked, false, 'fourth (plain) is unchecked');
|
|
105
|
+
assertEq(result[4].checked, false, 'fifth is unchecked');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
109
|
+
// (f) Missing Must-Haves section → empty array
|
|
110
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
111
|
+
|
|
112
|
+
console.log('\n=== parseTaskPlanMustHaves: missing section ===');
|
|
113
|
+
{
|
|
114
|
+
const content = `# T01: Some Task
|
|
115
|
+
|
|
116
|
+
## Description
|
|
117
|
+
|
|
118
|
+
Some description here.
|
|
119
|
+
|
|
120
|
+
## Verification
|
|
121
|
+
|
|
122
|
+
- Run tests
|
|
123
|
+
`;
|
|
124
|
+
const result = parseTaskPlanMustHaves(content);
|
|
125
|
+
assertEq(result.length, 0, 'returns empty array when section missing');
|
|
126
|
+
assertTrue(Array.isArray(result), 'result is an array');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
130
|
+
// (g) Empty Must-Haves section → empty array
|
|
131
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
132
|
+
|
|
133
|
+
console.log('\n=== parseTaskPlanMustHaves: empty section ===');
|
|
134
|
+
{
|
|
135
|
+
const content = `## Must-Haves
|
|
136
|
+
|
|
137
|
+
## Verification
|
|
138
|
+
|
|
139
|
+
- Run tests
|
|
140
|
+
`;
|
|
141
|
+
const result = parseTaskPlanMustHaves(content);
|
|
142
|
+
assertEq(result.length, 0, 'returns empty array when section is empty');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
146
|
+
// (h) Content with YAML frontmatter
|
|
147
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
148
|
+
|
|
149
|
+
console.log('\n=== parseTaskPlanMustHaves: YAML frontmatter ===');
|
|
150
|
+
{
|
|
151
|
+
const content = `---
|
|
152
|
+
estimated_steps: 5
|
|
153
|
+
estimated_files: 3
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
# T01: Task with frontmatter
|
|
157
|
+
|
|
158
|
+
## Must-Haves
|
|
159
|
+
|
|
160
|
+
- [ ] Real must-have after frontmatter
|
|
161
|
+
- [x] Checked must-have after frontmatter
|
|
162
|
+
`;
|
|
163
|
+
const result = parseTaskPlanMustHaves(content);
|
|
164
|
+
assertEq(result.length, 2, 'frontmatter does not pollute results');
|
|
165
|
+
assertEq(result[0].text, 'Real must-have after frontmatter', 'first item text correct');
|
|
166
|
+
assertEq(result[0].checked, false, 'first item unchecked');
|
|
167
|
+
assertEq(result[1].text, 'Checked must-have after frontmatter', 'second item text correct');
|
|
168
|
+
assertEq(result[1].checked, true, 'second item checked');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Verify frontmatter content is not misinterpreted as must-haves
|
|
172
|
+
console.log('\n=== parseTaskPlanMustHaves: frontmatter-only content ===');
|
|
173
|
+
{
|
|
174
|
+
const content = `---
|
|
175
|
+
estimated_steps: 5
|
|
176
|
+
estimated_files: 3
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
# T01: Task with only frontmatter
|
|
180
|
+
|
|
181
|
+
## Description
|
|
182
|
+
|
|
183
|
+
No must-haves section here.
|
|
184
|
+
`;
|
|
185
|
+
const result = parseTaskPlanMustHaves(content);
|
|
186
|
+
assertEq(result.length, 0, 'frontmatter-only content returns empty array');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
190
|
+
// (i) Real task plan format (based on S01/T01-PLAN.md structure)
|
|
191
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
192
|
+
|
|
193
|
+
console.log('\n=== parseTaskPlanMustHaves: real task plan format ===');
|
|
194
|
+
{
|
|
195
|
+
const content = `---
|
|
196
|
+
estimated_steps: 5
|
|
197
|
+
estimated_files: 3
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
# T01: Add completing-milestone phase to deriveState with tests
|
|
201
|
+
|
|
202
|
+
**Slice:** S01 — Milestone Completion Unit
|
|
203
|
+
**Milestone:** M002
|
|
204
|
+
|
|
205
|
+
## Description
|
|
206
|
+
|
|
207
|
+
Add the \`completing-milestone\` phase to the GSD state machine.
|
|
208
|
+
|
|
209
|
+
## Steps
|
|
210
|
+
|
|
211
|
+
1. Add \`'completing-milestone'\` to the \`Phase\` union type in \`types.ts\`.
|
|
212
|
+
2. In \`state.ts\`, modify the registry-building loop.
|
|
213
|
+
|
|
214
|
+
## Must-Haves
|
|
215
|
+
|
|
216
|
+
- [ ] \`Phase\` type includes \`'completing-milestone'\`
|
|
217
|
+
- [ ] \`deriveState\` returns \`phase: 'completing-milestone'\` when all slices are \`[x]\` and no \`M00x-SUMMARY.md\` exists
|
|
218
|
+
- [ ] \`deriveState\` returns milestone as \`'complete'\` and advances when summary exists
|
|
219
|
+
- [ ] All 63+ existing \`deriveState\` tests pass without modification
|
|
220
|
+
- [ ] New test fixtures cover single-milestone and multi-milestone completing-milestone scenarios
|
|
221
|
+
|
|
222
|
+
## Verification
|
|
223
|
+
|
|
224
|
+
- Run tests
|
|
225
|
+
- All existing 63 assertions pass
|
|
226
|
+
|
|
227
|
+
## Observability Impact
|
|
228
|
+
|
|
229
|
+
- Signals added/changed: \`completing-milestone\` phase now visible
|
|
230
|
+
- How a future agent inspects this: Run \`deriveState(basePath)\`
|
|
231
|
+
- Failure state exposed: If \`deriveState\` doesn't detect the phase
|
|
232
|
+
|
|
233
|
+
## Inputs
|
|
234
|
+
|
|
235
|
+
- \`agent/extensions/gsd/types.ts\` — Phase type definition
|
|
236
|
+
|
|
237
|
+
## Expected Output
|
|
238
|
+
|
|
239
|
+
- \`agent/extensions/gsd/types.ts\` — Phase union includes \`'completing-milestone'\`
|
|
240
|
+
`;
|
|
241
|
+
const result = parseTaskPlanMustHaves(content);
|
|
242
|
+
assertEq(result.length, 5, 'real plan has 5 must-haves');
|
|
243
|
+
assertTrue(result[0].text.includes('`Phase` type includes'), 'first must-have text matches');
|
|
244
|
+
assertTrue(result[1].text.includes('`deriveState` returns'), 'second must-have text matches');
|
|
245
|
+
assertEq(result[0].checked, false, 'all real must-haves are unchecked');
|
|
246
|
+
assertEq(result[4].checked, false, 'last real must-have is unchecked');
|
|
247
|
+
assertTrue(result[4].text.includes('multi-milestone'), 'last must-have references multi-milestone');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
251
|
+
// Edge cases
|
|
252
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
253
|
+
|
|
254
|
+
console.log('\n=== parseTaskPlanMustHaves: empty string ===');
|
|
255
|
+
{
|
|
256
|
+
const result = parseTaskPlanMustHaves('');
|
|
257
|
+
assertEq(result.length, 0, 'empty string returns empty array');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
console.log('\n=== parseTaskPlanMustHaves: must-haves with inline code and backticks ===');
|
|
261
|
+
{
|
|
262
|
+
const content = `## Must-Haves
|
|
263
|
+
|
|
264
|
+
- [ ] \`functionName\` is exported from \`module.ts\`
|
|
265
|
+
- [x] Returns \`Array<{ text: string }>\` with correct extraction
|
|
266
|
+
`;
|
|
267
|
+
const result = parseTaskPlanMustHaves(content);
|
|
268
|
+
assertEq(result.length, 2, 'handles backtick content');
|
|
269
|
+
assertTrue(result[0].text.includes('`functionName`'), 'preserves backticks in text');
|
|
270
|
+
assertEq(result[0].checked, false, 'backtick item unchecked');
|
|
271
|
+
assertEq(result[1].checked, true, 'backtick item checked');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
console.log('\n=== parseTaskPlanMustHaves: asterisk bullets ===');
|
|
275
|
+
{
|
|
276
|
+
const content = `## Must-Haves
|
|
277
|
+
|
|
278
|
+
* [ ] Asterisk unchecked
|
|
279
|
+
* [x] Asterisk checked
|
|
280
|
+
* Plain asterisk
|
|
281
|
+
`;
|
|
282
|
+
const result = parseTaskPlanMustHaves(content);
|
|
283
|
+
assertEq(result.length, 3, 'handles asterisk bullets');
|
|
284
|
+
assertEq(result[0].checked, false, 'asterisk unchecked');
|
|
285
|
+
assertEq(result[1].checked, true, 'asterisk checked');
|
|
286
|
+
assertEq(result[2].checked, false, 'plain asterisk unchecked');
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
290
|
+
|
|
291
|
+
report();
|