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,127 @@
1
+ // Tests for saveActivityLog performance behavior:
2
+ // - cache next sequence per activity directory instead of rescanning every save
3
+ // - skip rewriting identical snapshots for the same unit
4
+ // - recover safely if another writer creates the cached next sequence
5
+
6
+ import { existsSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
7
+ import { tmpdir } from "node:os";
8
+ import { join } from "node:path";
9
+
10
+ import { saveActivityLog } from "../activity-log.ts";
11
+ import { createTestContext } from "./test-helpers.ts";
12
+
13
+ const { assertEq, assertTrue, report } = createTestContext();
14
+
15
+ let tmpDirs: string[] = [];
16
+
17
+ function createBaseDir(): string {
18
+ const dir = mkdtempSync(join(tmpdir(), "gsd-activity-save-test-"));
19
+ tmpDirs.push(dir);
20
+ return dir;
21
+ }
22
+
23
+ function activityDir(baseDir: string): string {
24
+ return join(baseDir, ".gsd", "activity");
25
+ }
26
+
27
+ function listActivityFiles(baseDir: string): string[] {
28
+ const dir = activityDir(baseDir);
29
+ return existsSync(dir) ? readdirSync(dir).sort() : [];
30
+ }
31
+
32
+ function createCtx(entries: unknown[]) {
33
+ return {
34
+ sessionManager: {
35
+ getEntries: () => entries,
36
+ },
37
+ };
38
+ }
39
+
40
+ function cleanup(): void {
41
+ for (const dir of tmpDirs) {
42
+ rmSync(dir, { recursive: true, force: true });
43
+ }
44
+ tmpDirs = [];
45
+ }
46
+
47
+ process.on("exit", cleanup);
48
+
49
+ async function main(): Promise<void> {
50
+ console.log("\n── (a) cache next sequence instead of rescanning every save");
51
+ {
52
+ const baseDir = createBaseDir();
53
+ saveActivityLog(createCtx([{ kind: "first", n: 1 }]) as any, baseDir, "execute-task", "M001/S01/T01");
54
+
55
+ writeFileSync(
56
+ join(activityDir(baseDir), "999-external-manual.jsonl"),
57
+ '{"external":true}\n',
58
+ "utf-8",
59
+ );
60
+
61
+ saveActivityLog(createCtx([{ kind: "second", n: 2 }]) as any, baseDir, "execute-task", "M001/S01/T02");
62
+
63
+ const files = listActivityFiles(baseDir);
64
+ assertTrue(files.includes("001-execute-task-M001-S01-T01.jsonl"), "(a) first save uses sequence 001");
65
+ assertTrue(files.includes("002-execute-task-M001-S01-T02.jsonl"), "(a) second save uses cached next sequence 002");
66
+ assertTrue(files.includes("999-external-manual.jsonl"), "(a) externally added file remains present");
67
+ assertTrue(!files.some(file => file.startsWith("1000-")), "(a) second save did not rescan and jump to sequence 1000");
68
+ }
69
+
70
+ console.log("\n── (b) skip rewriting identical snapshots for the same unit");
71
+ {
72
+ const baseDir = createBaseDir();
73
+ const ctx = createCtx([{ role: "assistant", content: "same snapshot" }]);
74
+
75
+ saveActivityLog(ctx as any, baseDir, "plan-slice", "M002/S01");
76
+ saveActivityLog(ctx as any, baseDir, "plan-slice", "M002/S01");
77
+
78
+ let files = listActivityFiles(baseDir);
79
+ assertEq(files.length, 1, "(b) identical repeated save writes only one activity file");
80
+ assertTrue(files[0] === "001-plan-slice-M002-S01.jsonl", "(b) the original sequence is preserved");
81
+
82
+ saveActivityLog(createCtx([{ role: "assistant", content: "changed snapshot" }]) as any, baseDir, "plan-slice", "M002/S01");
83
+ files = listActivityFiles(baseDir);
84
+ assertEq(files.length, 2, "(b) changed snapshot writes a new activity file");
85
+ assertTrue(files.includes("002-plan-slice-M002-S01.jsonl"), "(b) deduped save did not consume the next sequence");
86
+ }
87
+
88
+ console.log("\n── (c) recover if another writer creates the exact cached target file");
89
+ {
90
+ const baseDir = createBaseDir();
91
+ saveActivityLog(createCtx([{ turn: 1 }]) as any, baseDir, "execute-task", "M003/S02/T01");
92
+
93
+ writeFileSync(
94
+ join(activityDir(baseDir), "002-execute-task-M003-S02-T02.jsonl"),
95
+ '{"collision":true}\n',
96
+ "utf-8",
97
+ );
98
+
99
+ saveActivityLog(createCtx([{ turn: 2 }]) as any, baseDir, "execute-task", "M003/S02/T02");
100
+
101
+ const files = listActivityFiles(baseDir);
102
+ assertTrue(files.includes("002-execute-task-M003-S02-T02.jsonl"), "(c) exact collision file is preserved");
103
+ assertTrue(files.includes("003-execute-task-M003-S02-T02.jsonl"), "(c) logger rescans only on collision and advances to 003");
104
+ }
105
+
106
+ console.log("\n── (d) dedupe is tracked per unit, not just the last write in the directory");
107
+ {
108
+ const baseDir = createBaseDir();
109
+ const repeatedCtx = createCtx([{ role: "assistant", content: "same-for-unit-a" }]);
110
+
111
+ saveActivityLog(repeatedCtx as any, baseDir, "execute-task", "M004/S01/T01");
112
+ saveActivityLog(createCtx([{ role: "assistant", content: "other-unit" }]) as any, baseDir, "execute-task", "M004/S01/T02");
113
+ saveActivityLog(repeatedCtx as any, baseDir, "execute-task", "M004/S01/T01");
114
+
115
+ const files = listActivityFiles(baseDir);
116
+ assertEq(files.length, 2, "(d) interleaving another unit does not force a duplicate rewrite for unit A");
117
+ assertTrue(files.includes("001-execute-task-M004-S01-T01.jsonl"), "(d) original unit A snapshot is retained");
118
+ assertTrue(files.includes("002-execute-task-M004-S01-T02.jsonl"), "(d) unit B snapshot is retained");
119
+ }
120
+
121
+ report();
122
+ }
123
+
124
+ main().catch((error) => {
125
+ console.error(error);
126
+ process.exit(1);
127
+ });
@@ -0,0 +1,109 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ import { describeNextUnit } from "../auto.js";
5
+
6
+ let passed = 0;
7
+ let failed = 0;
8
+
9
+ function assert(condition: boolean, message: string): void {
10
+ if (condition) {
11
+ passed++;
12
+ } else {
13
+ failed++;
14
+ console.error(` FAIL: ${message}`);
15
+ }
16
+ }
17
+
18
+ // ─── Test describeNextUnit with 'needs-discussion' phase ──────────────────
19
+
20
+ const ndState = {
21
+ phase: "needs-discussion" as const,
22
+ activeMilestone: { id: "M007", title: "Future Milestone" },
23
+ activeSlice: undefined,
24
+ activeTask: undefined,
25
+ milestoneRegistry: [],
26
+ nextAction: "",
27
+ };
28
+
29
+ const ndResult = describeNextUnit(ndState as any);
30
+ assert(
31
+ ndResult.label !== "Continue",
32
+ `needs-discussion label should not be default "Continue", got: "${ndResult.label}"`,
33
+ );
34
+ assert(
35
+ ndResult.label.toLowerCase().includes("draft") || ndResult.label.toLowerCase().includes("discuss"),
36
+ `needs-discussion label should mention "draft" or "discuss", got: "${ndResult.label}"`,
37
+ );
38
+ assert(
39
+ ndResult.description.toLowerCase().includes("discussion") || ndResult.description.toLowerCase().includes("draft"),
40
+ `needs-discussion description should mention "discussion" or "draft", got: "${ndResult.description}"`,
41
+ );
42
+
43
+ // ─── Backward compatibility: pre-planning still works ──────────────────────
44
+
45
+ const ppState = {
46
+ phase: "pre-planning" as const,
47
+ activeMilestone: { id: "M001", title: "Test" },
48
+ activeSlice: undefined,
49
+ activeTask: undefined,
50
+ milestoneRegistry: [],
51
+ nextAction: "",
52
+ };
53
+
54
+ const ppResult = describeNextUnit(ppState as any);
55
+ assert(
56
+ ppResult.label === "Research & plan milestone",
57
+ `pre-planning label should be "Research & plan milestone", got: "${ppResult.label}"`,
58
+ );
59
+
60
+ // ─── Backward compatibility: executing still works ──────────────────────────
61
+
62
+ const exState = {
63
+ phase: "executing" as const,
64
+ activeMilestone: { id: "M001", title: "Test" },
65
+ activeSlice: { id: "S01", title: "Test Slice" },
66
+ activeTask: { id: "T01", title: "Test Task" },
67
+ milestoneRegistry: [],
68
+ nextAction: "",
69
+ };
70
+
71
+ const exResult = describeNextUnit(exState as any);
72
+ assert(
73
+ exResult.label.includes("T01"),
74
+ `executing label should include task ID, got: "${exResult.label}"`,
75
+ );
76
+
77
+ // ─── Static verification: needs-discussion in dispatchNextUnit ──────────────
78
+
79
+ const autoSource = readFileSync(
80
+ join(import.meta.dirname, "..", "auto.ts"),
81
+ "utf-8",
82
+ );
83
+
84
+ // Check describeNextUnit has the case
85
+ const hasDescribeCase = autoSource.includes('case "needs-discussion"');
86
+ assert(hasDescribeCase, "auto.ts describeNextUnit should have 'needs-discussion' case");
87
+
88
+ // Check dispatchNextUnit has the branch
89
+ const hasDispatchBranch = autoSource.includes('state.phase === "needs-discussion"');
90
+ assert(hasDispatchBranch, "auto.ts dispatchNextUnit should have 'needs-discussion' branch");
91
+
92
+ // Check the dispatch branch calls stopAuto
93
+ const dispatchIdx = autoSource.indexOf('state.phase === "needs-discussion"');
94
+ const nextChunk = autoSource.slice(dispatchIdx, dispatchIdx + 600);
95
+ assert(
96
+ nextChunk.includes("stopAuto"),
97
+ "needs-discussion dispatch branch should call stopAuto",
98
+ );
99
+
100
+ // Check notification includes /gsd guidance
101
+ assert(
102
+ nextChunk.includes("/gsd"),
103
+ "needs-discussion notification should tell user to run /gsd",
104
+ );
105
+
106
+ // ─── Results ──────────────────────────────────────────────────────────────
107
+
108
+ console.log(`\nauto-draft-pause: ${passed} passed, ${failed} failed`);
109
+ if (failed > 0) process.exit(1);
@@ -0,0 +1,45 @@
1
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { tmpdir } from "node:os";
4
+
5
+ import { runGSDDoctor, selectDoctorScope, filterDoctorIssues } from "../doctor.js";
6
+ import { createTestContext } from './test-helpers.ts';
7
+
8
+ const { assertTrue, report } = createTestContext();
9
+ const tmpBase = mkdtempSync(join(tmpdir(), "gsd-auto-preflight-test-"));
10
+ const gsd = join(tmpBase, ".gsd");
11
+
12
+ mkdirSync(join(gsd, "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
13
+ mkdirSync(join(gsd, "milestones", "M009", "slices", "S01", "tasks"), { recursive: true });
14
+
15
+ writeFileSync(join(gsd, "milestones", "M001", "M001-ROADMAP.md"), `# M001: Historical\n\n## Slices\n- [x] **S01: Old Slice** \`risk:low\` \`depends:[]\`\n > After this: old done\n`);
16
+ writeFileSync(join(gsd, "milestones", "M001", "slices", "S01", "S01-PLAN.md"), `# S01: Old Slice\n\n**Goal:** Old\n**Demo:** Old\n\n## Must-Haves\n- done\n\n## Tasks\n- [x] **T01: Old Task** \`est:5m\`\n done\n`);
17
+ writeFileSync(join(gsd, "milestones", "M001", "slices", "S01", "tasks", "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\nprovides: []\nrequires: []\naffects: []\nkey_files: []\nkey_decisions: []\npatterns_established: []\nobservability_surfaces: []\ndrill_down_paths: []\nduration: 5m\nverification_result: passed\ncompleted_at: 2026-03-09T00:00:00Z\n---\n\n# T01: Old Task\n\n**Done**\n\n## What Happened\nDone.\n\n## Diagnostics\n- log\n`);
18
+ writeFileSync(join(gsd, "milestones", "M001", "slices", "S01", "S01-SUMMARY.md"), `---\nid: S01\nparent: M001\nmilestone: M001\nprovides: []\nrequires: []\naffects: []\nkey_files: []\nkey_decisions: []\npatterns_established: []\nobservability_surfaces: []\ndrill_down_paths: []\nduration: 5m\nverification_result: passed\ncompleted_at: 2026-03-09T00:00:00Z\n---\n\n# S01: Old Slice\n\n**Done**\n\n## What Happened\nDone.\n\n## Verification\nDone.\n\n## Deviations\nNone\n\n## Known Limitations\nNone\n\n## Follow-ups\nNone\n\n## Files Created/Modified\n- \`x\` — x\n\n## Forward Intelligence\n\n### What the next slice should know\n- x\n\n### What's fragile\n- x\n\n### Authoritative diagnostics\n- x\n\n### What assumptions changed\n- x\n`);
19
+
20
+ writeFileSync(join(gsd, "milestones", "M001", "M001-SUMMARY.md"), `---\nid: M001\nstatus: complete\ncompleted_at: 2026-03-09T00:00:00Z\n---\n\n# M001: Historical\n\nComplete.\n`);
21
+
22
+ writeFileSync(join(gsd, "milestones", "M009", "M009-ROADMAP.md"), `# M009: Active\n\n## Slices\n- [ ] **S01: Active Slice** \`risk:low\` \`depends:[]\`\n > After this: active works\n`);
23
+ writeFileSync(join(gsd, "milestones", "M009", "slices", "S01", "S01-PLAN.md"), `# S01: Active Slice\n\n**Goal:** Active\n**Demo:** Active\n\n## Must-Haves\n- done\n\n## Tasks\n- [ ] **T01: Active Task** \`est:5m\`\n todo\n`);
24
+
25
+ async function main(): Promise<void> {
26
+ const scope = await selectDoctorScope(tmpBase);
27
+ assertTrue(scope === "M009/S01", "active scope selected instead of historical milestone");
28
+
29
+ const scopedReport = await runGSDDoctor(tmpBase, { fix: false, scope });
30
+ const scopedBlocking = filterDoctorIssues(scopedReport.issues, { scope, includeWarnings: false });
31
+ assertTrue(scopedBlocking.length === 0, "no blocking issues in active scope");
32
+
33
+ const historicalReport = await runGSDDoctor(tmpBase, { fix: false });
34
+ const historicalWarnings = historicalReport.issues.filter(issue => issue.unitId.startsWith("M001/S01") && issue.severity === "warning");
35
+ assertTrue(historicalWarnings.length > 0, "full repo still contains historical warning drift");
36
+
37
+ rmSync(tmpBase, { recursive: true, force: true });
38
+
39
+ report();
40
+ }
41
+
42
+ main().catch((error) => {
43
+ console.error(error);
44
+ process.exit(1);
45
+ });
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Integration tests for the secrets collection gate in startAuto().
3
+ *
4
+ * Exercises getManifestStatus() → collectSecretsFromManifest() composition
5
+ * end-to-end using real filesystem state. Proves the three gate paths:
6
+ * 1. No manifest exists — gate skips silently
7
+ * 2. Pending keys exist — gate triggers collection
8
+ * 3. No pending keys — gate skips silently
9
+ *
10
+ * Uses temp directories with real .gsd/milestones/M001/ structure, mirroring
11
+ * the pattern from manifest-status.test.ts.
12
+ */
13
+
14
+ import test from 'node:test';
15
+ import assert from 'node:assert/strict';
16
+ import { mkdirSync, writeFileSync, readFileSync, rmSync } from 'node:fs';
17
+ import { join } from 'node:path';
18
+ import { tmpdir } from 'node:os';
19
+ import { getManifestStatus } from '../files.ts';
20
+ import { collectSecretsFromManifest } from '../../get-secrets-from-user.ts';
21
+
22
+ function makeTempDir(prefix: string): string {
23
+ const dir = join(tmpdir(), `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
24
+ mkdirSync(dir, { recursive: true });
25
+ return dir;
26
+ }
27
+
28
+ /** Create the .gsd/milestones/M001/ directory structure and write a secrets manifest. */
29
+ function writeManifest(base: string, content: string): void {
30
+ const mDir = join(base, '.gsd', 'milestones', 'M001');
31
+ mkdirSync(mDir, { recursive: true });
32
+ writeFileSync(join(mDir, 'M001-SECRETS.md'), content);
33
+ }
34
+
35
+ /** Stub ctx with hasUI: false — collectOneSecret returns null (skip), showSecretsSummary is a no-op. */
36
+ function makeNoUICtx(cwd: string) {
37
+ return {
38
+ ui: {},
39
+ hasUI: false,
40
+ cwd,
41
+ };
42
+ }
43
+
44
+ // ─── Scenario 1: No manifest exists ──────────────────────────────────────────
45
+
46
+ test('secrets gate: no manifest exists — getManifestStatus returns null', async () => {
47
+ const tmp = makeTempDir('gate-no-manifest');
48
+ try {
49
+ // No .gsd directory at all
50
+ const result = await getManifestStatus(tmp, 'M001');
51
+ assert.strictEqual(result, null, 'should return null when no manifest file exists');
52
+ } finally {
53
+ rmSync(tmp, { recursive: true, force: true });
54
+ }
55
+ });
56
+
57
+ // ─── Scenario 2: Pending keys exist ─────────────────────────────────────────
58
+
59
+ test('secrets gate: pending keys exist — gate triggers collection, manifest updated on disk', async () => {
60
+ const tmp = makeTempDir('gate-pending');
61
+ const savedA = process.env.GSD_GATE_TEST_EXISTING;
62
+ try {
63
+ // Simulate one key already in env
64
+ process.env.GSD_GATE_TEST_EXISTING = 'already-here';
65
+
66
+ // Ensure pending keys are NOT in env
67
+ delete process.env.GSD_GATE_TEST_PEND_A;
68
+ delete process.env.GSD_GATE_TEST_PEND_B;
69
+
70
+ writeManifest(tmp, `# Secrets Manifest
71
+
72
+ **Milestone:** M001
73
+ **Generated:** 2025-06-20T10:00:00Z
74
+
75
+ ### GSD_GATE_TEST_PEND_A
76
+
77
+ **Service:** ServiceA
78
+ **Status:** pending
79
+ **Destination:** dotenv
80
+
81
+ 1. Get key A from dashboard
82
+
83
+ ### GSD_GATE_TEST_PEND_B
84
+
85
+ **Service:** ServiceB
86
+ **Status:** pending
87
+ **Destination:** dotenv
88
+
89
+ 1. Get key B from dashboard
90
+
91
+ ### GSD_GATE_TEST_EXISTING
92
+
93
+ **Service:** ServiceC
94
+ **Status:** pending
95
+ **Destination:** dotenv
96
+
97
+ 1. Already in env
98
+ `);
99
+
100
+ // (a) Verify getManifestStatus shows pending keys
101
+ const status = await getManifestStatus(tmp, 'M001');
102
+ assert.notStrictEqual(status, null, 'manifest should exist');
103
+ assert.ok(status!.pending.length > 0, 'should have pending keys');
104
+ assert.deepStrictEqual(status!.pending, ['GSD_GATE_TEST_PEND_A', 'GSD_GATE_TEST_PEND_B']);
105
+ assert.deepStrictEqual(status!.existing, ['GSD_GATE_TEST_EXISTING']);
106
+
107
+ // (b) Call collectSecretsFromManifest with no-UI context
108
+ // With hasUI: false, collectOneSecret returns null → pending keys become "skipped"
109
+ const result = await collectSecretsFromManifest(tmp, 'M001', makeNoUICtx(tmp));
110
+
111
+ // (c) Verify return shape
112
+ assert.deepStrictEqual(result.applied, [], 'no keys applied (no UI to enter values)');
113
+ assert.ok(result.skipped.includes('GSD_GATE_TEST_PEND_A'), 'PEND_A should be skipped');
114
+ assert.ok(result.skipped.includes('GSD_GATE_TEST_PEND_B'), 'PEND_B should be skipped');
115
+ assert.deepStrictEqual(result.existingSkipped, ['GSD_GATE_TEST_EXISTING']);
116
+
117
+ // (d) Verify manifest on disk was updated — pending entries that went through
118
+ // collection are now "skipped". The existing-in-env entry retains its manifest
119
+ // status ("pending") because collectSecretsFromManifest only updates entries
120
+ // that flow through collectOneSecret. At runtime, getManifestStatus overrides
121
+ // env-present entries to "existing" regardless of manifest status.
122
+ const manifestPath = join(tmp, '.gsd', 'milestones', 'M001', 'M001-SECRETS.md');
123
+ const updatedContent = readFileSync(manifestPath, 'utf8');
124
+ assert.ok(
125
+ updatedContent.includes('**Status:** skipped'),
126
+ 'formerly-pending entries should now have status "skipped" in the manifest file',
127
+ );
128
+ // Count: PEND_A → skipped, PEND_B → skipped, EXISTING stays pending on disk
129
+ const skippedMatches = updatedContent.match(/\*\*Status:\*\* skipped/g);
130
+ assert.strictEqual(skippedMatches?.length, 2, 'two entries should have status "skipped"');
131
+ const pendingMatches = updatedContent.match(/\*\*Status:\*\* pending/g);
132
+ assert.strictEqual(pendingMatches?.length, 1, 'one entry (existing-in-env) retains pending on disk');
133
+
134
+ // (e) Verify getManifestStatus now shows no pending
135
+ const statusAfter = await getManifestStatus(tmp, 'M001');
136
+ assert.notStrictEqual(statusAfter, null);
137
+ assert.deepStrictEqual(statusAfter!.pending, [], 'no pending keys after collection');
138
+ } finally {
139
+ delete process.env.GSD_GATE_TEST_EXISTING;
140
+ if (savedA !== undefined) process.env.GSD_GATE_TEST_EXISTING = savedA;
141
+ delete process.env.GSD_GATE_TEST_PEND_A;
142
+ delete process.env.GSD_GATE_TEST_PEND_B;
143
+ rmSync(tmp, { recursive: true, force: true });
144
+ }
145
+ });
146
+
147
+ // ─── Scenario 3: No pending keys — all collected or in env ──────────────────
148
+
149
+ test('secrets gate: no pending keys — getManifestStatus shows pending.length === 0', async () => {
150
+ const tmp = makeTempDir('gate-no-pending');
151
+ const savedKey = process.env.GSD_GATE_TEST_ENVKEY;
152
+ try {
153
+ process.env.GSD_GATE_TEST_ENVKEY = 'some-value';
154
+
155
+ writeManifest(tmp, `# Secrets Manifest
156
+
157
+ **Milestone:** M001
158
+ **Generated:** 2025-06-20T10:00:00Z
159
+
160
+ ### ALREADY_COLLECTED
161
+
162
+ **Service:** ServiceX
163
+ **Status:** collected
164
+ **Destination:** dotenv
165
+
166
+ 1. Was collected previously
167
+
168
+ ### ALREADY_SKIPPED
169
+
170
+ **Service:** ServiceY
171
+ **Status:** skipped
172
+ **Destination:** dotenv
173
+
174
+ 1. Not needed
175
+
176
+ ### GSD_GATE_TEST_ENVKEY
177
+
178
+ **Service:** ServiceZ
179
+ **Status:** pending
180
+ **Destination:** dotenv
181
+
182
+ 1. In env already
183
+ `);
184
+
185
+ const result = await getManifestStatus(tmp, 'M001');
186
+ assert.notStrictEqual(result, null, 'manifest should exist');
187
+ assert.deepStrictEqual(result!.pending, [], 'no pending keys — gate would skip');
188
+ assert.deepStrictEqual(result!.collected, ['ALREADY_COLLECTED']);
189
+ assert.deepStrictEqual(result!.skipped, ['ALREADY_SKIPPED']);
190
+ assert.deepStrictEqual(result!.existing, ['GSD_GATE_TEST_ENVKEY']);
191
+ } finally {
192
+ delete process.env.GSD_GATE_TEST_ENVKEY;
193
+ if (savedKey !== undefined) process.env.GSD_GATE_TEST_ENVKEY = savedKey;
194
+ rmSync(tmp, { recursive: true, force: true });
195
+ }
196
+ });
@@ -0,0 +1,53 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { mkdtempSync, readFileSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { writeUnitRuntimeRecord, readUnitRuntimeRecord } from '../unit-runtime.ts';
7
+ import { resolveAutoSupervisorConfig } from '../preferences.ts';
8
+
9
+ test('resolveAutoSupervisorConfig provides safe timeout defaults', () => {
10
+ const supervisor = resolveAutoSupervisorConfig();
11
+ assert.equal(supervisor.soft_timeout_minutes, 20);
12
+ assert.equal(supervisor.idle_timeout_minutes, 10);
13
+ assert.equal(supervisor.hard_timeout_minutes, 30);
14
+ });
15
+
16
+ test('writeUnitRuntimeRecord persists progress and recovery metadata defaults', () => {
17
+ const base = mkdtempSync(join(tmpdir(), 'gsd-auto-supervisor-'));
18
+ const startedAt = 1234567890;
19
+
20
+ writeUnitRuntimeRecord(base, 'plan-milestone', 'M010', startedAt, {
21
+ phase: 'dispatched',
22
+ lastProgressAt: startedAt,
23
+ progressCount: 1,
24
+ lastProgressKind: 'dispatch',
25
+ });
26
+
27
+ const runtime = readUnitRuntimeRecord(base, 'plan-milestone', 'M010');
28
+ assert.ok(runtime);
29
+ assert.equal(runtime.phase, 'dispatched');
30
+ assert.equal(runtime.lastProgressAt, startedAt);
31
+ assert.equal(runtime.progressCount, 1);
32
+ assert.equal(runtime.lastProgressKind, 'dispatch');
33
+ assert.equal(runtime.recoveryAttempts, 0);
34
+ });
35
+
36
+ test('writeUnitRuntimeRecord keeps explicit recovery attempt fields', () => {
37
+ const base = mkdtempSync(join(tmpdir(), 'gsd-auto-supervisor-'));
38
+ const startedAt = 2234567890;
39
+
40
+ writeUnitRuntimeRecord(base, 'research-milestone', 'M011', startedAt, {
41
+ phase: 'timeout',
42
+ recoveryAttempts: 2,
43
+ lastRecoveryReason: 'idle',
44
+ lastProgressAt: startedAt + 50,
45
+ progressCount: 3,
46
+ lastProgressKind: 'recovery-retry',
47
+ });
48
+
49
+ const runtime = JSON.parse(readFileSync(join(base, '.gsd/runtime/units/research-milestone-M011.json'), 'utf8'));
50
+ assert.equal(runtime.recoveryAttempts, 2);
51
+ assert.equal(runtime.lastRecoveryReason, 'idle');
52
+ assert.equal(runtime.lastProgressKind, 'recovery-retry');
53
+ });