gsd-pi 2.34.0 → 2.35.0-dev.30eec3f

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 (500) hide show
  1. package/dist/cli.js +7 -2
  2. package/dist/resource-loader.d.ts +1 -1
  3. package/dist/resource-loader.js +13 -1
  4. package/dist/resources/extensions/async-jobs/await-tool.js +0 -2
  5. package/dist/resources/extensions/async-jobs/job-manager.js +0 -6
  6. package/dist/resources/extensions/bg-shell/output-formatter.js +1 -19
  7. package/dist/resources/extensions/bg-shell/process-manager.js +0 -4
  8. package/dist/resources/extensions/bg-shell/types.js +0 -2
  9. package/dist/resources/extensions/context7/index.js +5 -0
  10. package/dist/resources/extensions/get-secrets-from-user.js +2 -30
  11. package/dist/resources/extensions/google-search/index.js +5 -0
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +43 -1
  13. package/dist/resources/extensions/gsd/auto-loop.js +10 -1
  14. package/dist/resources/extensions/gsd/auto-recovery.js +35 -0
  15. package/dist/resources/extensions/gsd/auto-start.js +35 -2
  16. package/dist/resources/extensions/gsd/auto.js +59 -4
  17. package/dist/resources/extensions/gsd/changelog.js +162 -0
  18. package/dist/resources/extensions/gsd/commands-bootstrap.js +1 -0
  19. package/dist/resources/extensions/gsd/commands-handlers.js +2 -2
  20. package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
  21. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +5 -1
  22. package/dist/resources/extensions/gsd/commands.js +8 -1
  23. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  24. package/dist/resources/extensions/gsd/doctor-checks.js +113 -5
  25. package/dist/resources/extensions/gsd/doctor-environment.js +26 -17
  26. package/dist/resources/extensions/gsd/doctor-proactive.js +22 -0
  27. package/dist/resources/extensions/gsd/doctor.js +36 -0
  28. package/dist/resources/extensions/gsd/files.js +11 -2
  29. package/dist/resources/extensions/gsd/gitignore.js +54 -7
  30. package/dist/resources/extensions/gsd/guided-flow.js +5 -3
  31. package/dist/resources/extensions/gsd/health-widget-core.js +96 -0
  32. package/dist/resources/extensions/gsd/health-widget.js +97 -46
  33. package/dist/resources/extensions/gsd/index.js +10 -1
  34. package/dist/resources/extensions/gsd/migrate-external.js +55 -2
  35. package/dist/resources/extensions/gsd/paths.js +74 -7
  36. package/dist/resources/extensions/gsd/post-unit-hooks.js +4 -1
  37. package/dist/resources/extensions/gsd/preferences-validation.js +54 -1
  38. package/dist/resources/extensions/gsd/preferences.js +2 -0
  39. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  40. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  41. package/dist/resources/extensions/gsd/roadmap-mutations.js +55 -0
  42. package/dist/resources/extensions/gsd/session-lock.js +26 -2
  43. package/dist/resources/extensions/gsd/templates/plan.md +8 -0
  44. package/dist/resources/extensions/gsd/worktree-resolver.js +12 -0
  45. package/dist/resources/extensions/mcp-client/index.js +2 -1
  46. package/dist/resources/extensions/remote-questions/remote-command.js +2 -22
  47. package/dist/resources/extensions/shared/mod.js +1 -1
  48. package/dist/resources/extensions/shared/sanitize.js +30 -0
  49. package/dist/resources/extensions/subagent/index.js +6 -14
  50. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  51. package/package.json +2 -1
  52. package/packages/native/dist/native.d.ts +0 -2
  53. package/packages/native/dist/native.js +0 -2
  54. package/packages/native/src/native.ts +0 -3
  55. package/packages/pi-agent-core/dist/agent-loop.d.ts +14 -0
  56. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  57. package/packages/pi-agent-core/dist/agent-loop.js +24 -27
  58. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  59. package/packages/pi-agent-core/dist/agent.d.ts +1 -0
  60. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  61. package/packages/pi-agent-core/dist/agent.js +11 -22
  62. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  63. package/packages/pi-agent-core/dist/proxy.d.ts +1 -25
  64. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  65. package/packages/pi-agent-core/dist/proxy.js +3 -9
  66. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  67. package/packages/pi-agent-core/src/agent-loop.ts +30 -27
  68. package/packages/pi-agent-core/src/agent.ts +12 -23
  69. package/packages/pi-agent-core/src/proxy.ts +3 -9
  70. package/packages/pi-ai/dist/api-registry.d.ts +0 -2
  71. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  72. package/packages/pi-ai/dist/api-registry.js +0 -10
  73. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  74. package/packages/pi-ai/dist/providers/anthropic.d.ts +0 -8
  75. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  76. package/packages/pi-ai/dist/providers/anthropic.js +1 -1
  77. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  78. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  79. package/packages/pi-ai/dist/providers/azure-openai-responses.js +5 -41
  80. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  81. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts +0 -1
  82. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts.map +1 -1
  83. package/packages/pi-ai/dist/providers/github-copilot-headers.js +1 -1
  84. package/packages/pi-ai/dist/providers/github-copilot-headers.js.map +1 -1
  85. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts +1 -43
  86. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  87. package/packages/pi-ai/dist/providers/google-gemini-cli.js +2 -2
  88. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  89. package/packages/pi-ai/dist/providers/google-shared.d.ts +0 -4
  90. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  91. package/packages/pi-ai/dist/providers/google-shared.js +1 -1
  92. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  93. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  94. package/packages/pi-ai/dist/providers/openai-completions.js +10 -73
  95. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  96. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  97. package/packages/pi-ai/dist/providers/openai-responses.js +9 -80
  98. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  99. package/packages/pi-ai/dist/providers/openai-shared.d.ts +65 -0
  100. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -0
  101. package/packages/pi-ai/dist/providers/openai-shared.js +146 -0
  102. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -0
  103. package/packages/pi-ai/dist/providers/register-builtins.d.ts +0 -1
  104. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  105. package/packages/pi-ai/dist/providers/register-builtins.js +1 -1
  106. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  107. package/packages/pi-ai/dist/utils/event-stream.d.ts +0 -2
  108. package/packages/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  109. package/packages/pi-ai/dist/utils/event-stream.js +0 -4
  110. package/packages/pi-ai/dist/utils/event-stream.js.map +1 -1
  111. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  112. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +7 -135
  113. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  114. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  115. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +7 -135
  116. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  117. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts +46 -0
  118. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts.map +1 -0
  119. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js +160 -0
  120. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js.map +1 -0
  121. package/packages/pi-ai/dist/utils/overflow.d.ts +0 -4
  122. package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  123. package/packages/pi-ai/dist/utils/overflow.js +0 -6
  124. package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
  125. package/packages/pi-ai/dist/utils/validation.d.ts +0 -8
  126. package/packages/pi-ai/dist/utils/validation.d.ts.map +1 -1
  127. package/packages/pi-ai/dist/utils/validation.js +0 -14
  128. package/packages/pi-ai/dist/utils/validation.js.map +1 -1
  129. package/packages/pi-ai/src/api-registry.ts +0 -12
  130. package/packages/pi-ai/src/providers/anthropic.ts +1 -1
  131. package/packages/pi-ai/src/providers/azure-openai-responses.ts +11 -45
  132. package/packages/pi-ai/src/providers/github-copilot-headers.ts +1 -1
  133. package/packages/pi-ai/src/providers/google-gemini-cli.ts +2 -2
  134. package/packages/pi-ai/src/providers/google-shared.ts +1 -1
  135. package/packages/pi-ai/src/providers/openai-completions.ts +16 -86
  136. package/packages/pi-ai/src/providers/openai-responses.ts +16 -96
  137. package/packages/pi-ai/src/providers/openai-shared.ts +193 -0
  138. package/packages/pi-ai/src/providers/register-builtins.ts +1 -1
  139. package/packages/pi-ai/src/utils/event-stream.ts +0 -5
  140. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +14 -162
  141. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +13 -161
  142. package/packages/pi-ai/src/utils/oauth/google-oauth-utils.ts +201 -0
  143. package/packages/pi-ai/src/utils/overflow.ts +1 -8
  144. package/packages/pi-ai/src/utils/validation.ts +0 -15
  145. package/packages/pi-coding-agent/dist/config.d.ts +0 -9
  146. package/packages/pi-coding-agent/dist/config.d.ts.map +1 -1
  147. package/packages/pi-coding-agent/dist/config.js +4 -8
  148. package/packages/pi-coding-agent/dist/config.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +16 -63
  150. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/agent-session.js +104 -641
  152. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  153. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +0 -1
  154. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  155. package/packages/pi-coding-agent/dist/core/auth-storage.js +4 -35
  156. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js +5 -43
  159. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  161. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +11 -69
  162. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +40 -0
  164. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  165. package/packages/pi-coding-agent/dist/core/compaction/utils.js +78 -0
  166. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  167. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +77 -0
  168. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -0
  169. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +331 -0
  170. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -0
  171. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts +0 -4
  172. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  173. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js +1 -1
  174. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +2 -2
  176. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  177. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  178. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +15 -5
  180. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/extensions/runner.js +129 -256
  182. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +49 -42
  184. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/extensions/types.js +2 -21
  186. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +0 -8
  188. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -2
  190. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts +39 -0
  192. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts.map +1 -0
  193. package/packages/pi-coding-agent/dist/core/lock-utils.js +89 -0
  194. package/packages/pi-coding-agent/dist/core/lock-utils.js.map +1 -0
  195. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +0 -17
  196. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  197. package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -62
  198. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  199. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +1 -1
  200. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
  201. package/packages/pi-coding-agent/dist/core/lsp/config.js +2 -6
  202. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts +0 -5
  204. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/lsp/edits.js +1 -1
  206. package/packages/pi-coding-agent/dist/core/lsp/edits.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/lsp/index.js +52 -107
  209. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts +0 -1
  211. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -22
  213. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +0 -1
  215. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
  216. package/packages/pi-coding-agent/dist/core/lsp/types.js +0 -28
  217. package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +1 -6
  219. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -1
  220. package/packages/pi-coding-agent/dist/core/lsp/utils.js +1 -28
  221. package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/messages.d.ts +0 -8
  223. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/messages.js +5 -5
  225. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -3
  227. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/model-registry.js +1 -3
  229. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts +1 -26
  231. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -59
  233. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  235. package/packages/pi-coding-agent/dist/core/package-manager.js +2 -4
  236. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts +0 -17
  238. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/prompt-templates.js +2 -2
  240. package/packages/pi-coding-agent/dist/core/prompt-templates.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +2 -4
  242. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  243. package/packages/pi-coding-agent/dist/core/resource-loader.js +46 -60
  244. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  245. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +87 -0
  246. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -0
  247. package/packages/pi-coding-agent/dist/core/retry-handler.js +295 -0
  248. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -0
  249. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +0 -5
  250. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/session-manager.js +5 -32
  252. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +8 -12
  254. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/settings-manager.js +78 -168
  256. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/skills.js +1 -3
  259. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  261. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  262. package/packages/pi-coding-agent/dist/index.js +1 -1
  263. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  264. package/packages/pi-coding-agent/dist/migrations.d.ts +0 -16
  265. package/packages/pi-coding-agent/dist/migrations.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/migrations.js +2 -2
  267. package/packages/pi-coding-agent/dist/migrations.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts +0 -2
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js +2 -2
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +9 -26
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -13
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js +61 -0
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +6 -9
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -24
  287. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  288. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +50 -512
  289. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +71 -0
  291. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +514 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +65 -4
  295. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +6 -23
  297. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +12 -0
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +175 -0
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -0
  302. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
  303. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js +15 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/modes/print-mode.js +2 -30
  308. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -28
  311. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts +19 -0
  313. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts.map +1 -0
  314. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js +45 -0
  315. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js.map +1 -0
  316. package/packages/pi-coding-agent/dist/utils/changelog.d.ts +0 -4
  317. package/packages/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/utils/changelog.js +1 -1
  319. package/packages/pi-coding-agent/dist/utils/changelog.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts +0 -1
  321. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/utils/clipboard-image.js +1 -1
  323. package/packages/pi-coding-agent/dist/utils/clipboard-image.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/utils/error.d.ts +5 -0
  325. package/packages/pi-coding-agent/dist/utils/error.d.ts.map +1 -0
  326. package/packages/pi-coding-agent/dist/utils/error.js +7 -0
  327. package/packages/pi-coding-agent/dist/utils/error.js.map +1 -0
  328. package/packages/pi-coding-agent/dist/utils/photon.d.ts +0 -19
  329. package/packages/pi-coding-agent/dist/utils/photon.d.ts.map +1 -1
  330. package/packages/pi-coding-agent/dist/utils/photon.js +1 -120
  331. package/packages/pi-coding-agent/dist/utils/photon.js.map +1 -1
  332. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts +0 -1
  333. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts.map +1 -1
  334. package/packages/pi-coding-agent/dist/utils/tools-manager.js +1 -1
  335. package/packages/pi-coding-agent/dist/utils/tools-manager.js.map +1 -1
  336. package/packages/pi-coding-agent/package.json +1 -1
  337. package/packages/pi-coding-agent/src/config.ts +5 -10
  338. package/packages/pi-coding-agent/src/core/agent-session.ts +117 -745
  339. package/packages/pi-coding-agent/src/core/auth-storage.ts +4 -38
  340. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +7 -53
  341. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +14 -74
  342. package/packages/pi-coding-agent/src/core/compaction/utils.ts +100 -0
  343. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +424 -0
  344. package/packages/pi-coding-agent/src/core/export-html/ansi-to-html.ts +1 -1
  345. package/packages/pi-coding-agent/src/core/extensions/index.ts +1 -21
  346. package/packages/pi-coding-agent/src/core/extensions/runner.ts +119 -256
  347. package/packages/pi-coding-agent/src/core/extensions/types.ts +50 -69
  348. package/packages/pi-coding-agent/src/core/keybindings.ts +2 -2
  349. package/packages/pi-coding-agent/src/core/lock-utils.ts +113 -0
  350. package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -73
  351. package/packages/pi-coding-agent/src/core/lsp/config.ts +2 -10
  352. package/packages/pi-coding-agent/src/core/lsp/edits.ts +1 -1
  353. package/packages/pi-coding-agent/src/core/lsp/index.ts +83 -152
  354. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -23
  355. package/packages/pi-coding-agent/src/core/lsp/types.ts +0 -29
  356. package/packages/pi-coding-agent/src/core/lsp/utils.ts +1 -33
  357. package/packages/pi-coding-agent/src/core/messages.ts +5 -5
  358. package/packages/pi-coding-agent/src/core/model-registry.ts +0 -2
  359. package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -77
  360. package/packages/pi-coding-agent/src/core/package-manager.ts +1 -4
  361. package/packages/pi-coding-agent/src/core/prompt-templates.ts +2 -2
  362. package/packages/pi-coding-agent/src/core/resource-loader.ts +56 -69
  363. package/packages/pi-coding-agent/src/core/retry-handler.ts +359 -0
  364. package/packages/pi-coding-agent/src/core/session-manager.ts +5 -34
  365. package/packages/pi-coding-agent/src/core/settings-manager.ts +87 -166
  366. package/packages/pi-coding-agent/src/core/skills.ts +1 -4
  367. package/packages/pi-coding-agent/src/index.ts +1 -7
  368. package/packages/pi-coding-agent/src/migrations.ts +2 -2
  369. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector-search.ts +2 -2
  370. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +17 -29
  371. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -13
  372. package/packages/pi-coding-agent/src/modes/interactive/components/tree-render-utils.ts +81 -0
  373. package/packages/pi-coding-agent/src/modes/interactive/components/tree-selector.ts +14 -19
  374. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +50 -561
  375. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +653 -0
  376. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +7 -26
  377. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +196 -0
  378. package/packages/pi-coding-agent/src/modes/interactive/utils/shorten-path.ts +14 -0
  379. package/packages/pi-coding-agent/src/modes/print-mode.ts +2 -30
  380. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -28
  381. package/packages/pi-coding-agent/src/modes/shared/command-context-actions.ts +53 -0
  382. package/packages/pi-coding-agent/src/utils/changelog.ts +1 -1
  383. package/packages/pi-coding-agent/src/utils/clipboard-image.ts +1 -1
  384. package/packages/pi-coding-agent/src/utils/error.ts +6 -0
  385. package/packages/pi-coding-agent/src/utils/photon.ts +0 -137
  386. package/packages/pi-coding-agent/src/utils/tools-manager.ts +1 -1
  387. package/packages/pi-tui/dist/components/editor.d.ts +0 -10
  388. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  389. package/packages/pi-tui/dist/components/editor.js +1 -1
  390. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  391. package/packages/pi-tui/dist/components/markdown.d.ts +5 -0
  392. package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
  393. package/packages/pi-tui/dist/components/markdown.js +25 -31
  394. package/packages/pi-tui/dist/components/markdown.js.map +1 -1
  395. package/packages/pi-tui/dist/keys.d.ts +0 -4
  396. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  397. package/packages/pi-tui/dist/keys.js +94 -162
  398. package/packages/pi-tui/dist/keys.js.map +1 -1
  399. package/packages/pi-tui/dist/overlay-layout.d.ts +55 -0
  400. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -0
  401. package/packages/pi-tui/dist/overlay-layout.js +288 -0
  402. package/packages/pi-tui/dist/overlay-layout.js.map +1 -0
  403. package/packages/pi-tui/dist/tui.d.ts +0 -22
  404. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  405. package/packages/pi-tui/dist/tui.js +6 -272
  406. package/packages/pi-tui/dist/tui.js.map +1 -1
  407. package/packages/pi-tui/dist/utils.d.ts +0 -7
  408. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  409. package/packages/pi-tui/dist/utils.js +0 -44
  410. package/packages/pi-tui/dist/utils.js.map +1 -1
  411. package/packages/pi-tui/src/components/editor.ts +1 -1
  412. package/packages/pi-tui/src/components/markdown.ts +25 -29
  413. package/packages/pi-tui/src/keys.ts +94 -173
  414. package/packages/pi-tui/src/overlay-layout.ts +372 -0
  415. package/packages/pi-tui/src/tui.ts +11 -312
  416. package/packages/pi-tui/src/utils.ts +0 -43
  417. package/pkg/dist/core/export-html/ansi-to-html.d.ts +0 -4
  418. package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  419. package/pkg/dist/core/export-html/ansi-to-html.js +1 -1
  420. package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -1
  421. package/pkg/dist/modes/interactive/theme/theme.d.ts +65 -4
  422. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  423. package/pkg/dist/modes/interactive/theme/theme.js +6 -23
  424. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  425. package/pkg/dist/modes/interactive/theme/themes.d.ts +12 -0
  426. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  427. package/pkg/dist/modes/interactive/theme/themes.js +175 -0
  428. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -0
  429. package/pkg/package.json +1 -1
  430. package/src/resources/extensions/async-jobs/await-tool.ts +0 -2
  431. package/src/resources/extensions/async-jobs/job-manager.ts +0 -7
  432. package/src/resources/extensions/bg-shell/output-formatter.ts +0 -17
  433. package/src/resources/extensions/bg-shell/process-manager.ts +0 -4
  434. package/src/resources/extensions/bg-shell/types.ts +0 -12
  435. package/src/resources/extensions/context7/index.ts +7 -0
  436. package/src/resources/extensions/get-secrets-from-user.ts +2 -35
  437. package/src/resources/extensions/google-search/index.ts +7 -0
  438. package/src/resources/extensions/gsd/auto-dispatch.ts +49 -1
  439. package/src/resources/extensions/gsd/auto-loop.ts +11 -1
  440. package/src/resources/extensions/gsd/auto-recovery.ts +39 -0
  441. package/src/resources/extensions/gsd/auto-start.ts +42 -2
  442. package/src/resources/extensions/gsd/auto.ts +61 -3
  443. package/src/resources/extensions/gsd/changelog.ts +213 -0
  444. package/src/resources/extensions/gsd/commands-bootstrap.ts +1 -0
  445. package/src/resources/extensions/gsd/commands-handlers.ts +2 -2
  446. package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
  447. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +5 -1
  448. package/src/resources/extensions/gsd/commands.ts +9 -1
  449. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  450. package/src/resources/extensions/gsd/doctor-checks.ts +107 -5
  451. package/src/resources/extensions/gsd/doctor-environment.ts +26 -16
  452. package/src/resources/extensions/gsd/doctor-proactive.ts +24 -0
  453. package/src/resources/extensions/gsd/doctor-types.ts +9 -1
  454. package/src/resources/extensions/gsd/doctor.ts +35 -0
  455. package/src/resources/extensions/gsd/files.ts +12 -2
  456. package/src/resources/extensions/gsd/gitignore.ts +54 -7
  457. package/src/resources/extensions/gsd/guided-flow.ts +5 -3
  458. package/src/resources/extensions/gsd/health-widget-core.ts +129 -0
  459. package/src/resources/extensions/gsd/health-widget.ts +103 -59
  460. package/src/resources/extensions/gsd/index.ts +10 -1
  461. package/src/resources/extensions/gsd/migrate-external.ts +47 -2
  462. package/src/resources/extensions/gsd/paths.ts +73 -7
  463. package/src/resources/extensions/gsd/post-unit-hooks.ts +5 -1
  464. package/src/resources/extensions/gsd/preferences-validation.ts +54 -1
  465. package/src/resources/extensions/gsd/preferences.ts +2 -0
  466. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  467. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  468. package/src/resources/extensions/gsd/roadmap-mutations.ts +66 -0
  469. package/src/resources/extensions/gsd/session-lock.ts +29 -2
  470. package/src/resources/extensions/gsd/templates/plan.md +8 -0
  471. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
  472. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +98 -2
  473. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +59 -3
  474. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +20 -0
  475. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +214 -0
  476. package/src/resources/extensions/gsd/tests/health-widget.test.ts +158 -0
  477. package/src/resources/extensions/gsd/tests/paths.test.ts +113 -0
  478. package/src/resources/extensions/gsd/tests/preferences.test.ts +40 -2
  479. package/src/resources/extensions/gsd/tests/test-utils.ts +165 -0
  480. package/src/resources/extensions/gsd/tests/validate-directory.test.ts +15 -0
  481. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -0
  482. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +32 -0
  483. package/src/resources/extensions/gsd/worktree-resolver.ts +11 -0
  484. package/src/resources/extensions/mcp-client/index.ts +2 -1
  485. package/src/resources/extensions/remote-questions/remote-command.ts +2 -23
  486. package/src/resources/extensions/shared/mod.ts +1 -1
  487. package/src/resources/extensions/shared/sanitize.ts +36 -0
  488. package/src/resources/extensions/subagent/index.ts +6 -12
  489. package/src/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  490. package/dist/resources/extensions/shared/wizard-ui.js +0 -478
  491. package/packages/pi-coding-agent/dist/modes/interactive/theme/dark.json +0 -85
  492. package/packages/pi-coding-agent/dist/modes/interactive/theme/light.json +0 -84
  493. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.json +0 -335
  494. package/packages/pi-coding-agent/src/modes/interactive/theme/dark.json +0 -85
  495. package/packages/pi-coding-agent/src/modes/interactive/theme/light.json +0 -84
  496. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
  497. package/pkg/dist/modes/interactive/theme/dark.json +0 -85
  498. package/pkg/dist/modes/interactive/theme/light.json +0 -84
  499. package/pkg/dist/modes/interactive/theme/theme-schema.json +0 -335
  500. package/src/resources/extensions/shared/wizard-ui.ts +0 -551
