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.
Files changed (504) hide show
  1. package/dist/bundled-extension-paths.d.ts +2 -0
  2. package/dist/bundled-extension-paths.js +10 -0
  3. package/dist/loader.js +45 -28
  4. package/dist/onboarding.js +100 -0
  5. package/dist/resource-loader.js +12 -3
  6. package/dist/resources/GSD-WORKFLOW.md +661 -0
  7. package/dist/resources/agents/researcher.md +29 -0
  8. package/dist/resources/agents/scout.md +56 -0
  9. package/dist/resources/agents/worker.md +31 -0
  10. package/dist/resources/extensions/ask-user-questions.ts +289 -0
  11. package/dist/resources/extensions/async-jobs/async-bash-tool.ts +211 -0
  12. package/dist/resources/extensions/async-jobs/await-tool.ts +101 -0
  13. package/dist/resources/extensions/async-jobs/cancel-job-tool.ts +34 -0
  14. package/dist/resources/extensions/async-jobs/index.ts +133 -0
  15. package/dist/resources/extensions/async-jobs/job-manager.ts +211 -0
  16. package/dist/resources/extensions/bg-shell/index.ts +3179 -0
  17. package/dist/resources/extensions/browser-tools/BROWSER-TOOLS-V2-PROPOSAL.md +1277 -0
  18. package/dist/resources/extensions/browser-tools/capture.ts +165 -0
  19. package/dist/resources/extensions/browser-tools/core.d.ts +205 -0
  20. package/dist/resources/extensions/browser-tools/core.js +1057 -0
  21. package/dist/resources/extensions/browser-tools/evaluate-helpers.ts +184 -0
  22. package/dist/resources/extensions/browser-tools/index.ts +51 -0
  23. package/dist/resources/extensions/browser-tools/lifecycle.ts +270 -0
  24. package/dist/resources/extensions/browser-tools/package.json +24 -0
  25. package/dist/resources/extensions/browser-tools/refs.ts +264 -0
  26. package/dist/resources/extensions/browser-tools/settle.ts +197 -0
  27. package/dist/resources/extensions/browser-tools/state.ts +408 -0
  28. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +652 -0
  29. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +614 -0
  30. package/dist/resources/extensions/browser-tools/tools/assertions.ts +342 -0
  31. package/dist/resources/extensions/browser-tools/tools/forms.ts +801 -0
  32. package/dist/resources/extensions/browser-tools/tools/inspection.ts +492 -0
  33. package/dist/resources/extensions/browser-tools/tools/intent.ts +614 -0
  34. package/dist/resources/extensions/browser-tools/tools/interaction.ts +865 -0
  35. package/dist/resources/extensions/browser-tools/tools/navigation.ts +232 -0
  36. package/dist/resources/extensions/browser-tools/tools/pages.ts +303 -0
  37. package/dist/resources/extensions/browser-tools/tools/refs.ts +541 -0
  38. package/dist/resources/extensions/browser-tools/tools/screenshot.ts +83 -0
  39. package/dist/resources/extensions/browser-tools/tools/session.ts +400 -0
  40. package/dist/resources/extensions/browser-tools/tools/wait.ts +247 -0
  41. package/dist/resources/extensions/browser-tools/utils.ts +660 -0
  42. package/dist/resources/extensions/context7/index.ts +428 -0
  43. package/dist/resources/extensions/context7/package.json +11 -0
  44. package/dist/resources/extensions/get-secrets-from-user.ts +625 -0
  45. package/dist/resources/extensions/google-search/index.ts +336 -0
  46. package/dist/resources/extensions/google-search/package.json +9 -0
  47. package/dist/resources/extensions/gsd/activity-log.ts +116 -0
  48. package/dist/resources/extensions/gsd/auto.ts +3732 -0
  49. package/dist/resources/extensions/gsd/commands.ts +544 -0
  50. package/dist/resources/extensions/gsd/crash-recovery.ts +105 -0
  51. package/dist/resources/extensions/gsd/dashboard-overlay.ts +564 -0
  52. package/dist/resources/extensions/gsd/dispatch-guard.ts +78 -0
  53. package/dist/resources/extensions/gsd/docs/preferences-reference.md +278 -0
  54. package/dist/resources/extensions/gsd/doctor.ts +766 -0
  55. package/dist/resources/extensions/gsd/exit-command.ts +18 -0
  56. package/dist/resources/extensions/gsd/files.ts +857 -0
  57. package/dist/resources/extensions/gsd/git-service.ts +904 -0
  58. package/dist/resources/extensions/gsd/gitignore.ts +200 -0
  59. package/dist/resources/extensions/gsd/guided-flow.ts +1054 -0
  60. package/dist/resources/extensions/gsd/index.ts +735 -0
  61. package/dist/resources/extensions/gsd/metrics.ts +374 -0
  62. package/dist/resources/extensions/gsd/migrate/command.ts +218 -0
  63. package/dist/resources/extensions/gsd/migrate/index.ts +42 -0
  64. package/dist/resources/extensions/gsd/migrate/parser.ts +323 -0
  65. package/dist/resources/extensions/gsd/migrate/parsers.ts +624 -0
  66. package/dist/resources/extensions/gsd/migrate/preview.ts +48 -0
  67. package/dist/resources/extensions/gsd/migrate/transformer.ts +346 -0
  68. package/dist/resources/extensions/gsd/migrate/types.ts +370 -0
  69. package/dist/resources/extensions/gsd/migrate/validator.ts +55 -0
  70. package/dist/resources/extensions/gsd/migrate/writer.ts +539 -0
  71. package/dist/resources/extensions/gsd/native-git-bridge.ts +181 -0
  72. package/dist/resources/extensions/gsd/native-parser-bridge.ts +135 -0
  73. package/dist/resources/extensions/gsd/observability-validator.ts +408 -0
  74. package/dist/resources/extensions/gsd/package.json +11 -0
  75. package/dist/resources/extensions/gsd/paths.ts +339 -0
  76. package/dist/resources/extensions/gsd/post-unit-hooks.ts +449 -0
  77. package/dist/resources/extensions/gsd/preferences.ts +988 -0
  78. package/dist/resources/extensions/gsd/prompt-loader.ts +92 -0
  79. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +25 -0
  80. package/dist/resources/extensions/gsd/prompts/complete-slice.md +27 -0
  81. package/dist/resources/extensions/gsd/prompts/discuss.md +237 -0
  82. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +29 -0
  83. package/dist/resources/extensions/gsd/prompts/execute-task.md +63 -0
  84. package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +3 -0
  85. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -0
  86. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +61 -0
  87. package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +3 -0
  88. package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +29 -0
  89. package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +3 -0
  90. package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +13 -0
  91. package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -0
  92. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +78 -0
  93. package/dist/resources/extensions/gsd/prompts/plan-slice.md +55 -0
  94. package/dist/resources/extensions/gsd/prompts/queue.md +100 -0
  95. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +48 -0
  96. package/dist/resources/extensions/gsd/prompts/replan-slice.md +39 -0
  97. package/dist/resources/extensions/gsd/prompts/research-milestone.md +37 -0
  98. package/dist/resources/extensions/gsd/prompts/research-slice.md +28 -0
  99. package/dist/resources/extensions/gsd/prompts/review-migration.md +66 -0
  100. package/dist/resources/extensions/gsd/prompts/run-uat.md +109 -0
  101. package/dist/resources/extensions/gsd/prompts/system.md +190 -0
  102. package/dist/resources/extensions/gsd/prompts/worktree-merge.md +123 -0
  103. package/dist/resources/extensions/gsd/roadmap-slices.ts +50 -0
  104. package/dist/resources/extensions/gsd/session-forensics.ts +500 -0
  105. package/dist/resources/extensions/gsd/skill-discovery.ts +137 -0
  106. package/dist/resources/extensions/gsd/state.ts +569 -0
  107. package/dist/resources/extensions/gsd/templates/context.md +76 -0
  108. package/dist/resources/extensions/gsd/templates/decisions.md +8 -0
  109. package/dist/resources/extensions/gsd/templates/milestone-summary.md +73 -0
  110. package/dist/resources/extensions/gsd/templates/plan.md +131 -0
  111. package/dist/resources/extensions/gsd/templates/preferences.md +23 -0
  112. package/dist/resources/extensions/gsd/templates/project.md +31 -0
  113. package/dist/resources/extensions/gsd/templates/reassessment.md +28 -0
  114. package/dist/resources/extensions/gsd/templates/requirements.md +81 -0
  115. package/dist/resources/extensions/gsd/templates/research.md +46 -0
  116. package/dist/resources/extensions/gsd/templates/roadmap.md +118 -0
  117. package/dist/resources/extensions/gsd/templates/secrets-manifest.md +22 -0
  118. package/dist/resources/extensions/gsd/templates/slice-context.md +58 -0
  119. package/dist/resources/extensions/gsd/templates/slice-summary.md +99 -0
  120. package/dist/resources/extensions/gsd/templates/state.md +19 -0
  121. package/dist/resources/extensions/gsd/templates/task-plan.md +52 -0
  122. package/dist/resources/extensions/gsd/templates/task-summary.md +57 -0
  123. package/dist/resources/extensions/gsd/templates/uat.md +54 -0
  124. package/dist/resources/extensions/gsd/tests/activity-log-prune.test.ts +297 -0
  125. package/dist/resources/extensions/gsd/tests/activity-log-save.test.ts +127 -0
  126. package/dist/resources/extensions/gsd/tests/auto-draft-pause.test.ts +109 -0
  127. package/dist/resources/extensions/gsd/tests/auto-preflight.test.ts +45 -0
  128. package/dist/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +196 -0
  129. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +53 -0
  130. package/dist/resources/extensions/gsd/tests/collect-from-manifest.test.ts +469 -0
  131. package/dist/resources/extensions/gsd/tests/complete-milestone.test.ts +200 -0
  132. package/dist/resources/extensions/gsd/tests/cost-projection.test.ts +134 -0
  133. package/dist/resources/extensions/gsd/tests/derive-state-deps.test.ts +312 -0
  134. package/dist/resources/extensions/gsd/tests/derive-state-draft.test.ts +299 -0
  135. package/dist/resources/extensions/gsd/tests/derive-state.test.ts +660 -0
  136. package/dist/resources/extensions/gsd/tests/discuss-prompt.test.ts +27 -0
  137. package/dist/resources/extensions/gsd/tests/dispatch-guard.test.ts +91 -0
  138. package/dist/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +170 -0
  139. package/dist/resources/extensions/gsd/tests/doctor.test.ts +594 -0
  140. package/dist/resources/extensions/gsd/tests/draft-promotion.test.ts +169 -0
  141. package/dist/resources/extensions/gsd/tests/exit-command.test.ts +50 -0
  142. package/dist/resources/extensions/gsd/tests/git-service.test.ts +1788 -0
  143. package/dist/resources/extensions/gsd/tests/idle-recovery.test.ts +577 -0
  144. package/dist/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +580 -0
  145. package/dist/resources/extensions/gsd/tests/manifest-status.test.ts +283 -0
  146. package/dist/resources/extensions/gsd/tests/metrics-io.test.ts +176 -0
  147. package/dist/resources/extensions/gsd/tests/metrics.test.ts +188 -0
  148. package/dist/resources/extensions/gsd/tests/migrate-command.test.ts +369 -0
  149. package/dist/resources/extensions/gsd/tests/migrate-parser.test.ts +757 -0
  150. package/dist/resources/extensions/gsd/tests/migrate-transformer.test.ts +635 -0
  151. package/dist/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +414 -0
  152. package/dist/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +297 -0
  153. package/dist/resources/extensions/gsd/tests/migrate-writer.test.ts +398 -0
  154. package/dist/resources/extensions/gsd/tests/must-have-parser.test.ts +291 -0
  155. package/dist/resources/extensions/gsd/tests/network-error-fallback.test.ts +54 -0
  156. package/dist/resources/extensions/gsd/tests/next-milestone-id.test.ts +66 -0
  157. package/dist/resources/extensions/gsd/tests/orphaned-branch.test.ts +353 -0
  158. package/dist/resources/extensions/gsd/tests/parsers.test.ts +1664 -0
  159. package/dist/resources/extensions/gsd/tests/plan-milestone.test.ts +133 -0
  160. package/dist/resources/extensions/gsd/tests/plan-quality-validator.test.ts +363 -0
  161. package/dist/resources/extensions/gsd/tests/post-unit-hooks.test.ts +297 -0
  162. package/dist/resources/extensions/gsd/tests/preferences-hooks.test.ts +226 -0
  163. package/dist/resources/extensions/gsd/tests/queue-draft-detection.test.ts +126 -0
  164. package/dist/resources/extensions/gsd/tests/reassess-prompt.test.ts +142 -0
  165. package/dist/resources/extensions/gsd/tests/regex-hardening.test.ts +281 -0
  166. package/dist/resources/extensions/gsd/tests/remote-questions.test.ts +155 -0
  167. package/dist/resources/extensions/gsd/tests/remote-status.test.ts +99 -0
  168. package/dist/resources/extensions/gsd/tests/replan-slice.test.ts +493 -0
  169. package/dist/resources/extensions/gsd/tests/requirements.test.ts +106 -0
  170. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +35 -0
  171. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +11 -0
  172. package/dist/resources/extensions/gsd/tests/roadmap-slices.test.ts +41 -0
  173. package/dist/resources/extensions/gsd/tests/run-uat.test.ts +316 -0
  174. package/dist/resources/extensions/gsd/tests/secure-env-collect.test.ts +185 -0
  175. package/dist/resources/extensions/gsd/tests/smart-entry-draft.test.ts +123 -0
  176. package/dist/resources/extensions/gsd/tests/test-helpers.ts +61 -0
  177. package/dist/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +219 -0
  178. package/dist/resources/extensions/gsd/tests/unit-runtime.test.ts +234 -0
  179. package/dist/resources/extensions/gsd/tests/workspace-index.test.ts +75 -0
  180. package/dist/resources/extensions/gsd/tests/worktree-integration.test.ts +234 -0
  181. package/dist/resources/extensions/gsd/tests/worktree-manager.test.ts +141 -0
  182. package/dist/resources/extensions/gsd/tests/worktree.test.ts +597 -0
  183. package/dist/resources/extensions/gsd/tests/write-gate.test.ts +122 -0
  184. package/dist/resources/extensions/gsd/types.ts +296 -0
  185. package/dist/resources/extensions/gsd/unit-runtime.ts +184 -0
  186. package/dist/resources/extensions/gsd/workspace-index.ts +189 -0
  187. package/dist/resources/extensions/gsd/worktree-command.ts +845 -0
  188. package/dist/resources/extensions/gsd/worktree-manager.ts +459 -0
  189. package/dist/resources/extensions/gsd/{worktree.js → worktree.ts} +92 -61
  190. package/dist/resources/extensions/mac-tools/index.ts +852 -0
  191. package/dist/resources/extensions/mac-tools/swift-cli/Package.swift +22 -0
  192. package/dist/resources/extensions/mac-tools/swift-cli/Sources/main.swift +1318 -0
  193. package/dist/resources/extensions/mcporter/index.ts +429 -0
  194. package/dist/resources/extensions/remote-questions/config.ts +81 -0
  195. package/dist/resources/extensions/remote-questions/discord-adapter.ts +128 -0
  196. package/dist/resources/extensions/remote-questions/format.ts +163 -0
  197. package/dist/resources/extensions/remote-questions/manager.ts +192 -0
  198. package/dist/resources/extensions/remote-questions/remote-command.ts +361 -0
  199. package/dist/resources/extensions/remote-questions/slack-adapter.ts +92 -0
  200. package/dist/resources/extensions/remote-questions/status.ts +31 -0
  201. package/dist/resources/extensions/remote-questions/store.ts +77 -0
  202. package/dist/resources/extensions/remote-questions/types.ts +75 -0
  203. package/dist/resources/extensions/search-the-web/cache.ts +78 -0
  204. package/dist/resources/extensions/search-the-web/command-search-provider.ts +99 -0
  205. package/dist/resources/extensions/search-the-web/format.ts +258 -0
  206. package/dist/resources/extensions/search-the-web/http.ts +238 -0
  207. package/dist/resources/extensions/search-the-web/index.ts +65 -0
  208. package/dist/resources/extensions/search-the-web/native-search.ts +165 -0
  209. package/dist/resources/extensions/search-the-web/provider.ts +136 -0
  210. package/dist/resources/extensions/search-the-web/tavily.ts +116 -0
  211. package/dist/resources/extensions/search-the-web/tool-fetch-page.ts +581 -0
  212. package/dist/resources/extensions/search-the-web/tool-llm-context.ts +620 -0
  213. package/dist/resources/extensions/search-the-web/tool-search.ts +635 -0
  214. package/dist/resources/extensions/search-the-web/url-utils.ts +91 -0
  215. package/dist/resources/extensions/shared/bundled-extension-paths.ts +11 -0
  216. package/dist/resources/extensions/shared/confirm-ui.ts +126 -0
  217. package/dist/resources/extensions/shared/interview-ui.ts +613 -0
  218. package/dist/resources/extensions/shared/next-action-ui.ts +197 -0
  219. package/dist/resources/extensions/shared/progress-widget.ts +282 -0
  220. package/dist/resources/extensions/shared/terminal.ts +23 -0
  221. package/dist/resources/extensions/shared/thinking-widget.ts +107 -0
  222. package/dist/resources/extensions/shared/ui.ts +400 -0
  223. package/dist/resources/extensions/shared/wizard-ui.ts +551 -0
  224. package/dist/resources/extensions/slash-commands/audit.ts +88 -0
  225. package/dist/resources/extensions/slash-commands/clear.ts +10 -0
  226. package/dist/resources/extensions/slash-commands/create-extension.ts +297 -0
  227. package/dist/resources/extensions/slash-commands/create-slash-command.ts +234 -0
  228. package/dist/resources/extensions/slash-commands/index.ts +12 -0
  229. package/dist/resources/extensions/subagent/agents.ts +126 -0
  230. package/dist/resources/extensions/subagent/index.ts +1072 -0
  231. package/dist/resources/extensions/subagent/isolation.ts +498 -0
  232. package/dist/resources/extensions/ttsr/index.ts +163 -0
  233. package/dist/resources/extensions/ttsr/rule-loader.ts +121 -0
  234. package/dist/resources/extensions/ttsr/ttsr-interrupt.md +6 -0
  235. package/dist/resources/extensions/ttsr/ttsr-manager.ts +430 -0
  236. package/dist/resources/extensions/universal-config/discovery.ts +78 -0
  237. package/dist/resources/extensions/universal-config/format.ts +160 -0
  238. package/dist/resources/extensions/universal-config/index.ts +118 -0
  239. package/dist/resources/extensions/universal-config/package.json +11 -0
  240. package/dist/resources/extensions/universal-config/scanners.ts +579 -0
  241. package/dist/resources/extensions/universal-config/tests/discovery.test.ts +111 -0
  242. package/dist/resources/extensions/universal-config/tests/format.test.ts +111 -0
  243. package/dist/resources/extensions/universal-config/tests/scanners.test.ts +438 -0
  244. package/dist/resources/extensions/universal-config/tools.ts +60 -0
  245. package/dist/resources/extensions/universal-config/types.ts +116 -0
  246. package/dist/resources/extensions/voice/index.ts +271 -0
  247. package/dist/resources/extensions/voice/speech-recognizer.py +504 -0
  248. package/dist/resources/extensions/voice/speech-recognizer.swift +154 -0
  249. package/dist/resources/skills/debug-like-expert/SKILL.md +231 -0
  250. package/dist/resources/skills/debug-like-expert/references/debugging-mindset.md +253 -0
  251. package/dist/resources/skills/debug-like-expert/references/hypothesis-testing.md +373 -0
  252. package/dist/resources/skills/debug-like-expert/references/investigation-techniques.md +337 -0
  253. package/dist/resources/skills/debug-like-expert/references/verification-patterns.md +425 -0
  254. package/dist/resources/skills/debug-like-expert/references/when-to-research.md +361 -0
  255. package/dist/resources/skills/frontend-design/SKILL.md +45 -0
  256. package/dist/resources/skills/github-workflows/SKILL.md +92 -0
  257. package/dist/resources/skills/github-workflows/references/gh/SKILL.md +255 -0
  258. package/dist/resources/skills/github-workflows/references/gh/references/issue-stories.md +204 -0
  259. package/dist/resources/skills/github-workflows/references/gh/references/labels.md +170 -0
  260. package/dist/resources/skills/github-workflows/references/gh/references/milestones.md +158 -0
  261. package/dist/resources/skills/github-workflows/references/gh/references/projects-v2.md +177 -0
  262. package/dist/resources/skills/github-workflows/references/gh/scripts/experiment_cleanup.py +191 -0
  263. package/dist/resources/skills/github-workflows/references/gh/scripts/github_project_setup.py +799 -0
  264. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  265. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +608 -0
  266. package/dist/resources/skills/swiftui/SKILL.md +208 -0
  267. package/dist/resources/skills/swiftui/references/animations.md +921 -0
  268. package/dist/resources/skills/swiftui/references/architecture.md +1561 -0
  269. package/dist/resources/skills/swiftui/references/layout-system.md +1186 -0
  270. package/dist/resources/skills/swiftui/references/navigation.md +1492 -0
  271. package/dist/resources/skills/swiftui/references/networking-async.md +214 -0
  272. package/dist/resources/skills/swiftui/references/performance.md +1706 -0
  273. package/dist/resources/skills/swiftui/references/platform-integration.md +204 -0
  274. package/dist/resources/skills/swiftui/references/state-management.md +1443 -0
  275. package/dist/resources/skills/swiftui/references/swiftdata.md +297 -0
  276. package/dist/resources/skills/swiftui/references/testing-debugging.md +247 -0
  277. package/dist/resources/skills/swiftui/references/uikit-appkit-interop.md +218 -0
  278. package/dist/resources/skills/swiftui/workflows/add-feature.md +191 -0
  279. package/dist/resources/skills/swiftui/workflows/build-new-app.md +311 -0
  280. package/dist/resources/skills/swiftui/workflows/debug-swiftui.md +192 -0
  281. package/dist/resources/skills/swiftui/workflows/optimize-performance.md +197 -0
  282. package/dist/resources/skills/swiftui/workflows/ship-app.md +203 -0
  283. package/dist/resources/skills/swiftui/workflows/write-tests.md +235 -0
  284. package/dist/wizard.js +1 -0
  285. package/package.json +8 -6
  286. package/packages/native/dist/fd/index.d.ts +1 -0
  287. package/packages/native/dist/fd/index.js +1 -0
  288. package/packages/native/dist/grep/index.d.ts +2 -1
  289. package/packages/native/dist/grep/index.js +1 -0
  290. package/packages/native/src/__tests__/fd.test.mjs +35 -0
  291. package/packages/native/src/__tests__/grep.test.mjs +26 -9
  292. package/packages/native/src/fd/index.ts +1 -0
  293. package/packages/native/src/grep/index.ts +3 -2
  294. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  295. package/packages/pi-agent-core/dist/agent-loop.js +169 -55
  296. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  297. package/packages/pi-agent-core/dist/agent.d.ts +13 -1
  298. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  299. package/packages/pi-agent-core/dist/agent.js +16 -0
  300. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  301. package/packages/pi-agent-core/dist/types.d.ts +91 -1
  302. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  303. package/packages/pi-agent-core/dist/types.js.map +1 -1
  304. package/packages/pi-agent-core/src/agent-loop.ts +273 -63
  305. package/packages/pi-agent-core/src/agent.ts +24 -0
  306. package/packages/pi-agent-core/src/types.ts +98 -0
  307. package/packages/pi-ai/dist/env-api-keys.js +2 -0
  308. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  309. package/packages/pi-ai/dist/models.generated.d.ts +314 -0
  310. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  311. package/packages/pi-ai/dist/models.generated.js +236 -0
  312. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  313. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  314. package/packages/pi-ai/dist/providers/google-gemini-cli.js +6 -0
  315. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  316. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  317. package/packages/pi-ai/dist/providers/openai-completions.js +2 -0
  318. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  319. package/packages/pi-ai/dist/types.d.ts +1 -1
  320. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  321. package/packages/pi-ai/dist/types.js.map +1 -1
  322. package/packages/pi-ai/src/env-api-keys.ts +2 -0
  323. package/packages/pi-ai/src/models.generated.ts +236 -0
  324. package/packages/pi-ai/src/providers/google-gemini-cli.ts +8 -0
  325. package/packages/pi-ai/src/providers/openai-completions.ts +3 -0
  326. package/packages/pi-ai/src/types.ts +2 -1
  327. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  328. package/packages/pi-coding-agent/dist/cli/args.js +1 -0
  329. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +26 -0
  331. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/agent-session.js +137 -22
  333. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +20 -0
  335. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/core/auth-storage.js +43 -0
  337. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts +51 -0
  339. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/fallback-resolver.js +119 -0
  341. package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -0
  342. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.d.ts +2 -0
  343. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.d.ts.map +1 -0
  344. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +183 -0
  345. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -0
  346. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
  347. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  348. package/packages/pi-coding-agent/dist/core/index.js +1 -0
  349. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  352. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +12 -1
  354. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/core/session-manager.js +37 -1
  356. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  357. package/packages/pi-coding-agent/dist/core/session-manager.test.d.ts +2 -0
  358. package/packages/pi-coding-agent/dist/core/session-manager.test.d.ts.map +1 -0
  359. package/packages/pi-coding-agent/dist/core/session-manager.test.js +61 -0
  360. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -0
  361. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  362. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/settings-manager.js +47 -0
  364. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  366. package/packages/pi-coding-agent/dist/core/tools/find.js +1 -0
  367. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  368. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +6 -15
  370. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +18 -1
  372. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +46 -4
  374. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  375. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +25 -2
  377. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  378. package/packages/pi-coding-agent/src/cli/args.ts +1 -0
  379. package/packages/pi-coding-agent/src/core/agent-session.ts +167 -22
  380. package/packages/pi-coding-agent/src/core/auth-storage.ts +45 -0
  381. package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +229 -0
  382. package/packages/pi-coding-agent/src/core/fallback-resolver.ts +165 -0
  383. package/packages/pi-coding-agent/src/core/index.ts +1 -0
  384. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  385. package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -0
  386. package/packages/pi-coding-agent/src/core/session-manager.ts +51 -1
  387. package/packages/pi-coding-agent/src/core/settings-manager.ts +66 -0
  388. package/packages/pi-coding-agent/src/core/tools/find.ts +1 -0
  389. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +6 -16
  390. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +49 -4
  391. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -2
  392. package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
  393. package/packages/pi-tui/dist/autocomplete.js +3 -4
  394. package/packages/pi-tui/dist/autocomplete.js.map +1 -1
  395. package/packages/pi-tui/dist/components/editor.d.ts +7 -0
  396. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  397. package/packages/pi-tui/dist/components/editor.js +57 -50
  398. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  399. package/packages/pi-tui/src/autocomplete.ts +3 -5
  400. package/packages/pi-tui/src/components/editor.ts +70 -49
  401. package/pkg/dist/core/export-html/ansi-to-html.d.ts +22 -0
  402. package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  403. package/pkg/dist/core/export-html/ansi-to-html.js +249 -0
  404. package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -0
  405. package/pkg/dist/core/export-html/index.d.ts +37 -0
  406. package/pkg/dist/core/export-html/index.d.ts.map +1 -0
  407. package/pkg/dist/core/export-html/index.js +223 -0
  408. package/pkg/dist/core/export-html/index.js.map +1 -0
  409. package/pkg/dist/core/export-html/template.css +971 -0
  410. package/pkg/dist/core/export-html/template.html +54 -0
  411. package/pkg/dist/core/export-html/template.js +1583 -0
  412. package/pkg/dist/core/export-html/tool-renderer.d.ts +38 -0
  413. package/pkg/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  414. package/pkg/dist/core/export-html/tool-renderer.js +70 -0
  415. package/pkg/dist/core/export-html/tool-renderer.js.map +1 -0
  416. package/pkg/dist/core/export-html/vendor/highlight.min.js +1213 -0
  417. package/pkg/dist/core/export-html/vendor/marked.min.js +6 -0
  418. package/scripts/postinstall.js +30 -17
  419. package/src/resources/extensions/bg-shell/index.ts +51 -7
  420. package/src/resources/extensions/gsd/activity-log.ts +61 -14
  421. package/src/resources/extensions/gsd/auto.ts +288 -19
  422. package/src/resources/extensions/gsd/commands.ts +9 -3
  423. package/src/resources/extensions/gsd/dashboard-overlay.ts +55 -12
  424. package/src/resources/extensions/gsd/docs/preferences-reference.md +25 -0
  425. package/src/resources/extensions/gsd/doctor.ts +60 -3
  426. package/src/resources/extensions/gsd/files.ts +45 -1
  427. package/src/resources/extensions/gsd/git-service.ts +46 -41
  428. package/src/resources/extensions/gsd/guided-flow.ts +81 -9
  429. package/src/resources/extensions/gsd/index.ts +62 -1
  430. package/src/resources/extensions/gsd/native-git-bridge.ts +181 -0
  431. package/src/resources/extensions/gsd/paths.ts +35 -4
  432. package/src/resources/extensions/gsd/post-unit-hooks.ts +449 -0
  433. package/src/resources/extensions/gsd/preferences.ts +232 -1
  434. package/src/resources/extensions/gsd/prompt-loader.ts +45 -3
  435. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  436. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -3
  437. package/src/resources/extensions/gsd/prompts/discuss.md +10 -8
  438. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  439. package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +3 -1
  440. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -1
  441. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
  442. package/src/resources/extensions/gsd/prompts/guided-execute-task.md +3 -1
  443. package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +4 -2
  444. package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +3 -1
  445. package/src/resources/extensions/gsd/prompts/guided-research-slice.md +3 -1
  446. package/src/resources/extensions/gsd/prompts/plan-milestone.md +9 -12
  447. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -3
  448. package/src/resources/extensions/gsd/prompts/queue.md +3 -1
  449. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  450. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  451. package/src/resources/extensions/gsd/state.ts +130 -18
  452. package/src/resources/extensions/gsd/templates/context.md +1 -1
  453. package/src/resources/extensions/gsd/templates/state.md +3 -3
  454. package/src/resources/extensions/gsd/tests/activity-log-save.test.ts +127 -0
  455. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +5 -1
  456. package/src/resources/extensions/gsd/tests/doctor.test.ts +115 -1
  457. package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +6 -2
  458. package/src/resources/extensions/gsd/tests/git-service.test.ts +35 -35
  459. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +8 -8
  460. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +4 -1
  461. package/src/resources/extensions/gsd/tests/network-error-fallback.test.ts +54 -0
  462. package/src/resources/extensions/gsd/tests/orphaned-branch.test.ts +5 -5
  463. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +297 -0
  464. package/src/resources/extensions/gsd/tests/preferences-hooks.test.ts +226 -0
  465. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +12 -0
  466. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +6 -0
  467. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +4 -4
  468. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +4 -4
  469. package/src/resources/extensions/gsd/tests/worktree.test.ts +19 -19
  470. package/src/resources/extensions/gsd/types.ts +109 -0
  471. package/src/resources/extensions/gsd/worktree-manager.ts +72 -13
  472. package/src/resources/extensions/gsd/worktree.ts +5 -4
  473. package/src/resources/extensions/search-the-web/command-search-provider.ts +8 -4
  474. package/src/resources/extensions/search-the-web/native-search.ts +32 -23
  475. package/src/resources/extensions/search-the-web/provider.ts +19 -2
  476. package/src/resources/extensions/search-the-web/tool-fetch-page.ts +62 -0
  477. package/src/resources/extensions/search-the-web/tool-llm-context.ts +62 -3
  478. package/src/resources/extensions/search-the-web/tool-search.ts +62 -3
  479. package/src/resources/extensions/shared/bundled-extension-paths.ts +11 -0
  480. package/src/resources/extensions/subagent/index.ts +2 -1
  481. package/src/resources/skills/github-workflows/SKILL.md +5 -0
  482. package/dist/resources/extensions/gsd/git-service.d.ts +0 -225
  483. package/dist/resources/extensions/gsd/git-service.js +0 -756
  484. package/dist/resources/extensions/gsd/preferences.d.ts +0 -122
  485. package/dist/resources/extensions/gsd/preferences.js +0 -616
  486. package/dist/resources/extensions/gsd/worktree.d.ts +0 -106
  487. package/dist/resources/extensions/remote-questions/config.d.ts +0 -14
  488. package/dist/resources/extensions/remote-questions/config.js +0 -68
  489. package/dist/resources/extensions/remote-questions/discord-adapter.d.ts +0 -17
  490. package/dist/resources/extensions/remote-questions/discord-adapter.js +0 -118
  491. package/dist/resources/extensions/remote-questions/format.d.ts +0 -38
  492. package/dist/resources/extensions/remote-questions/format.js +0 -119
  493. package/dist/resources/extensions/remote-questions/manager.d.ts +0 -23
  494. package/dist/resources/extensions/remote-questions/manager.js +0 -161
  495. package/dist/resources/extensions/remote-questions/remote-command.d.ts +0 -6
  496. package/dist/resources/extensions/remote-questions/remote-command.js +0 -358
  497. package/dist/resources/extensions/remote-questions/slack-adapter.d.ts +0 -15
  498. package/dist/resources/extensions/remote-questions/slack-adapter.js +0 -82
  499. package/dist/resources/extensions/remote-questions/status.d.ts +0 -9
  500. package/dist/resources/extensions/remote-questions/status.js +0 -25
  501. package/dist/resources/extensions/remote-questions/store.d.ts +0 -11
  502. package/dist/resources/extensions/remote-questions/store.js +0 -66
  503. package/dist/resources/extensions/remote-questions/types.d.ts +0 -68
  504. package/dist/resources/extensions/remote-questions/types.js +0 -4
