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,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();