@@ -0,0 +1,213 @@
1
+ /**
2
+ * GSD Changelog — Fetch and display categorized release notes from GitHub
3
+ *
4
+ * Fetches releases from the gsd-build/gsd-2 GitHub repository,
5
+ * prompts the user for a version filter, and sends raw release notes
6
+ * into the conversation for the LLM to summarize.
7
+ *
8
+ * Entry point: handleChangelog() called from commands.ts
9
+ */
10
+
11
+ import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent";
12
+
13
+ // ─── Types ────────────────────────────────────────────────────────────────────
14
+
15
+ interface GitHubRelease {
16
+ tag_name: string;
17
+ name: string;
18
+ body: string;
19
+ }
20
+
21
+ // ─── Semver comparison ────────────────────────────────────────────────────────
22
+
23
+ function compareSemver(a: string, b: string): number {
24
+ const pa = a.split(".").map(Number);
25
+ const pb = b.split(".").map(Number);
26
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
27
+ const va = pa[i] || 0;
28
+ const vb = pb[i] || 0;
29
+ if (va > vb) return 1;
30
+ if (va < vb) return -1;
31
+ }
32
+ return 0;
33
+ }
34
+
35
+ function stripV(tag: string): string {
36
+ return tag.startsWith("v") ? tag.slice(1) : tag;
37
+ }
38
+
39
+ // ─── Body parsing ─────────────────────────────────────────────────────────────
40
+
41
+ interface CategorySection {
42
+ heading: string;
43
+ content: string;
44
+ }
45
+
46
+ function parseReleaseBody(body: string): CategorySection[] {
47
+ if (!body) return [];
48
+
49
+ const sections: CategorySection[] = [];
50
+ const lines = body.split("\n");
51
+ let currentHeading: string | null = null;
52
+ let currentLines: string[] = [];
53
+
54
+ for (const line of lines) {
55
+ if (line.startsWith("### ")) {
56
+ if (currentHeading !== null) {
57
+ const content = currentLines.join("\n").trim();
58
+ if (content) {
59
+ sections.push({ heading: currentHeading, content });
60
+ }
61
+ }
62
+ currentHeading = line.slice(4).trim();
63
+ currentLines = [];
64
+ } else if (currentHeading !== null) {
65
+ currentLines.push(line);
66
+ }
67
+ }
68
+
69
+ if (currentHeading !== null) {
70
+ const content = currentLines.join("\n").trim();
71
+ if (content) {
72
+ sections.push({ heading: currentHeading, content });
73
+ }
74
+ }
75
+
76
+ return sections;
77
+ }
78
+
79
+ // ─── Display formatting ──────────────────────────────────────────────────────
80
+
81
+ function formatRelease(release: GitHubRelease): string {
82
+ const version = stripV(release.tag_name);
83
+ const title = release.name || `v${version}`;
84
+ const sections = parseReleaseBody(release.body);
85
+
86
+ const parts: string[] = [`## ${title}`];
87
+
88
+ if (sections.length === 0) {
89
+ if (release.body?.trim()) {
90
+ parts.push(release.body.trim());
91
+ } else {
92
+ parts.push("_No release notes._");
93
+ }
94
+ } else {
95
+ for (const section of sections) {
96
+ parts.push(`### ${section.heading}`);
97
+ parts.push(section.content);
98
+ }
99
+ }
100
+
101
+ return parts.join("\n\n");
102
+ }
103
+
104
+ // ─── Entry Point ──────────────────────────────────────────────────────────────
105
+
106
+ const RELEASES_URL = "https://api.github.com/repos/gsd-build/gsd-2/releases?per_page=100";
107
+
108
+ export async function handleChangelog(
109
+ args: string,
110
+ ctx: ExtensionCommandContext,
111
+ pi: ExtensionAPI,
112
+ ): Promise<void> {
113
+ // ── Fetch releases ──────────────────────────────────────────────────────
114
+ let releases: GitHubRelease[];
115
+ try {
116
+ const response = await fetch(RELEASES_URL, {
117
+ headers: { "User-Agent": "gsd-changelog" },
118
+ });
119
+
120
+ if (!response.ok) {
121
+ ctx.ui.notify(
122
+ `Failed to fetch changelog: GitHub API returned ${response.status} ${response.statusText}`,
123
+ "error",
124
+ );
125
+ return;
126
+ }
127
+
128
+ releases = (await response.json()) as GitHubRelease[];
129
+ } catch (err) {
130
+ const message = err instanceof Error ? err.message : String(err);
131
+ ctx.ui.notify(`Failed to fetch changelog: ${message}`, "error");
132
+ return;
133
+ }
134
+
135
+ if (!releases.length) {
136
+ ctx.ui.notify("No releases found in the repository.", "warning");
137
+ return;
138
+ }
139
+
140
+ // ── Determine version filter ────────────────────────────────────────────
141
+ const currentVersion = process.env.GSD_VERSION || "";
142
+ let sinceVersion: string | undefined;
143
+ let showCurrentOnly = false;
144
+
145
+ if (args.trim()) {
146
+ sinceVersion = stripV(args.trim());
147
+ } else {
148
+ const input = await ctx.ui.input(
149
+ "Show changes since version:",
150
+ currentVersion || "latest",
151
+ );
152
+
153
+ if (input === undefined) {
154
+ return;
155
+ }
156
+
157
+ if (input.trim() === "") {
158
+ showCurrentOnly = true;
159
+ } else {
160
+ sinceVersion = stripV(input.trim());
161
+ }
162
+ }
163
+
164
+ // ── Filter releases ─────────────────────────────────────────────────────
165
+ let matched: GitHubRelease[];
166
+
167
+ if (showCurrentOnly) {
168
+ if (!currentVersion) {
169
+ ctx.ui.notify(
170
+ "GSD_VERSION is not set — cannot determine current release. Provide a version instead.",
171
+ "warning",
172
+ );
173
+ return;
174
+ }
175
+ const found = releases.find((r) => stripV(r.tag_name) === currentVersion);
176
+ if (!found) {
177
+ ctx.ui.notify(`No release found matching current version v${currentVersion}`, "warning");
178
+ return;
179
+ }
180
+ matched = [found];
181
+ } else if (sinceVersion) {
182
+ matched = releases
183
+ .filter((r) => compareSemver(stripV(r.tag_name), sinceVersion!) > 0)
184
+ .sort((a, b) => compareSemver(stripV(b.tag_name), stripV(a.tag_name)));
185
+
186
+ if (!matched.length) {
187
+ ctx.ui.notify(`No releases found since v${sinceVersion}`, "warning");
188
+ return;
189
+ }
190
+ } else {
191
+ matched = [releases[0]];
192
+ }
193
+
194
+ // ── Send to LLM for summarization ───────────────────────────────────────
195
+ const rawOutput = matched.map(formatRelease).join("\n\n---\n\n");
196
+ const versionRange = sinceVersion
197
+ ? `since v${sinceVersion} (${matched.length} release${matched.length === 1 ? "" : "s"})`
198
+ : `for current release ${matched[0].name || matched[0].tag_name}`;
199
+
200
+ const prompt = [
201
+ `Here are the raw GSD changelog entries ${versionRange}.`,
202
+ "Summarize the most important changes — group by category (Added, Changed, Fixed, etc.),",
203
+ "keep only the most impactful items (max 5 per category), skip trivial changes,",
204
+ "and include the version where each item appeared. Keep it concise and scannable.",
205
+ "",
206
+ rawOutput,
207
+ ].join("\n");
208
+
209
+ pi.sendMessage(
210
+ { customType: "gsd-changelog", content: prompt, display: true },
211
+ { triggerTurn: true },
212
+ );
213
+ }
@@ -12,6 +12,7 @@ const TOP_LEVEL_SUBCOMMANDS = [
12
12
  { cmd: "quick", desc: "Execute a quick task without full planning overhead" },
13
13
  { cmd: "discuss", desc: "Discuss architecture and decisions" },
14
14
  { cmd: "capture", desc: "Fire-and-forget thought capture" },
15
+ { cmd: "changelog", desc: "Show categorized release notes" },
15
16
  { cmd: "triage", desc: "Manually trigger triage of pending captures" },
16
17
  { cmd: "dispatch", desc: "Dispatch a specific phase directly" },
17
18
  { cmd: "history", desc: "View execution history" },
@@ -24,7 +24,7 @@ import { projectRoot } from "./commands.js";
24
24
  import { loadPrompt } from "./prompt-loader.js";
25
25
 
26
26
  export function dispatchDoctorHeal(pi: ExtensionAPI, scope: string | undefined, reportText: string, structuredIssues: string): void {
27
- const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".pi", "GSD-WORKFLOW.md");
27
+ const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".gsd", "agent", "GSD-WORKFLOW.md");
28
28
  const workflow = readFileSync(workflowPath, "utf-8");