@@ -0,0 +1,660 @@
1
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { tmpdir } from 'node:os';
4
+
5
+ import { deriveState, isSliceComplete, isMilestoneComplete } from '../state.ts';
6
+ import { createTestContext } from './test-helpers.ts';
7
+
8
+ const { assertEq, assertTrue, report } = createTestContext();
9
+ // ─── Fixture Helpers ───────────────────────────────────────────────────────
10
+
11
+ function createFixtureBase(): string {
12
+ const base = mkdtempSync(join(tmpdir(), 'gsd-state-test-'));
13
+ mkdirSync(join(base, '.gsd', 'milestones'), { recursive: true });
14
+ return base;
15
+ }
16
+
17
+ function writeRoadmap(base: string, mid: string, content: string): void {
18
+ const dir = join(base, '.gsd', 'milestones', mid);
19
+ mkdirSync(dir, { recursive: true });
20
+ writeFileSync(join(dir, `${mid}-ROADMAP.md`), content);
21
+ }
22
+
23
+ function writePlan(base: string, mid: string, sid: string, content: string): void {
24
+ const dir = join(base, '.gsd', 'milestones', mid, 'slices', sid);
25
+ mkdirSync(join(dir, 'tasks'), { recursive: true });
26
+ writeFileSync(join(dir, `${sid}-PLAN.md`), content);
27
+ }
28
+
29
+ function writeContinue(base: string, mid: string, sid: string, content: string): void {
30
+ const dir = join(base, '.gsd', 'milestones', mid, 'slices', sid);
31
+ mkdirSync(dir, { recursive: true });
32
+ writeFileSync(join(dir, `${sid}-CONTINUE.md`), content);
33
+ }
34
+
35
+ function writeMilestoneSummary(base: string, mid: string, content: string): void {
36
+ const dir = join(base, '.gsd', 'milestones', mid);
37
+ mkdirSync(dir, { recursive: true });
38
+ writeFileSync(join(dir, `${mid}-SUMMARY.md`), content);
39
+ }
40
+
41
+ function writeRequirements(base: string, content: string): void {
42
+ writeFileSync(join(base, '.gsd', 'REQUIREMENTS.md'), content);
43
+ }
44
+
45
+ function cleanup(base: string): void {
46
+ rmSync(base, { recursive: true, force: true });
47
+ }
48
+
49
+ // ═══════════════════════════════════════════════════════════════════════════
50
+ // Test Groups
51
+ // ═══════════════════════════════════════════════════════════════════════════
52
+
53
+ async function main(): Promise<void> {
54
+
55
+ // ─── Test 1: empty milestones dir → pre-planning ───────────────────────
56
+ console.log('\n=== empty milestones dir → pre-planning ===');
57
+ {
58
+ const base = createFixtureBase();
59
+ try {
60
+ const state = await deriveState(base);
61
+
62
+ assertEq(state.phase, 'pre-planning', 'phase is pre-planning');
63
+ assertEq(state.activeMilestone, null, 'activeMilestone is null');
64
+ assertEq(state.activeSlice, null, 'activeSlice is null');
65
+ assertEq(state.activeTask, null, 'activeTask is null');
66
+ assertEq(state.registry, [], 'registry is empty');
67
+ assertEq(state.progress?.milestones?.done, 0, 'milestones done = 0');
68
+ assertEq(state.progress?.milestones?.total, 0, 'milestones total = 0');
69
+ } finally {
70
+ cleanup(base);
71
+ }
72
+ }
73
+
74
+ // ─── Test 2: milestone dir exists but no roadmap → pre-planning ────────
75
+ console.log('\n=== milestone dir exists but no roadmap → pre-planning ===');
76
+ {
77
+ const base = createFixtureBase();
78
+ try {
79
+ // Create M001 directory but no roadmap file
80
+ mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
81
+
82
+ const state = await deriveState(base);
83
+
84
+ assertEq(state.phase, 'pre-planning', 'phase is pre-planning');
85
+ assertTrue(state.activeMilestone !== null, 'activeMilestone is not null');
86
+ assertEq(state.activeMilestone?.id, 'M001', 'activeMilestone id is M001');
87
+ assertEq(state.activeSlice, null, 'activeSlice is null');
88
+ assertEq(state.activeTask, null, 'activeTask is null');
89
+ assertEq(state.registry.length, 1, 'registry has 1 entry');
90
+ assertEq(state.registry[0]?.status, 'active', 'registry entry status is active');
91
+ } finally {
92
+ cleanup(base);
93
+ }
94
+ }
95
+
96
+ // ─── Test 3: roadmap with incomplete slice, no plan → planning ─────────
97
+ console.log('\n=== roadmap with incomplete slice, no plan → planning ===');
98
+ {
99
+ const base = createFixtureBase();
100
+ try {
101
+ writeRoadmap(base, 'M001', `# M001: Test Milestone
102
+
103
+ **Vision:** Test planning phase.
104
+
105
+ ## Slices
106
+
107
+ - [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
108
+ > After this: Slice is done.
109
+ `);
110
+
111
+ const state = await deriveState(base);
112
+
113
+ assertEq(state.phase, 'planning', 'phase is planning');
114
+ assertTrue(state.activeSlice !== null, 'activeSlice is not null');
115
+ assertEq(state.activeSlice?.id, 'S01', 'activeSlice id is S01');
116
+ assertEq(state.activeTask, null, 'activeTask is null');
117
+ assertEq(state.progress?.slices?.done, 0, 'slices done = 0');
118
+ assertEq(state.progress?.slices?.total, 1, 'slices total = 1');
119
+ } finally {
120
+ cleanup(base);
121
+ }
122
+ }
123
+
124
+ // ─── Test 4: roadmap + plan with incomplete tasks → executing ──────────
125
+ console.log('\n=== roadmap + plan with incomplete tasks → executing ===');
126
+ {
127
+ const base = createFixtureBase();
128
+ try {
129
+ writeRoadmap(base, 'M001', `# M001: Test Milestone
130
+
131
+ **Vision:** Test executing phase.
132
+
133
+ ## Slices
134
+
135
+ - [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
136
+ > After this: Slice is done.
137
+ `);
138
+
139
+ writePlan(base, 'M001', 'S01', `# S01: Test Slice
140
+
141
+ **Goal:** Test executing.
142
+ **Demo:** Tests pass.
143
+
144
+ ## Tasks
145
+
146
+ - [ ] **T01: First** \`est:10m\`
147
+ First task description.
148
+
149
+ - [ ] **T02: Second** \`est:10m\`
150
+ Second task description.
151
+ `);
152
+
153
+ const state = await deriveState(base);
154
+
155
+ assertEq(state.phase, 'executing', 'phase is executing');
156
+ assertTrue(state.activeTask !== null, 'activeTask is not null');
157
+ assertEq(state.activeTask?.id, 'T01', 'activeTask id is T01');
158
+ assertEq(state.progress?.tasks?.done, 0, 'tasks done = 0');
159
+ assertEq(state.progress?.tasks?.total, 2, 'tasks total = 2');
160
+ } finally {
161
+ cleanup(base);
162
+ }
163
+ }
164
+
165
+ // ─── Test 5: executing + continue file → resume message ─────────────
166
+ console.log('\n=== executing + continue file → resume message ===');
167
+ {
168
+ const base = createFixtureBase();
169
+ try {
170
+ writeRoadmap(base, 'M001', `# M001: Test Milestone
171
+
172
+ **Vision:** Test interrupted resume.
173
+
174
+ ## Slices
175
+
176
+ - [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
177
+ > After this: Slice is done.
178
+ `);
179
+
180
+ writePlan(base, 'M001', 'S01', `# S01: Test Slice
181
+
182
+ **Goal:** Test interrupted.
183
+ **Demo:** Tests pass.
184
+
185
+ ## Tasks
186
+
187
+ - [ ] **T01: First Task** \`est:10m\`
188
+ First task description.
189
+ `);
190
+
191
+ writeContinue(base, 'M001', 'S01', `---
192
+ milestone: M001
193
+ slice: S01
194
+ task: T01
195
+ step: 2
196
+ totalSteps: 5
197
+ status: interrupted
198
+ savedAt: 2026-03-10T10:00:00Z
199
+ ---
200
+
201
+ # Continue: T01
202
+
203
+ ## Completed Work
204
+ Steps 1 done.
205
+
206
+ ## Remaining Work
207
+ Steps 2-5.
208
+
209
+ ## Next Action
210
+ Continue from step 2.
211
+ `);
212
+
213
+ const state = await deriveState(base);
214
+
215
+ assertEq(state.phase, 'executing', 'interrupted: phase is executing');
216
+ assertTrue(state.activeTask !== null, 'interrupted: activeTask is not null');
217
+ assertEq(state.activeTask?.id, 'T01', 'interrupted: activeTask id is T01');
218
+ assertTrue(
219
+ state.nextAction.includes('Resume') || state.nextAction.includes('resume') || state.nextAction.includes('continue.md'),
220
+ 'interrupted: nextAction mentions Resume/resume/continue.md'
221
+ );
222
+ } finally {
223
+ cleanup(base);
224
+ }
225
+ }
226
+
227
+ // ─── Test 6: all tasks done, slice not [x] → summarizing ──────────────
228
+ console.log('\n=== all tasks done, slice not [x] → summarizing ===');
229
+ {
230
+ const base = createFixtureBase();
231
+ try {
232
+ writeRoadmap(base, 'M001', `# M001: Test Milestone
233
+
234
+ **Vision:** Test summarizing phase.
235
+
236
+ ## Slices
237
+
238
+ - [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
239
+ > After this: Slice is done.
240
+ `);
241
+
242
+ writePlan(base, 'M001', 'S01', `# S01: Test Slice
243
+
244
+ **Goal:** Test summarizing.
245
+ **Demo:** Tests pass.
246
+
247
+ ## Tasks
248
+
249
+ - [x] **T01: First Done** \`est:10m\`
250
+ Already completed.
251
+
252
+ - [x] **T02: Second Done** \`est:10m\`
253
+ Also completed.
254
+ `);
255
+
256
+ const state = await deriveState(base);
257
+
258
+ assertEq(state.phase, 'summarizing', 'summarizing: phase is summarizing');
259
+ assertTrue(state.activeSlice !== null, 'summarizing: activeSlice is not null');
260
+ assertEq(state.activeSlice?.id, 'S01', 'summarizing: activeSlice id is S01');
261
+ assertEq(state.activeTask, null, 'summarizing: activeTask is null');
262
+ assertTrue(
263
+ state.nextAction.toLowerCase().includes('summary') || state.nextAction.toLowerCase().includes('complete'),
264
+ 'summarizing: nextAction mentions summary or complete'
265
+ );
266
+ assertEq(state.progress?.tasks?.done, 2, 'summarizing: tasks done = 2');
267
+ assertEq(state.progress?.tasks?.total, 2, 'summarizing: tasks total = 2');
268
+ } finally {
269
+ cleanup(base);
270
+ }
271
+ }
272
+
273
+ // ─── Test 7: all milestones complete → complete ────────────────────────
274
+ console.log('\n=== all milestones complete → complete ===');
275
+ {
276
+ const base = createFixtureBase();
277
+ try {
278
+ writeRoadmap(base, 'M001', `# M001: Test Milestone
279
+
280
+ **Vision:** Test complete phase.
281
+
282
+ ## Slices
283
+
284
+ - [x] **S01: Done Slice** \`risk:low\` \`depends:[]\`
285
+ > After this: Done.
286
+ `);
287
+
288
+ writeMilestoneSummary(base, 'M001', `# M001 Summary\n\nMilestone complete.`);
289
+
290
+ const state = await deriveState(base);
291
+
292
+ assertEq(state.phase, 'complete', 'complete: phase is complete');
293
+ assertEq(state.activeSlice, null, 'complete: activeSlice is null');
294
+ assertEq(state.activeTask, null, 'complete: activeTask is null');
295
+ assertTrue(
296
+ state.nextAction.toLowerCase().includes('complete'),
297
+ 'complete: nextAction mentions complete'
298
+ );
299
+ assertEq(state.registry.length, 1, 'complete: registry has 1 entry');
300
+ assertEq(state.registry[0]?.status, 'complete', 'complete: registry[0] status is complete');
301
+ } finally {
302
+ cleanup(base);
303
+ }
304
+ }
305
+
306
+ // ─── Test 8: blocked dependencies ──────────────────────────────────────
307
+ console.log('\n=== blocked dependencies ===');
308
+ {
309
+ // Case A: S01 active (deps satisfied), S02 blocked on S01
310
+ const base1 = createFixtureBase();
311
+ try {
312
+ writeRoadmap(base1, 'M001', `# M001: Test Milestone
313
+
314
+ **Vision:** Test blocked deps.
315
+
316
+ ## Slices
317
+
318
+ - [ ] **S01: First** \`risk:low\` \`depends:[]\`
319
+ > After this: S01 done.
320
+
321
+ - [ ] **S02: Second** \`risk:low\` \`depends:[S01]\`
322
+ > After this: S02 done.
323
+ `);
324
+
325
+ // S01 has a plan with incomplete task — it's the active slice
326
+ writePlan(base1, 'M001', 'S01', `# S01: First
327
+
328
+ **Goal:** First slice.
329
+ **Demo:** Tests pass.
330
+
331
+ ## Tasks
332
+
333
+ - [ ] **T01: Incomplete** \`est:10m\`
334
+ Still working.
335
+ `);
336
+
337
+ const state1 = await deriveState(base1);
338
+
339
+ assertEq(state1.phase, 'executing', 'blocked-A: phase is executing (S01 active)');
340
+ assertEq(state1.activeSlice?.id, 'S01', 'blocked-A: activeSlice is S01');
341
+ } finally {
342
+ cleanup(base1);
343
+ }
344
+
345
+ // Case B: S01 depends on nonexistent S99 → truly blocked
346
+ const base2 = createFixtureBase();
347
+ try {
348
+ writeRoadmap(base2, 'M001', `# M001: Test Milestone
349
+
350
+ **Vision:** Test truly blocked.
351
+
352
+ ## Slices
353
+
354
+ - [ ] **S01: Blocked** \`risk:low\` \`depends:[S99]\`
355
+ > After this: Done.
356
+ `);
357
+
358
+ const state2 = await deriveState(base2);
359
+
360
+ assertEq(state2.phase, 'blocked', 'blocked-B: phase is blocked');
361
+ assertEq(state2.activeSlice, null, 'blocked-B: activeSlice is null');
362
+ assertTrue(state2.blockers.length > 0, 'blocked-B: blockers array is non-empty');
363
+ } finally {
364
+ cleanup(base2);
365
+ }
366
+ }
367
+
368
+ // ─── Test 9: multi-milestone registry ──────────────────────────────────
369
+ console.log('\n=== multi-milestone registry ===');
370
+ {
371
+ const base = createFixtureBase();
372
+ try {
373
+ // M001: complete (all slices done)
374
+ writeRoadmap(base, 'M001', `# M001: First Milestone
375
+
376
+ **Vision:** Already done.
377
+
378
+ ## Slices
379
+
380
+ - [x] **S01: Done** \`risk:low\` \`depends:[]\`
381
+ > After this: Done.
382
+ `);
383
+
384
+ writeMilestoneSummary(base, 'M001', `# M001 Summary\n\nFirst milestone complete.`);
385
+
386
+ // M002: active (has incomplete slices)
387
+ writeRoadmap(base, 'M002', `# M002: Second Milestone
388
+
389
+ **Vision:** Currently active.
390
+
391
+ ## Slices
392
+
393
+ - [ ] **S01: In Progress** \`risk:low\` \`depends:[]\`
394
+ > After this: Done.
395
+ `);
396
+
397
+ // M003: just a dir (no roadmap → pending since M002 is already active)
398
+ mkdirSync(join(base, '.gsd', 'milestones', 'M003'), { recursive: true });
399
+
400
+ const state = await deriveState(base);
401
+
402
+ assertEq(state.registry.length, 3, 'multi-ms: registry has 3 entries');
403
+ assertEq(state.registry[0]?.id, 'M001', 'multi-ms: registry[0] is M001');
404
+ assertEq(state.registry[0]?.status, 'complete', 'multi-ms: M001 is complete');
405
+ assertEq(state.registry[1]?.id, 'M002', 'multi-ms: registry[1] is M002');
406
+ assertEq(state.registry[1]?.status, 'active', 'multi-ms: M002 is active');
407
+ assertEq(state.registry[2]?.id, 'M003', 'multi-ms: registry[2] is M003');
408
+ assertEq(state.registry[2]?.status, 'pending', 'multi-ms: M003 is pending');
409
+ assertEq(state.activeMilestone?.id, 'M002', 'multi-ms: activeMilestone is M002');
410
+ assertEq(state.progress?.milestones?.done, 1, 'multi-ms: milestones done = 1');
411
+ assertEq(state.progress?.milestones?.total, 3, 'multi-ms: milestones total = 3');
412
+ } finally {
413
+ cleanup(base);
414
+ }
415
+ }
416
+
417
+ // ─── Test 10: requirements integration ─────────────────────────────────
418
+ console.log('\n=== requirements integration ===');
419
+ {
420
+ const base = createFixtureBase();
421
+ try {
422
+ writeRequirements(base, `# Requirements
423
+
424
+ ## Active
425
+
426
+ ### R001 — First Active Requirement
427
+ - Status: active
428
+ - Description: Something active.
429
+
430
+ ### R002 — Second Active Requirement
431
+ - Status: active
432
+ - Description: Another active one.
433
+
434
+ ## Validated
435
+
436
+ ### R003 — Validated Requirement
437
+ - Status: validated
438
+ - Description: Already validated.
439
+
440
+ ## Deferred
441
+
442
+ ### R004 — Deferred Requirement
443
+ - Status: deferred
444
+ - Description: Pushed back.
445
+
446
+ ### R005 — Another Deferred
447
+ - Status: deferred
448
+ - Description: Also deferred.
449
+
450
+ ## Out of Scope
451
+
452
+ ### R006 — Out of Scope Requirement
453
+ - Status: out-of-scope
454
+ - Description: Not doing this.
455
+ `);
456
+
457
+ // Need at least an empty milestones dir for deriveState
458
+ const state = await deriveState(base);
459
+
460
+ assertTrue(state.requirements !== undefined, 'requirements: requirements object exists');
461
+ assertEq(state.requirements?.active, 2, 'requirements: active = 2');
462
+ assertEq(state.requirements?.validated, 1, 'requirements: validated = 1');
463
+ assertEq(state.requirements?.deferred, 2, 'requirements: deferred = 2');
464
+ assertEq(state.requirements?.outOfScope, 1, 'requirements: outOfScope = 1');
465
+ assertEq(state.requirements?.total, 6, 'requirements: total = 6 (sum of all)');
466
+ } finally {
467
+ cleanup(base);
468
+ }
469
+ }
470
+
471
+ // ─── Test 11: all slices [x], no summary → completing-milestone ────────
472
+ console.log('\n=== all slices [x], no summary → completing-milestone ===');
473
+ {
474
+ const base = createFixtureBase();
475
+ try {
476
+ writeRoadmap(base, 'M001', `# M001: Test Milestone
477
+
478
+ **Vision:** Test completing-milestone phase.
479
+
480
+ ## Slices
481
+
482
+ - [x] **S01: First Done** \`risk:low\` \`depends:[]\`
483
+ > After this: S01 complete.
484
+
485
+ - [x] **S02: Second Done** \`risk:low\` \`depends:[S01]\`
486
+ > After this: S02 complete.
487
+ `);
488
+
489
+ const state = await deriveState(base);
490
+
491
+ assertEq(state.phase, 'completing-milestone', 'completing-ms: phase is completing-milestone');
492
+ assertTrue(state.activeMilestone !== null, 'completing-ms: activeMilestone is not null');
493
+ assertEq(state.activeMilestone?.id, 'M001', 'completing-ms: activeMilestone id is M001');
494
+ assertEq(state.activeSlice, null, 'completing-ms: activeSlice is null');
495
+ assertEq(state.activeTask, null, 'completing-ms: activeTask is null');
496
+ assertEq(state.registry.length, 1, 'completing-ms: registry has 1 entry');
497
+ assertEq(state.registry[0]?.status, 'active', 'completing-ms: registry[0] status is active (not complete)');
498
+ assertEq(state.progress?.slices?.done, 2, 'completing-ms: slices done = 2');
499
+ assertEq(state.progress?.slices?.total, 2, 'completing-ms: slices total = 2');
500
+ assertTrue(
501
+ state.nextAction.toLowerCase().includes('summary') || state.nextAction.toLowerCase().includes('complete'),
502
+ 'completing-ms: nextAction mentions summary or complete'
503
+ );
504
+ } finally {
505
+ cleanup(base);
506
+ }
507
+ }
508
+
509
+ // ─── Test 12: all slices [x], summary exists → complete ───────────────
510
+ console.log('\n=== all slices [x], summary exists → complete ===');
511
+ {
512
+ const base = createFixtureBase();
513
+ try {
514
+ writeRoadmap(base, 'M001', `# M001: Test Milestone
515
+
516
+ **Vision:** Test that summary presence means complete.
517
+
518
+ ## Slices
519
+
520
+ - [x] **S01: Done** \`risk:low\` \`depends:[]\`
521
+ > After this: Done.
522
+ `);
523
+
524
+ writeMilestoneSummary(base, 'M001', `# M001 Summary\n\nMilestone is complete.`);
525
+
526
+ const state = await deriveState(base);
527
+
528
+ assertEq(state.phase, 'complete', 'summary-exists: phase is complete');
529
+ assertEq(state.registry.length, 1, 'summary-exists: registry has 1 entry');
530
+ assertEq(state.registry[0]?.status, 'complete', 'summary-exists: registry[0] status is complete');
531
+ assertEq(state.activeSlice, null, 'summary-exists: activeSlice is null');
532
+ assertEq(state.activeTask, null, 'summary-exists: activeTask is null');
533
+ } finally {
534
+ cleanup(base);
535
+ }
536
+ }
537
+
538
+ // ─── Test 13: multi-milestone completing-milestone ─────────────────────
539
+ console.log('\n=== multi-milestone completing-milestone ===');
540
+ {
541
+ const base = createFixtureBase();
542
+ try {
543
+ // M001: all slices done + summary exists → complete
544
+ writeRoadmap(base, 'M001', `# M001: First Milestone
545
+
546
+ **Vision:** Already complete with summary.
547
+
548
+ ## Slices
549
+
550
+ - [x] **S01: Done** \`risk:low\` \`depends:[]\`
551
+ > After this: Done.
552
+ `);
553
+ writeMilestoneSummary(base, 'M001', `# M001 Summary\n\nFirst milestone complete.`);
554
+
555
+ // M002: all slices done, no summary → completing-milestone
556
+ writeRoadmap(base, 'M002', `# M002: Second Milestone
557
+
558
+ **Vision:** All slices done but no summary.
559
+
560
+ ## Slices
561
+
562
+ - [x] **S01: Done** \`risk:low\` \`depends:[]\`
563
+ > After this: Done.
564
+
565
+ - [x] **S02: Also Done** \`risk:low\` \`depends:[S01]\`
566
+ > After this: Done.
567
+ `);
568
+
569
+ // M003: has incomplete slices → pending (M002 is active)
570
+ writeRoadmap(base, 'M003', `# M003: Third Milestone
571
+
572
+ **Vision:** Not yet started.
573
+
574
+ ## Slices
575
+
576
+ - [ ] **S01: Not Started** \`risk:low\` \`depends:[]\`
577
+ > After this: Done.
578
+ `);
579
+
580
+ const state = await deriveState(base);
581
+
582
+ assertEq(state.phase, 'completing-milestone', 'multi-completing: phase is completing-milestone');
583
+ assertEq(state.activeMilestone?.id, 'M002', 'multi-completing: activeMilestone is M002');
584
+ assertEq(state.activeSlice, null, 'multi-completing: activeSlice is null');
585
+ assertEq(state.activeTask, null, 'multi-completing: activeTask is null');
586
+ assertEq(state.registry.length, 3, 'multi-completing: registry has 3 entries');
587
+ assertEq(state.registry[0]?.id, 'M001', 'multi-completing: registry[0] is M001');
588
+ assertEq(state.registry[0]?.status, 'complete', 'multi-completing: M001 is complete');
589
+ assertEq(state.registry[1]?.id, 'M002', 'multi-completing: registry[1] is M002');
590
+ assertEq(state.registry[1]?.status, 'active', 'multi-completing: M002 is active (completing-milestone)');
591
+ assertEq(state.registry[2]?.id, 'M003', 'multi-completing: registry[2] is M003');
592
+ assertEq(state.registry[2]?.status, 'pending', 'multi-completing: M003 is pending');
593
+ assertEq(state.progress?.milestones?.done, 1, 'multi-completing: milestones done = 1');
594
+ assertEq(state.progress?.milestones?.total, 3, 'multi-completing: milestones total = 3');
595
+ assertEq(state.progress?.slices?.done, 2, 'multi-completing: slices done = 2');
596
+ assertEq(state.progress?.slices?.total, 2, 'multi-completing: slices total = 2');
597
+ } finally {
598
+ cleanup(base);
599
+ }
600
+ }
601
+
602
+ // ═══ Milestone with summary but no roadmap → complete ═══════════════════
603
+ {
604
+ console.log('\n=== milestone with summary and no roadmap → complete ===');
605
+ const base = createFixtureBase();
606
+ try {
607
+ // M001, M002: completed milestones with summaries but no roadmaps
608
+ const m1dir = join(base, '.gsd', 'milestones', 'M001');
609
+ mkdirSync(m1dir, { recursive: true });
610
+ writeFileSync(join(m1dir, 'M001-SUMMARY.md'), '---\nid: M001\n---\n# Bootstrap\nDone.');
611
+
612
+ const m2dir = join(base, '.gsd', 'milestones', 'M002');
613
+ mkdirSync(m2dir, { recursive: true });
614
+ writeFileSync(join(m2dir, 'M002-SUMMARY.md'), '---\nid: M002\n---\n# Core Features\nDone.');
615
+
616
+ // M003: active milestone with a roadmap
617
+ writeRoadmap(base, 'M003', '# M003: Polish\n## Slices\n- [ ] **S01: Cleanup**');
618
+
619
+ const state = await deriveState(base);
620
+
621
+ assertEq(state.phase, 'planning', 'summary-no-roadmap: phase is planning (active is M003)');
622
+ assertEq(state.activeMilestone?.id, 'M003', 'summary-no-roadmap: active milestone is M003');
623
+ assertEq(state.activeMilestone?.title, 'Polish', 'summary-no-roadmap: active title is Polish');
624
+ assertEq(state.registry.length, 3, 'summary-no-roadmap: registry has 3 entries');
625
+ assertEq(state.registry[0]?.status, 'complete', 'summary-no-roadmap: M001 is complete');
626
+ assertEq(state.registry[0]?.title, 'Bootstrap', 'summary-no-roadmap: M001 title from summary');
627
+ assertEq(state.registry[1]?.status, 'complete', 'summary-no-roadmap: M002 is complete');
628
+ assertEq(state.registry[1]?.title, 'Core Features', 'summary-no-roadmap: M002 title from summary');
629
+ assertEq(state.registry[2]?.status, 'active', 'summary-no-roadmap: M003 is active');
630
+ assertEq(state.progress?.milestones?.done, 2, 'summary-no-roadmap: milestones done = 2');
631
+ assertEq(state.progress?.milestones?.total, 3, 'summary-no-roadmap: milestones total = 3');
632
+ } finally {
633
+ cleanup(base);
634
+ }
635
+ }
636
+
637
+ // ═══ All milestones have summary but no roadmap → complete ═════════════
638
+ {
639
+ console.log('\n=== all milestones summary-only → complete ===');
640
+ const base = createFixtureBase();
641
+ try {
642
+ const m1dir = join(base, '.gsd', 'milestones', 'M001');
643
+ mkdirSync(m1dir, { recursive: true });
644
+ writeFileSync(join(m1dir, 'M001-SUMMARY.md'), '---\ntitle: Done\n---\nAll done.');
645
+
646
+ const state = await deriveState(base);
647
+ assertEq(state.phase, 'complete', 'all-summary-only: phase is complete');
648
+ assertEq(state.registry[0]?.status, 'complete', 'all-summary-only: M001 is complete');
649
+ } finally {
650
+ cleanup(base);
651
+ }
652
+ }
653
+
654
+ report();
655
+ }
656
+
657
+ main().catch((error) => {
658
+ console.error(error);
659
+ process.exit(1);
660
+ });
@@ -0,0 +1,27 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { createTestContext } from './test-helpers.ts';
4
+
5
+ const { assertTrue, report } = createTestContext();
6
+ const promptPath = join(process.cwd(), 'src/resources/extensions/gsd/prompts/discuss.md');
7
+ const discussPrompt = readFileSync(promptPath, 'utf-8');
8
+
9
+ console.log('\n=== discuss prompt: resilient vision framing ===');
10
+ {
11
+ const hardenedPattern = /Say exactly:\s*"What's the vision\?"/;
12
+ assertTrue(!hardenedPattern.test(discussPrompt), 'prompt no longer uses exact-verbosity lock');
13
+ assertTrue(
14
+ discussPrompt.includes('Ask: "What\'s the vision?" once'),
15
+ 'prompt asks for vision exactly once',
16
+ );
17
+ assertTrue(
18
+ discussPrompt.includes('Special handling'),
19
+ 'prompt documents special handling for non-vision user messages',
20
+ );
21
+ assertTrue(
22
+ discussPrompt.includes('instead of repeating "What\'s the vision?"'),
23
+ 'prompt forbids repeating the vision question',
24
+ );
25
+ }
26
+
27
+ report();