29
29
  const prompt = loadPrompt("doctor-heal", {
30
30
  doctorSummary: reportText,
@@ -187,7 +187,7 @@ export async function handleTriage(ctx: ExtensionCommandContext, pi: ExtensionAP
187
187
  roadmapContext: roadmapContext || "(no active roadmap)",
188
188
  });
189
189
 
190
- const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".pi", "GSD-WORKFLOW.md");
190
+ const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".gsd", "agent", "GSD-WORKFLOW.md");
191
191
  const workflow = readFileSync(workflowPath, "utf-8");
192
192
 
193
193
  pi.sendMessage(
@@ -5,6 +5,9 @@
5
5
  */
6
6
 
7
7
  import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
8
+ import { existsSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { gsdRoot } from "./paths.js";
8
11
  import { getErrorMessage } from "./error-utils.js";
9
12
 
10
13
  export interface InspectData {
@@ -44,11 +47,15 @@ export function formatInspectOutput(data: InspectData): string {
44
47
 
45
48
  export async function handleInspect(ctx: ExtensionCommandContext): Promise<void> {
46
49
  try {
47
- const { isDbAvailable, _getAdapter } = await import("./gsd-db.js");
50
+ const { isDbAvailable, _getAdapter, openDatabase } = await import("./gsd-db.js");
48
51
 
49
52
  if (!isDbAvailable()) {
50
- ctx.ui.notify("No GSD database available. Run /gsd auto to create one.", "info");
51
- return;
53
+ const gsdDir = gsdRoot(process.cwd());
54
+ const dbPath = join(gsdDir, "gsd.db");
55
+ if (!existsSync(gsdDir) || !existsSync(dbPath) || !openDatabase(dbPath)) {
56
+ ctx.ui.notify("No GSD database available. Run /gsd auto to create one.", "info");
57
+ return;
58
+ }
52
59
  }
53
60
 
54
61
  const adapter = _getAdapter();
@@ -738,10 +738,14 @@ export function serializePreferencesToFrontmatter(prefs: Record<string, unknown>
738
738
  const orderedKeys = [
739
739
  "version", "mode", "always_use_skills", "prefer_skills", "avoid_skills",
740
740
  "skill_rules", "custom_instructions", "models", "skill_discovery",
741
- "auto_supervisor", "uat_dispatch", "unique_milestone_ids",
741
+ "skill_staleness_days", "auto_supervisor", "uat_dispatch", "unique_milestone_ids",
742
742
  "budget_ceiling", "budget_enforcement", "context_pause_threshold",
743
743
  "notifications", "remote_questions", "git",
744
744
  "post_unit_hooks", "pre_dispatch_hooks",
745
+ "dynamic_routing", "token_profile", "phases", "parallel",
746
+ "auto_visualize", "auto_report",
747
+ "verification_commands", "verification_auto_fix", "verification_max_retries",
748
+ "search_provider", "compression_strategy", "context_selection",
745
749
  ];
746
750
 
747
751
  const seen = new Set<string>();
@@ -71,7 +71,7 @@ export function projectRoot(): string {
71
71
 
72
72
  export function registerGSDCommand(pi: ExtensionAPI): void {
73
73
  pi.registerCommand("gsd", {
74
- description: "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|visualize|queue|quick|capture|triage|dispatch|history|undo|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|forensics|migrate|remote|steer|knowledge|new-milestone|parallel|update",
74
+ description: "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|visualize|queue|quick|capture|triage|dispatch|history|undo|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|update",
75
75
  getArgumentCompletions: (prefix: string) => {
76
76
  const subcommands = [
77
77
  { cmd: "help", desc: "Categorized command reference with descriptions" },
@@ -85,6 +85,7 @@ export function registerGSDCommand(pi: ExtensionAPI): void {
85
85
  { cmd: "quick", desc: "Execute a quick task without full planning overhead" },
86
86
  { cmd: "discuss", desc: "Discuss architecture and decisions" },
87
87
  { cmd: "capture", desc: "Fire-and-forget thought capture" },
88
+ { cmd: "changelog", desc: "Show categorized release notes" },
88
89
  { cmd: "triage", desc: "Manually trigger triage of pending captures" },
89
90
  { cmd: "dispatch", desc: "Dispatch a specific phase directly" },
90
91
  { cmd: "history", desc: "View execution history" },
@@ -499,6 +500,12 @@ export async function handleGSDCommand(
499
500
  return;
500
501
  }
501
502
 
503
+ if (trimmed === "changelog" || trimmed.startsWith("changelog ")) {
504
+ const { handleChangelog } = await import("./changelog.js");
505
+ await handleChangelog(trimmed.replace(/^changelog\s*/, "").trim(), ctx, pi);
506
+ return;
507
+ }
508
+
502
509
  if (trimmed === "next" || trimmed.startsWith("next ")) {
503
510
  if (trimmed.includes("--dry-run")) {
504
511
  await handleDryRun(ctx, projectRoot());
@@ -928,6 +935,7 @@ function showHelp(ctx: ExtensionCommandContext): void {
928
935
  " /gsd visualize Interactive 10-tab TUI (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)",
929
936
  " /gsd queue Show queued/dispatched units and execution order",
930
937
  " /gsd history View execution history [--cost] [--phase] [--model] [N]",
938
+ " /gsd changelog Show categorized release notes [version]",
931
939
  "",
932
940
  "COURSE CORRECTION",
933
941
  " /gsd steer <desc> Apply user override to active work",
@@ -134,6 +134,10 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
134
134
  - `isolation`: `"worktree"`, `"branch"`, or `"none"` — controls auto-mode git isolation strategy. `"worktree"` creates a milestone worktree for isolated work; `"branch"` works directly in the project root but creates a milestone branch (useful for submodule-heavy repos); `"none"` works directly on the current branch with no worktree or milestone branch (ideal for step-mode with hot reloads). Default: `"worktree"`.
135
135
  - `manage_gitignore`: boolean — when `false`, GSD will not touch `.gitignore` at all. Useful when your project has a strictly managed `.gitignore` and you don't want GSD adding entries. Default: `true`.
136
136
  - `worktree_post_create`: string — script to run after a worktree is created (both auto-mode and manual `/worktree`). Receives `SOURCE_DIR` and `WORKTREE_DIR` as environment variables. Can be absolute or relative to project root. Runs with 30-second timeout. Failure is non-fatal (logged as warning). Default: none.
137
+ - `auto_pr`: boolean — automatically create a GitHub pull request after a milestone branch is merged. Requires `gh` CLI to be installed. Default: `false`.
138
+ - `pr_target_branch`: string — branch to target when `auto_pr` is enabled. Defaults to `main_branch` when omitted.
139
+ - **Deprecated:** `commit_docs` — no longer valid; `.gsd/` is always gitignored. Remove this setting.
140
+ - **Deprecated:** `merge_to_main` — no longer valid; milestone-level merge is always used. Remove this setting.
137
141
 
138
142
  - `unique_milestone_ids`: boolean — when `true`, generates milestone IDs in `M{seq}-{rand6}` format (e.g. `M001-eh88as`) instead of plain sequential `M001`. Prevents ID collisions in team workflows where multiple contributors create milestones concurrently. Both formats coexist — existing `M001`-style milestones remain valid. Default: `false`.
139
143
 
@@ -181,6 +185,12 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
181
185
 
182
186
  - `auto_report`: boolean — generate an HTML report snapshot after each milestone completion. Default: `true`.
183
187
 
188
+ - `search_provider`: `"brave"`, `"tavily"`, `"ollama"`, `"native"`, or `"auto"` — selects the search backend for research phases. `"native"` forces Anthropic's built-in web search only; provider values force that backend and disable native search; `"auto"` uses the default heuristic. Default: `"auto"`.
189
+
190
+ - `compression_strategy`: `"truncate"` or `"compress"` — controls how context that exceeds the budget is reduced. `"truncate"` (default) drops sections from the end. `"compress"` applies heuristic compression before truncating, preserving more content at the cost of some fidelity. Default: `"truncate"`.
191
+
192
+ - `context_selection`: `"full"` or `"smart"` — controls how files are inlined into context. `"full"` inlines entire files; `"smart"` uses semantic chunking to include only the most relevant sections. Default is derived from `token_profile`.
193
+
184
194
  - `parallel`: configures parallel orchestration for running multiple slices concurrently. Keys:
185
195
  - `enabled`: boolean — enable parallel execution. Default: `false`.
186
196
  - `max_workers`: number — maximum concurrent workers (1-4). Default: `2`.
@@ -1,15 +1,15 @@
1
- import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
2
- import { join, sep } from "node:path";
1
+ import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync, rmSync, statSync } from "node:fs";
2
+ import { basename, dirname, join, sep } from "node:path";
3
3
 
4
4
  import type { DoctorIssue, DoctorIssueCode } from "./doctor-types.js";
5
5
  import { loadFile, parseRoadmap } from "./files.js";
6
6
  import { resolveMilestoneFile, milestonesDir, gsdRoot, resolveGsdRootFile, relGsdRootFile } from "./paths.js";
7
7
  import { deriveState, isMilestoneComplete } from "./state.js";
8
8
  import { saveFile } from "./files.js";
9
- import { listWorktrees, resolveGitDir } from "./worktree-manager.js";
9
+ import { listWorktrees, resolveGitDir, worktreesDir } from "./worktree-manager.js";
10
10
  import { abortAndReset } from "./git-self-heal.js";
11
- import { RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
12
- import { nativeIsRepo, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached } from "./native-git-bridge.js";
11
+ import { RUNTIME_EXCLUSION_PATHS, readIntegrationBranch } from "./git-service.js";
12
+ import { nativeIsRepo, nativeBranchExists, nativeWorktreeList, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached } from "./native-git-bridge.js";
13
13
  import { readCrashLock, isLockProcessAlive, clearLock } from "./crash-recovery.js";
14
14
  import { ensureGitignore } from "./gitignore.js";
15
15
  import { readAllSessionStatuses, isSessionStale, removeSessionStatus } from "./session-status-io.js";
@@ -215,6 +215,70 @@ export async function checkGitHealth(
215
215
  } catch {
216
216
  // git branch list failed — skip
217
217
  }
218
+
219
+ // ── Integration branch existence ──────────────────────────────────────
220
+ // For each active (non-complete) milestone, verify the stored integration
221
+ // branch still exists in git. A missing integration branch blocks merge-back
222
+ // and causes the next merge operation to fail silently.
223
+ try {
224
+ const state = await deriveState(basePath);
225
+ for (const milestone of state.registry) {
226
+ if (milestone.status === "complete") continue;
227
+ const integrationBranch = readIntegrationBranch(basePath, milestone.id);
228
+ if (!integrationBranch) continue; // No stored branch — skip (not yet set)
229
+ if (!nativeBranchExists(basePath, integrationBranch)) {
230
+ issues.push({
231
+ severity: "error",
232
+ code: "integration_branch_missing",
233
+ scope: "milestone",
234
+ unitId: milestone.id,
235
+ message: `Milestone ${milestone.id} recorded integration branch "${integrationBranch}" but that branch no longer exists in git. Merge-back will fail.`,
236
+ fixable: false,
237
+ });
238
+ }
239
+ }
240
+ } catch {
241
+ // Non-fatal — integration branch check failed
242
+ }
243
+
244
+ // ── Orphaned worktree directories ────────────────────────────────────
245
+ // Worktree removal can fail after a branch delete, leaving a directory
246
+ // that is no longer registered with git. These orphaned dirs cause
247
+ // "already exists" errors when re-creating the same worktree name.
248
+ try {
249
+ const wtDir = worktreesDir(basePath);
250
+ if (existsSync(wtDir)) {
251
+ const registeredPaths = new Set(
252
+ nativeWorktreeList(basePath).map(entry => entry.path),
253
+ );
254
+ for (const entry of readdirSync(wtDir)) {
255
+ const fullPath = join(wtDir, entry);
256
+ try {
257
+ if (!statSync(fullPath).isDirectory()) continue;
258
+ } catch { continue; }
259
+ if (!registeredPaths.has(fullPath)) {
260
+ issues.push({
261
+ severity: "warning",
262
+ code: "worktree_directory_orphaned",
263
+ scope: "project",
264
+ unitId: entry,
265
+ message: `Worktree directory ${fullPath} exists on disk but is not registered with git. Run "git worktree prune" or doctor --fix to remove it.`,
266
+ fixable: true,
267
+ });
268
+ if (shouldFix("worktree_directory_orphaned")) {
269
+ try {
270
+ rmSync(fullPath, { recursive: true, force: true });
271
+ fixesApplied.push(`removed orphaned worktree directory ${fullPath}`);
272
+ } catch {
273
+ fixesApplied.push(`failed to remove orphaned worktree directory ${fullPath}`);
274
+ }
275
+ }
276
+ }
277
+ }
278
+ }
279
+ } catch {
280
+ // Non-fatal — orphaned worktree directory check failed
281
+ }
218
282
  }
219
283
 
220
284
  // ── Runtime Health Checks ──────────────────────────────────────────────────
@@ -255,6 +319,44 @@ export async function checkRuntimeHealth(
255
319
  // Non-fatal — crash lock check failed
256
320
  }
257
321
 
322
+ // ── Stranded lock directory ────────────────────────────────────────────
323
+ // proper-lockfile creates a `.gsd.lock/` directory as the OS-level lock
324
+ // mechanism. If the process was SIGKILLed or crashed hard, this directory
325
+ // can remain on disk without any live process holding it. The next session
326
+ // fails to acquire the lock until the directory is removed (#1245).
327
+ try {
328
+ const lockDir = join(dirname(root), `${basename(root)}.lock`);
329
+ if (existsSync(lockDir)) {
330
+ const statRes = statSync(lockDir);
331
+ if (statRes.isDirectory()) {
332
+ // Check if any live process actually holds this lock
333
+ const lock = readCrashLock(basePath);
334
+ const lockHolderAlive = lock ? isLockProcessAlive(lock) : false;
335
+ if (!lockHolderAlive) {
336
+ issues.push({
337
+ severity: "error",
338
+ code: "stranded_lock_directory",
339
+ scope: "project",
340
+ unitId: "project",
341
+ message: `Stranded lock directory "${lockDir}" exists but no live process holds the session lock. This blocks new auto-mode sessions from starting.`,
342
+ file: lockDir,
343
+ fixable: true,
344
+ });
345
+ if (shouldFix("stranded_lock_directory")) {
346
+ try {
347
+ rmSync(lockDir, { recursive: true, force: true });
348
+ fixesApplied.push(`removed stranded lock directory ${lockDir}`);
349
+ } catch {
350
+ fixesApplied.push(`failed to remove stranded lock directory ${lockDir}`);
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ } catch {
357
+ // Non-fatal — stranded lock directory check failed
358
+ }
359
+
258
360
  // ── Stale parallel sessions ────────────────────────────────────────────
259
361
  try {
260
362
  const parallelStatuses = readAllSessionStatuses(basePath);
@@ -180,26 +180,36 @@ function checkPortConflicts(basePath: string): EnvironmentCheckResult[] {
180
180
  const portsToCheck = new Set<number>();
181
181
  const pkgPath = join(basePath, "package.json");
182
182
 
183
- if (existsSync(pkgPath)) {
184
- try {
185
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
186
- const scripts = pkg.scripts ?? {};
187
- const scriptText = Object.values(scripts).join(" ");
188
-
189
- // Look for --port NNNN, -p NNNN, PORT=NNNN, :NNNN patterns
190
- const portMatches = scriptText.matchAll(/(?:--port\s+|(?:^|[^a-z])PORT[=:]\s*|-p\s+|:)(\d{4,5})\b/gi);
191
- for (const m of portMatches) {
192
- const port = parseInt(m[1], 10);
193
- if (port >= 1024 && port <= 65535) portsToCheck.add(port);
194
- }
195
- } catch {
196
- // parse failed — use defaults
183
+ if (!existsSync(pkgPath)) {
184
+ // No package.json — this isn't a Node.js project. Skip port checks
185
+ // entirely to avoid false positives from system services (e.g., macOS
186
+ // AirPlay Receiver on port 5000). (#1381)
187
+ return [];
188
+ }
189
+
190
+ try {
191
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
192
+ const scripts = pkg.scripts ?? {};
193
+ const scriptText = Object.values(scripts).join(" ");
194
+
195
+ // Look for --port NNNN, -p NNNN, PORT=NNNN, :NNNN patterns
196
+ const portMatches = scriptText.matchAll(/(?:--port\s+|(?:^|[^a-z])PORT[=:]\s*|-p\s+|:)(\d{4,5})\b/gi);
197
+ for (const m of portMatches) {
198
+ const port = parseInt(m[1], 10);
199
+ if (port >= 1024 && port <= 65535) portsToCheck.add(port);
197
200
  }
201
+ } catch {
202
+ // parse failed — skip port checks rather than using defaults
203
+ return [];
198
204
  }
199
205
 
200
- // If no ports found in scripts, check common defaults
206
+ // If no ports found in scripts, check common defaults.
207
+ // Filter out port 5000 on macOS — AirPlay Receiver uses it by default (#1381).
201
208
  if (portsToCheck.size === 0) {
202
- for (const p of DEFAULT_DEV_PORTS) portsToCheck.add(p);
209
+ for (const p of DEFAULT_DEV_PORTS) {
210
+ if (p === 5000 && process.platform === "darwin") continue;
211
+ portsToCheck.add(p);
212
+ }
203
213
  }
204
214
 
205
215
  for (const port of portsToCheck) {
@@ -20,6 +20,9 @@ import { gsdRoot, resolveGsdRootFile } from "./paths.js";
20
20
  import { readCrashLock, isLockProcessAlive, clearLock } from "./crash-recovery.js";
21
21
  import { abortAndReset } from "./git-self-heal.js";
22
22
  import { rebuildState } from "./doctor.js";
23
+ import { deriveState } from "./state.js";
24
+ import { readIntegrationBranch } from "./git-service.js";
25
+ import { nativeBranchExists, nativeIsRepo } from "./native-git-bridge.js";
23
26
 
24
27
  // ── Health Score Tracking ──────────────────────────────────────────────────
25
28
 
@@ -191,6 +194,27 @@ export async function preDispatchHealthGate(basePath: string): Promise<PreDispat
191
194
  // Non-fatal — dispatch continues without STATE.md if rebuild fails
192
195
  }
193
196
 
197
+ // ── Integration branch existence check ──
198
+ // If the active milestone's recorded integration branch no longer exists in
199
+ // git, the merge-back at the end of the milestone will fail. Block dispatch
200
+ // now to surface this before work is lost.
201
+ try {
202
+ if (nativeIsRepo(basePath)) {
203
+ const state = await deriveState(basePath);
204
+ if (state.activeMilestone) {
205
+ const integrationBranch = readIntegrationBranch(basePath, state.activeMilestone.id);
206
+ if (integrationBranch && !nativeBranchExists(basePath, integrationBranch)) {
207
+ issues.push(
208
+ `Integration branch "${integrationBranch}" for milestone ${state.activeMilestone.id} no longer exists in git. ` +
209
+ `Restore the branch or update the integration branch before dispatching. Run /gsd doctor for details.`,
210
+ );
211
+ }
212
+ }
213
+ }
214
+ } catch {
215
+ // Non-fatal — dispatch continues if state/branch check fails
216
+ }
217
+
194
218
  // If we had critical issues that couldn't be auto-healed, block dispatch
195
219
  if (issues.length > 0) {
196
220
  return {
@@ -45,7 +45,15 @@ export type DoctorIssueCode =
45
45
  | "env_python"
46
46
  | "env_cargo"
47
47
  | "env_go"
48
- | "env_git_remote";
48
+ | "env_git_remote"
49
+ // Provider / auth checks
50
+ | "provider_key_missing"
51
+ | "provider_key_backedoff"
52
+ // Lock infrastructure checks
53
+ | "stranded_lock_directory"
54
+ // Git / worktree integrity checks
55
+ | "integration_branch_missing"
56
+ | "worktree_directory_orphaned";
49
57
 
50
58
  /**
51
59
  * Issue codes that represent expected completion-transition states.
@@ -11,6 +11,7 @@ import type { DoctorIssue, DoctorIssueCode } from "./doctor-types.js";
11
11
  import { COMPLETION_TRANSITION_CODES } from "./doctor-types.js";
12
12
  import { checkGitHealth, checkRuntimeHealth } from "./doctor-checks.js";
13
13
  import { checkEnvironmentHealth } from "./doctor-environment.js";
14
+ import { runProviderChecks } from "./doctor-providers.js";
14
15
 
15
16
  // ── Re-exports ─────────────────────────────────────────────────────────────
16
17
  // All public types and functions from extracted modules are re-exported here
@@ -406,6 +407,40 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
406
407
  issues.push(...auditRequirements(requirementsContent));
407
408
 
408
409
  const state = await deriveState(basePath);
410
+
411
+ // Provider / auth health checks — only relevant when there is active work to dispatch.
412
+ // Skipped for idle projects (no active milestone) to avoid noise in environments
413
+ // where CI/test runners have no API key configured.
414
+ if (state.activeMilestone) {
415
+ try {
416
+ const providerResults = runProviderChecks();
417
+ for (const result of providerResults) {
418
+ if (!result.required) continue;
419
+ if (result.status === "error") {
420
+ issues.push({
421
+ severity: "warning",
422
+ code: "provider_key_missing",
423
+ scope: "project",
424
+ unitId: "project",
425
+ message: result.message + (result.detail ? ` — ${result.detail}` : ""),
426
+ fixable: false,
427
+ });
428
+ } else if (result.status === "warning") {
429
+ issues.push({
430
+ severity: "warning",
431
+ code: "provider_key_backedoff",
432
+ scope: "project",
433
+ unitId: "project",
434
+ message: result.message + (result.detail ? ` — ${result.detail}` : ""),
435
+ fixable: false,
436
+ });
437
+ }
438
+ }
439
+ } catch {
440
+ // Non-fatal — provider check failure should not block other checks
441
+ }
442
+ }
443
+
409
444
  for (const milestone of state.registry) {
410
445
  const milestoneId = milestone.id;
411
446
  const milestonePath = resolveMilestonePath(basePath, milestoneId);