gsd-pi 2.34.0 → 2.35.0-dev.34ce717

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 (510) hide show
  1. package/README.md +3 -1
  2. package/dist/cli.js +7 -2
  3. package/dist/resource-loader.d.ts +1 -1
  4. package/dist/resource-loader.js +13 -1
  5. package/dist/resources/extensions/async-jobs/await-tool.js +0 -2
  6. package/dist/resources/extensions/async-jobs/job-manager.js +0 -6
  7. package/dist/resources/extensions/bg-shell/output-formatter.js +1 -19
  8. package/dist/resources/extensions/bg-shell/process-manager.js +0 -4
  9. package/dist/resources/extensions/bg-shell/types.js +0 -2
  10. package/dist/resources/extensions/context7/index.js +5 -0
  11. package/dist/resources/extensions/get-secrets-from-user.js +2 -30
  12. package/dist/resources/extensions/google-search/index.js +5 -0
  13. package/dist/resources/extensions/gsd/auto-dispatch.js +43 -1
  14. package/dist/resources/extensions/gsd/auto-loop.js +17 -3
  15. package/dist/resources/extensions/gsd/auto-model-selection.js +15 -3
  16. package/dist/resources/extensions/gsd/auto-recovery.js +35 -0
  17. package/dist/resources/extensions/gsd/auto-start.js +35 -2
  18. package/dist/resources/extensions/gsd/auto.js +59 -4
  19. package/dist/resources/extensions/gsd/changelog.js +162 -0
  20. package/dist/resources/extensions/gsd/commands-bootstrap.js +1 -0
  21. package/dist/resources/extensions/gsd/commands-handlers.js +2 -2
  22. package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
  23. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +5 -1
  24. package/dist/resources/extensions/gsd/commands-rate.js +31 -0
  25. package/dist/resources/extensions/gsd/commands.js +51 -2
  26. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  27. package/dist/resources/extensions/gsd/doctor-checks.js +113 -5
  28. package/dist/resources/extensions/gsd/doctor-environment.js +26 -17
  29. package/dist/resources/extensions/gsd/doctor-proactive.js +22 -0
  30. package/dist/resources/extensions/gsd/doctor.js +36 -0
  31. package/dist/resources/extensions/gsd/files.js +11 -2
  32. package/dist/resources/extensions/gsd/gitignore.js +54 -7
  33. package/dist/resources/extensions/gsd/guided-flow.js +12 -4
  34. package/dist/resources/extensions/gsd/health-widget-core.js +96 -0
  35. package/dist/resources/extensions/gsd/health-widget.js +97 -46
  36. package/dist/resources/extensions/gsd/index.js +26 -33
  37. package/dist/resources/extensions/gsd/migrate-external.js +55 -2
  38. package/dist/resources/extensions/gsd/milestone-ids.js +3 -2
  39. package/dist/resources/extensions/gsd/paths.js +74 -7
  40. package/dist/resources/extensions/gsd/post-unit-hooks.js +4 -1
  41. package/dist/resources/extensions/gsd/preferences-validation.js +54 -1
  42. package/dist/resources/extensions/gsd/preferences.js +14 -0
  43. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  44. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  45. package/dist/resources/extensions/gsd/roadmap-mutations.js +55 -0
  46. package/dist/resources/extensions/gsd/session-lock.js +53 -2
  47. package/dist/resources/extensions/gsd/state.js +2 -1
  48. package/dist/resources/extensions/gsd/templates/plan.md +8 -0
  49. package/dist/resources/extensions/gsd/worktree-resolver.js +12 -0
  50. package/dist/resources/extensions/mcp-client/index.js +2 -1
  51. package/dist/resources/extensions/remote-questions/remote-command.js +2 -22
  52. package/dist/resources/extensions/shared/mod.js +1 -1
  53. package/dist/resources/extensions/shared/sanitize.js +30 -0
  54. package/dist/resources/extensions/subagent/index.js +6 -14
  55. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  56. package/package.json +2 -1
  57. package/packages/native/dist/native.d.ts +0 -2
  58. package/packages/native/dist/native.js +0 -2
  59. package/packages/native/src/native.ts +0 -3
  60. package/packages/pi-agent-core/dist/agent-loop.d.ts +14 -0
  61. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  62. package/packages/pi-agent-core/dist/agent-loop.js +24 -27
  63. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  64. package/packages/pi-agent-core/dist/agent.d.ts +1 -0
  65. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  66. package/packages/pi-agent-core/dist/agent.js +11 -22
  67. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  68. package/packages/pi-agent-core/dist/proxy.d.ts +1 -25
  69. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  70. package/packages/pi-agent-core/dist/proxy.js +3 -9
  71. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  72. package/packages/pi-agent-core/src/agent-loop.ts +30 -27
  73. package/packages/pi-agent-core/src/agent.ts +12 -23
  74. package/packages/pi-agent-core/src/proxy.ts +3 -9
  75. package/packages/pi-ai/dist/api-registry.d.ts +0 -2
  76. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  77. package/packages/pi-ai/dist/api-registry.js +0 -10
  78. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  79. package/packages/pi-ai/dist/providers/anthropic.d.ts +0 -8
  80. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  81. package/packages/pi-ai/dist/providers/anthropic.js +1 -1
  82. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  83. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  84. package/packages/pi-ai/dist/providers/azure-openai-responses.js +5 -41
  85. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  86. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts +0 -1
  87. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts.map +1 -1
  88. package/packages/pi-ai/dist/providers/github-copilot-headers.js +1 -1
  89. package/packages/pi-ai/dist/providers/github-copilot-headers.js.map +1 -1
  90. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts +1 -43
  91. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  92. package/packages/pi-ai/dist/providers/google-gemini-cli.js +2 -2
  93. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  94. package/packages/pi-ai/dist/providers/google-shared.d.ts +0 -4
  95. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  96. package/packages/pi-ai/dist/providers/google-shared.js +1 -1
  97. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  98. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  99. package/packages/pi-ai/dist/providers/openai-completions.js +10 -73
  100. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  101. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  102. package/packages/pi-ai/dist/providers/openai-responses.js +9 -80
  103. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  104. package/packages/pi-ai/dist/providers/openai-shared.d.ts +65 -0
  105. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -0
  106. package/packages/pi-ai/dist/providers/openai-shared.js +146 -0
  107. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -0
  108. package/packages/pi-ai/dist/providers/register-builtins.d.ts +0 -1
  109. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  110. package/packages/pi-ai/dist/providers/register-builtins.js +1 -1
  111. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  112. package/packages/pi-ai/dist/utils/event-stream.d.ts +0 -2
  113. package/packages/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  114. package/packages/pi-ai/dist/utils/event-stream.js +0 -4
  115. package/packages/pi-ai/dist/utils/event-stream.js.map +1 -1
  116. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  117. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +7 -135
  118. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  119. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  120. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +7 -135
  121. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  122. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts +46 -0
  123. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts.map +1 -0
  124. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js +160 -0
  125. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js.map +1 -0
  126. package/packages/pi-ai/dist/utils/overflow.d.ts +0 -4
  127. package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  128. package/packages/pi-ai/dist/utils/overflow.js +0 -6
  129. package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
  130. package/packages/pi-ai/dist/utils/validation.d.ts +0 -8
  131. package/packages/pi-ai/dist/utils/validation.d.ts.map +1 -1
  132. package/packages/pi-ai/dist/utils/validation.js +0 -14
  133. package/packages/pi-ai/dist/utils/validation.js.map +1 -1
  134. package/packages/pi-ai/src/api-registry.ts +0 -12
  135. package/packages/pi-ai/src/providers/anthropic.ts +1 -1
  136. package/packages/pi-ai/src/providers/azure-openai-responses.ts +11 -45
  137. package/packages/pi-ai/src/providers/github-copilot-headers.ts +1 -1
  138. package/packages/pi-ai/src/providers/google-gemini-cli.ts +2 -2
  139. package/packages/pi-ai/src/providers/google-shared.ts +1 -1
  140. package/packages/pi-ai/src/providers/openai-completions.ts +16 -86
  141. package/packages/pi-ai/src/providers/openai-responses.ts +16 -96
  142. package/packages/pi-ai/src/providers/openai-shared.ts +193 -0
  143. package/packages/pi-ai/src/providers/register-builtins.ts +1 -1
  144. package/packages/pi-ai/src/utils/event-stream.ts +0 -5
  145. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +14 -162
  146. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +13 -161
  147. package/packages/pi-ai/src/utils/oauth/google-oauth-utils.ts +201 -0
  148. package/packages/pi-ai/src/utils/overflow.ts +1 -8
  149. package/packages/pi-ai/src/utils/validation.ts +0 -15
  150. package/packages/pi-coding-agent/dist/config.d.ts +0 -9
  151. package/packages/pi-coding-agent/dist/config.d.ts.map +1 -1
  152. package/packages/pi-coding-agent/dist/config.js +4 -8
  153. package/packages/pi-coding-agent/dist/config.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +16 -63
  155. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/core/agent-session.js +104 -641
  157. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +0 -1
  159. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/auth-storage.js +4 -35
  161. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js +5 -43
  164. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  165. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +11 -69
  167. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +40 -0
  169. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/compaction/utils.js +78 -0
  171. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +77 -0
  173. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -0
  174. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +331 -0
  175. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -0
  176. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts +0 -4
  177. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  178. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js +1 -1
  179. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js.map +1 -1
  180. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +2 -2
  181. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  182. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  183. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +15 -5
  185. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  186. package/packages/pi-coding-agent/dist/core/extensions/runner.js +129 -256
  187. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  188. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +49 -42
  189. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  190. package/packages/pi-coding-agent/dist/core/extensions/types.js +2 -21
  191. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  192. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +0 -8
  193. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  194. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -2
  195. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  196. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts +39 -0
  197. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts.map +1 -0
  198. package/packages/pi-coding-agent/dist/core/lock-utils.js +89 -0
  199. package/packages/pi-coding-agent/dist/core/lock-utils.js.map +1 -0
  200. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +0 -17
  201. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  202. package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -62
  203. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  204. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +1 -1
  205. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
  206. package/packages/pi-coding-agent/dist/core/lsp/config.js +2 -6
  207. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts +0 -5
  209. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/lsp/edits.js +1 -1
  211. package/packages/pi-coding-agent/dist/core/lsp/edits.js.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/lsp/index.js +52 -107
  214. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts +0 -1
  216. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  217. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -22
  218. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +0 -1
  220. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/lsp/types.js +0 -28
  222. package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +1 -6
  224. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/lsp/utils.js +1 -28
  226. package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -1
  227. package/packages/pi-coding-agent/dist/core/messages.d.ts +0 -8
  228. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  229. package/packages/pi-coding-agent/dist/core/messages.js +5 -5
  230. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  231. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -3
  232. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  233. package/packages/pi-coding-agent/dist/core/model-registry.js +1 -3
  234. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts +1 -26
  236. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -59
  238. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/package-manager.js +2 -4
  241. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts +0 -17
  243. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/prompt-templates.js +2 -2
  245. package/packages/pi-coding-agent/dist/core/prompt-templates.js.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +2 -4
  247. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/resource-loader.js +46 -60
  249. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +87 -0
  251. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -0
  252. package/packages/pi-coding-agent/dist/core/retry-handler.js +295 -0
  253. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -0
  254. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +0 -5
  255. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/session-manager.js +5 -32
  257. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +8 -12
  259. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/core/settings-manager.js +78 -168
  261. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/skills.js +1 -3
  264. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  266. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  267. package/packages/pi-coding-agent/dist/index.js +1 -1
  268. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/migrations.d.ts +0 -16
  270. package/packages/pi-coding-agent/dist/migrations.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/migrations.js +2 -2
  272. package/packages/pi-coding-agent/dist/migrations.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts +0 -2
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js +2 -2
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +1 -1
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +9 -26
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -13
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js +61 -0
  287. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +6 -9
  290. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -24
  292. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  293. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +50 -512
  294. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +71 -0
  296. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -0
  297. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +514 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -0
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +65 -4
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +6 -23
  302. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +12 -0
  304. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +175 -0
  306. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -0
  307. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
  308. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
  309. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js +15 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js.map +1 -0
  311. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/modes/print-mode.js +2 -30
  313. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  315. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -28
  316. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts +19 -0
  318. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts.map +1 -0
  319. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js +45 -0
  320. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js.map +1 -0
  321. package/packages/pi-coding-agent/dist/utils/changelog.d.ts +0 -4
  322. package/packages/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/utils/changelog.js +1 -1
  324. package/packages/pi-coding-agent/dist/utils/changelog.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts +0 -1
  326. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/utils/clipboard-image.js +1 -1
  328. package/packages/pi-coding-agent/dist/utils/clipboard-image.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/utils/error.d.ts +5 -0
  330. package/packages/pi-coding-agent/dist/utils/error.d.ts.map +1 -0
  331. package/packages/pi-coding-agent/dist/utils/error.js +7 -0
  332. package/packages/pi-coding-agent/dist/utils/error.js.map +1 -0
  333. package/packages/pi-coding-agent/dist/utils/photon.d.ts +0 -19
  334. package/packages/pi-coding-agent/dist/utils/photon.d.ts.map +1 -1
  335. package/packages/pi-coding-agent/dist/utils/photon.js +1 -120
  336. package/packages/pi-coding-agent/dist/utils/photon.js.map +1 -1
  337. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts +0 -1
  338. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts.map +1 -1
  339. package/packages/pi-coding-agent/dist/utils/tools-manager.js +1 -1
  340. package/packages/pi-coding-agent/dist/utils/tools-manager.js.map +1 -1
  341. package/packages/pi-coding-agent/package.json +1 -1
  342. package/packages/pi-coding-agent/src/config.ts +5 -10
  343. package/packages/pi-coding-agent/src/core/agent-session.ts +117 -745
  344. package/packages/pi-coding-agent/src/core/auth-storage.ts +4 -38
  345. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +7 -53
  346. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +14 -74
  347. package/packages/pi-coding-agent/src/core/compaction/utils.ts +100 -0
  348. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +424 -0
  349. package/packages/pi-coding-agent/src/core/export-html/ansi-to-html.ts +1 -1
  350. package/packages/pi-coding-agent/src/core/extensions/index.ts +1 -21
  351. package/packages/pi-coding-agent/src/core/extensions/runner.ts +119 -256
  352. package/packages/pi-coding-agent/src/core/extensions/types.ts +50 -69
  353. package/packages/pi-coding-agent/src/core/keybindings.ts +2 -2
  354. package/packages/pi-coding-agent/src/core/lock-utils.ts +113 -0
  355. package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -73
  356. package/packages/pi-coding-agent/src/core/lsp/config.ts +2 -10
  357. package/packages/pi-coding-agent/src/core/lsp/edits.ts +1 -1
  358. package/packages/pi-coding-agent/src/core/lsp/index.ts +83 -152
  359. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -23
  360. package/packages/pi-coding-agent/src/core/lsp/types.ts +0 -29
  361. package/packages/pi-coding-agent/src/core/lsp/utils.ts +1 -33
  362. package/packages/pi-coding-agent/src/core/messages.ts +5 -5
  363. package/packages/pi-coding-agent/src/core/model-registry.ts +0 -2
  364. package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -77
  365. package/packages/pi-coding-agent/src/core/package-manager.ts +1 -4
  366. package/packages/pi-coding-agent/src/core/prompt-templates.ts +2 -2
  367. package/packages/pi-coding-agent/src/core/resource-loader.ts +56 -69
  368. package/packages/pi-coding-agent/src/core/retry-handler.ts +359 -0
  369. package/packages/pi-coding-agent/src/core/session-manager.ts +5 -34
  370. package/packages/pi-coding-agent/src/core/settings-manager.ts +87 -166
  371. package/packages/pi-coding-agent/src/core/skills.ts +1 -4
  372. package/packages/pi-coding-agent/src/index.ts +1 -7
  373. package/packages/pi-coding-agent/src/migrations.ts +2 -2
  374. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector-search.ts +2 -2
  375. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +17 -29
  376. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -13
  377. package/packages/pi-coding-agent/src/modes/interactive/components/tree-render-utils.ts +81 -0
  378. package/packages/pi-coding-agent/src/modes/interactive/components/tree-selector.ts +14 -19
  379. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +50 -561
  380. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +653 -0
  381. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +7 -26
  382. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +196 -0
  383. package/packages/pi-coding-agent/src/modes/interactive/utils/shorten-path.ts +14 -0
  384. package/packages/pi-coding-agent/src/modes/print-mode.ts +2 -30
  385. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -28
  386. package/packages/pi-coding-agent/src/modes/shared/command-context-actions.ts +53 -0
  387. package/packages/pi-coding-agent/src/utils/changelog.ts +1 -1
  388. package/packages/pi-coding-agent/src/utils/clipboard-image.ts +1 -1
  389. package/packages/pi-coding-agent/src/utils/error.ts +6 -0
  390. package/packages/pi-coding-agent/src/utils/photon.ts +0 -137
  391. package/packages/pi-coding-agent/src/utils/tools-manager.ts +1 -1
  392. package/packages/pi-tui/dist/components/editor.d.ts +0 -10
  393. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  394. package/packages/pi-tui/dist/components/editor.js +1 -1
  395. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  396. package/packages/pi-tui/dist/components/markdown.d.ts +5 -0
  397. package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
  398. package/packages/pi-tui/dist/components/markdown.js +25 -31
  399. package/packages/pi-tui/dist/components/markdown.js.map +1 -1
  400. package/packages/pi-tui/dist/keys.d.ts +0 -4
  401. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/keys.js +94 -162
  403. package/packages/pi-tui/dist/keys.js.map +1 -1
  404. package/packages/pi-tui/dist/overlay-layout.d.ts +55 -0
  405. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -0
  406. package/packages/pi-tui/dist/overlay-layout.js +288 -0
  407. package/packages/pi-tui/dist/overlay-layout.js.map +1 -0
  408. package/packages/pi-tui/dist/tui.d.ts +0 -22
  409. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  410. package/packages/pi-tui/dist/tui.js +6 -272
  411. package/packages/pi-tui/dist/tui.js.map +1 -1
  412. package/packages/pi-tui/dist/utils.d.ts +0 -7
  413. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  414. package/packages/pi-tui/dist/utils.js +0 -44
  415. package/packages/pi-tui/dist/utils.js.map +1 -1
  416. package/packages/pi-tui/src/components/editor.ts +1 -1
  417. package/packages/pi-tui/src/components/markdown.ts +25 -29
  418. package/packages/pi-tui/src/keys.ts +94 -173
  419. package/packages/pi-tui/src/overlay-layout.ts +372 -0
  420. package/packages/pi-tui/src/tui.ts +11 -312
  421. package/packages/pi-tui/src/utils.ts +0 -43
  422. package/pkg/dist/core/export-html/ansi-to-html.d.ts +0 -4
  423. package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  424. package/pkg/dist/core/export-html/ansi-to-html.js +1 -1
  425. package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -1
  426. package/pkg/dist/modes/interactive/theme/theme.d.ts +65 -4
  427. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  428. package/pkg/dist/modes/interactive/theme/theme.js +6 -23
  429. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  430. package/pkg/dist/modes/interactive/theme/themes.d.ts +12 -0
  431. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  432. package/pkg/dist/modes/interactive/theme/themes.js +175 -0
  433. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -0
  434. package/pkg/package.json +1 -1
  435. package/src/resources/extensions/async-jobs/await-tool.ts +0 -2
  436. package/src/resources/extensions/async-jobs/job-manager.ts +0 -7
  437. package/src/resources/extensions/bg-shell/output-formatter.ts +0 -17
  438. package/src/resources/extensions/bg-shell/process-manager.ts +0 -4
  439. package/src/resources/extensions/bg-shell/types.ts +0 -12
  440. package/src/resources/extensions/context7/index.ts +7 -0
  441. package/src/resources/extensions/get-secrets-from-user.ts +2 -35
  442. package/src/resources/extensions/google-search/index.ts +7 -0
  443. package/src/resources/extensions/gsd/auto-dispatch.ts +49 -1
  444. package/src/resources/extensions/gsd/auto-loop.ts +22 -2
  445. package/src/resources/extensions/gsd/auto-model-selection.ts +23 -2
  446. package/src/resources/extensions/gsd/auto-recovery.ts +39 -0
  447. package/src/resources/extensions/gsd/auto-start.ts +42 -2
  448. package/src/resources/extensions/gsd/auto.ts +61 -3
  449. package/src/resources/extensions/gsd/changelog.ts +213 -0
  450. package/src/resources/extensions/gsd/commands-bootstrap.ts +1 -0
  451. package/src/resources/extensions/gsd/commands-handlers.ts +2 -2
  452. package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
  453. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +5 -1
  454. package/src/resources/extensions/gsd/commands-rate.ts +55 -0
  455. package/src/resources/extensions/gsd/commands.ts +52 -2
  456. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  457. package/src/resources/extensions/gsd/doctor-checks.ts +107 -5
  458. package/src/resources/extensions/gsd/doctor-environment.ts +26 -16
  459. package/src/resources/extensions/gsd/doctor-proactive.ts +24 -0
  460. package/src/resources/extensions/gsd/doctor-types.ts +9 -1
  461. package/src/resources/extensions/gsd/doctor.ts +35 -0
  462. package/src/resources/extensions/gsd/files.ts +12 -2
  463. package/src/resources/extensions/gsd/gitignore.ts +54 -7
  464. package/src/resources/extensions/gsd/guided-flow.ts +12 -4
  465. package/src/resources/extensions/gsd/health-widget-core.ts +129 -0
  466. package/src/resources/extensions/gsd/health-widget.ts +103 -59
  467. package/src/resources/extensions/gsd/index.ts +30 -33
  468. package/src/resources/extensions/gsd/migrate-external.ts +47 -2
  469. package/src/resources/extensions/gsd/milestone-ids.ts +3 -2
  470. package/src/resources/extensions/gsd/paths.ts +73 -7
  471. package/src/resources/extensions/gsd/post-unit-hooks.ts +5 -1
  472. package/src/resources/extensions/gsd/preferences-validation.ts +54 -1
  473. package/src/resources/extensions/gsd/preferences.ts +16 -1
  474. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  475. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  476. package/src/resources/extensions/gsd/roadmap-mutations.ts +66 -0
  477. package/src/resources/extensions/gsd/session-lock.ts +59 -2
  478. package/src/resources/extensions/gsd/state.ts +2 -1
  479. package/src/resources/extensions/gsd/templates/plan.md +8 -0
  480. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
  481. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +98 -2
  482. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +59 -3
  483. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +20 -0
  484. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +214 -0
  485. package/src/resources/extensions/gsd/tests/health-widget.test.ts +158 -0
  486. package/src/resources/extensions/gsd/tests/paths.test.ts +113 -0
  487. package/src/resources/extensions/gsd/tests/preferences.test.ts +40 -2
  488. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +26 -0
  489. package/src/resources/extensions/gsd/tests/test-utils.ts +165 -0
  490. package/src/resources/extensions/gsd/tests/validate-directory.test.ts +15 -0
  491. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +7 -0
  492. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +32 -0
  493. package/src/resources/extensions/gsd/worktree-resolver.ts +11 -0
  494. package/src/resources/extensions/mcp-client/index.ts +2 -1
  495. package/src/resources/extensions/remote-questions/remote-command.ts +2 -23
  496. package/src/resources/extensions/shared/mod.ts +1 -1
  497. package/src/resources/extensions/shared/sanitize.ts +36 -0
  498. package/src/resources/extensions/subagent/index.ts +6 -12
  499. package/src/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  500. package/dist/resources/extensions/shared/wizard-ui.js +0 -478
  501. package/packages/pi-coding-agent/dist/modes/interactive/theme/dark.json +0 -85
  502. package/packages/pi-coding-agent/dist/modes/interactive/theme/light.json +0 -84
  503. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.json +0 -335
  504. package/packages/pi-coding-agent/src/modes/interactive/theme/dark.json +0 -85
  505. package/packages/pi-coding-agent/src/modes/interactive/theme/light.json +0 -84
  506. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
  507. package/pkg/dist/modes/interactive/theme/dark.json +0 -85
  508. package/pkg/dist/modes/interactive/theme/light.json +0 -84
  509. package/pkg/dist/modes/interactive/theme/theme-schema.json +0 -335
  510. package/src/resources/extensions/shared/wizard-ui.ts +0 -551
@@ -0,0 +1,162 @@
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
+ // ─── Semver comparison ────────────────────────────────────────────────────────
11
+ function compareSemver(a, b) {
12
+ const pa = a.split(".").map(Number);
13
+ const pb = b.split(".").map(Number);
14
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
15
+ const va = pa[i] || 0;
16
+ const vb = pb[i] || 0;
17
+ if (va > vb)
18
+ return 1;
19
+ if (va < vb)
20
+ return -1;
21
+ }
22
+ return 0;
23
+ }
24
+ function stripV(tag) {
25
+ return tag.startsWith("v") ? tag.slice(1) : tag;
26
+ }
27
+ function parseReleaseBody(body) {
28
+ if (!body)
29
+ return [];
30
+ const sections = [];
31
+ const lines = body.split("\n");
32
+ let currentHeading = null;
33
+ let currentLines = [];
34
+ for (const line of lines) {
35
+ if (line.startsWith("### ")) {
36
+ if (currentHeading !== null) {
37
+ const content = currentLines.join("\n").trim();
38
+ if (content) {
39
+ sections.push({ heading: currentHeading, content });
40
+ }
41
+ }
42
+ currentHeading = line.slice(4).trim();
43
+ currentLines = [];
44
+ }
45
+ else if (currentHeading !== null) {
46
+ currentLines.push(line);
47
+ }
48
+ }
49
+ if (currentHeading !== null) {
50
+ const content = currentLines.join("\n").trim();
51
+ if (content) {
52
+ sections.push({ heading: currentHeading, content });
53
+ }
54
+ }
55
+ return sections;
56
+ }
57
+ // ─── Display formatting ──────────────────────────────────────────────────────
58
+ function formatRelease(release) {
59
+ const version = stripV(release.tag_name);
60
+ const title = release.name || `v${version}`;
61
+ const sections = parseReleaseBody(release.body);
62
+ const parts = [`## ${title}`];
63
+ if (sections.length === 0) {
64
+ if (release.body?.trim()) {
65
+ parts.push(release.body.trim());
66
+ }
67
+ else {
68
+ parts.push("_No release notes._");
69
+ }
70
+ }
71
+ else {
72
+ for (const section of sections) {
73
+ parts.push(`### ${section.heading}`);
74
+ parts.push(section.content);
75
+ }
76
+ }
77
+ return parts.join("\n\n");
78
+ }
79
+ // ─── Entry Point ──────────────────────────────────────────────────────────────
80
+ const RELEASES_URL = "https://api.github.com/repos/gsd-build/gsd-2/releases?per_page=100";
81
+ export async function handleChangelog(args, ctx, pi) {
82
+ // ── Fetch releases ──────────────────────────────────────────────────────
83
+ let releases;
84
+ try {
85
+ const response = await fetch(RELEASES_URL, {
86
+ headers: { "User-Agent": "gsd-changelog" },
87
+ });
88
+ if (!response.ok) {
89
+ ctx.ui.notify(`Failed to fetch changelog: GitHub API returned ${response.status} ${response.statusText}`, "error");
90
+ return;
91
+ }
92
+ releases = (await response.json());
93
+ }
94
+ catch (err) {
95
+ const message = err instanceof Error ? err.message : String(err);
96
+ ctx.ui.notify(`Failed to fetch changelog: ${message}`, "error");
97
+ return;
98
+ }
99
+ if (!releases.length) {
100
+ ctx.ui.notify("No releases found in the repository.", "warning");
101
+ return;
102
+ }
103
+ // ── Determine version filter ────────────────────────────────────────────
104
+ const currentVersion = process.env.GSD_VERSION || "";
105
+ let sinceVersion;
106
+ let showCurrentOnly = false;
107
+ if (args.trim()) {
108
+ sinceVersion = stripV(args.trim());
109
+ }
110
+ else {
111
+ const input = await ctx.ui.input("Show changes since version:", currentVersion || "latest");
112
+ if (input === undefined) {
113
+ return;
114
+ }
115
+ if (input.trim() === "") {
116
+ showCurrentOnly = true;
117
+ }
118
+ else {
119
+ sinceVersion = stripV(input.trim());
120
+ }
121
+ }
122
+ // ── Filter releases ─────────────────────────────────────────────────────
123
+ let matched;
124
+ if (showCurrentOnly) {
125
+ if (!currentVersion) {
126
+ ctx.ui.notify("GSD_VERSION is not set — cannot determine current release. Provide a version instead.", "warning");
127
+ return;
128
+ }
129
+ const found = releases.find((r) => stripV(r.tag_name) === currentVersion);
130
+ if (!found) {
131
+ ctx.ui.notify(`No release found matching current version v${currentVersion}`, "warning");
132
+ return;
133
+ }
134
+ matched = [found];
135
+ }
136
+ else if (sinceVersion) {
137
+ matched = releases
138
+ .filter((r) => compareSemver(stripV(r.tag_name), sinceVersion) > 0)
139
+ .sort((a, b) => compareSemver(stripV(b.tag_name), stripV(a.tag_name)));
140
+ if (!matched.length) {
141
+ ctx.ui.notify(`No releases found since v${sinceVersion}`, "warning");
142
+ return;
143
+ }
144
+ }
145
+ else {
146
+ matched = [releases[0]];
147
+ }
148
+ // ── Send to LLM for summarization ───────────────────────────────────────
149
+ const rawOutput = matched.map(formatRelease).join("\n\n---\n\n");
150
+ const versionRange = sinceVersion
151
+ ? `since v${sinceVersion} (${matched.length} release${matched.length === 1 ? "" : "s"})`
152
+ : `for current release ${matched[0].name || matched[0].tag_name}`;
153
+ const prompt = [
154
+ `Here are the raw GSD changelog entries ${versionRange}.`,
155
+ "Summarize the most important changes — group by category (Added, Changed, Fixed, etc.),",
156
+ "keep only the most impactful items (max 5 per category), skip trivial changes,",
157
+ "and include the version where each item appeared. Keep it concise and scannable.",
158
+ "",
159
+ rawOutput,
160
+ ].join("\n");
161
+ pi.sendMessage({ customType: "gsd-changelog", content: prompt, display: true }, { triggerTurn: true });
162
+ }
@@ -11,6 +11,7 @@ const TOP_LEVEL_SUBCOMMANDS = [
11
11
  { cmd: "quick", desc: "Execute a quick task without full planning overhead" },
12
12
  { cmd: "discuss", desc: "Discuss architecture and decisions" },
13
13
  { cmd: "capture", desc: "Fire-and-forget thought capture" },
14
+ { cmd: "changelog", desc: "Show categorized release notes" },
14
15
  { cmd: "triage", desc: "Manually trigger triage of pending captures" },
15
16
  { cmd: "dispatch", desc: "Dispatch a specific phase directly" },
16
17
  { cmd: "history", desc: "View execution history" },
@@ -15,7 +15,7 @@ import { isAutoActive } from "./auto.js";
15
15
  import { projectRoot } from "./commands.js";
16
16
  import { loadPrompt } from "./prompt-loader.js";
17
17
  export function dispatchDoctorHeal(pi, scope, reportText, structuredIssues) {
18
- const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".pi", "GSD-WORKFLOW.md");
18
+ const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".gsd", "agent", "GSD-WORKFLOW.md");
19
19
  const workflow = readFileSync(workflowPath, "utf-8");
20
20
  const prompt = loadPrompt("doctor-heal", {
21
21
  doctorSummary: reportText,
@@ -144,7 +144,7 @@ export async function handleTriage(ctx, pi, basePath) {
144
144
  currentPlan: currentPlan || "(no active slice plan)",
145
145
  roadmapContext: roadmapContext || "(no active roadmap)",
146
146
  });
147
- const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".pi", "GSD-WORKFLOW.md");
147
+ const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".gsd", "agent", "GSD-WORKFLOW.md");
148
148
  const workflow = readFileSync(workflowPath, "utf-8");
149
149
  pi.sendMessage({
150
150
  customType: "gsd-triage",
@@ -3,6 +3,9 @@
3
3
  *
4
4
  * Contains: InspectData type, formatInspectOutput, handleInspect
5
5
  */
6
+ import { existsSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { gsdRoot } from "./paths.js";
6
9
  import { getErrorMessage } from "./error-utils.js";
7
10
  export function formatInspectOutput(data) {
8
11
  const lines = [];
@@ -30,10 +33,14 @@ export function formatInspectOutput(data) {
30
33
  }
31
34
  export async function handleInspect(ctx) {
32
35
  try {
33
- const { isDbAvailable, _getAdapter } = await import("./gsd-db.js");
36
+ const { isDbAvailable, _getAdapter, openDatabase } = await import("./gsd-db.js");
34
37
  if (!isDbAvailable()) {
35
- ctx.ui.notify("No GSD database available. Run /gsd auto to create one.", "info");
36
- return;
38
+ const gsdDir = gsdRoot(process.cwd());
39
+ const dbPath = join(gsdDir, "gsd.db");
40
+ if (!existsSync(gsdDir) || !existsSync(dbPath) || !openDatabase(dbPath)) {
41
+ ctx.ui.notify("No GSD database available. Run /gsd auto to create one.", "info");
42
+ return;
43
+ }
37
44
  }
38
45
  const adapter = _getAdapter();
39
46
  if (!adapter) {
@@ -624,10 +624,14 @@ export function serializePreferencesToFrontmatter(prefs) {
624
624
  const orderedKeys = [
625
625
  "version", "mode", "always_use_skills", "prefer_skills", "avoid_skills",
626
626
  "skill_rules", "custom_instructions", "models", "skill_discovery",
627
- "auto_supervisor", "uat_dispatch", "unique_milestone_ids",
627
+ "skill_staleness_days", "auto_supervisor", "uat_dispatch", "unique_milestone_ids",
628
628
  "budget_ceiling", "budget_enforcement", "context_pause_threshold",
629
629
  "notifications", "remote_questions", "git",
630
630
  "post_unit_hooks", "pre_dispatch_hooks",
631
+ "dynamic_routing", "token_profile", "phases", "parallel",
632
+ "auto_visualize", "auto_report",
633
+ "verification_commands", "verification_auto_fix", "verification_max_retries",
634
+ "search_provider", "compression_strategy", "context_selection",
631
635
  ];
632
636
  const seen = new Set();
633
637
  for (const key of orderedKeys) {
@@ -0,0 +1,31 @@
1
+ /**
2
+ * /gsd rate — Submit feedback on the last unit's model tier assignment.
3
+ * Feeds into the adaptive routing history so future dispatches improve.
4
+ */
5
+ import { loadLedgerFromDisk } from "./metrics.js";
6
+ import { recordFeedback, initRoutingHistory } from "./routing-history.js";
7
+ const VALID_RATINGS = new Set(["over", "under", "ok"]);
8
+ export async function handleRate(args, ctx, basePath) {
9
+ const rating = args.trim().toLowerCase();
10
+ if (!rating || !VALID_RATINGS.has(rating)) {
11
+ ctx.ui.notify("Usage: /gsd rate <over|ok|under>\n" +
12
+ " over — model was overpowered for that task (encourage cheaper)\n" +
13
+ " ok — model was appropriate\n" +
14
+ " under — model was too weak (encourage stronger)", "info");
15
+ return;
16
+ }
17
+ const ledger = loadLedgerFromDisk(basePath);
18
+ if (!ledger || ledger.units.length === 0) {
19
+ ctx.ui.notify("No completed units found — nothing to rate.", "warning");
20
+ return;
21
+ }
22
+ const lastUnit = ledger.units[ledger.units.length - 1];
23
+ const tier = lastUnit.tier;
24
+ if (!tier) {
25
+ ctx.ui.notify("Last unit has no tier data (dynamic routing was not active). Rating skipped.", "warning");
26
+ return;
27
+ }
28
+ initRoutingHistory(basePath);
29
+ recordFeedback(lastUnit.type, lastUnit.id, tier, rating);
30
+ ctx.ui.notify(`Recorded "${rating}" for ${lastUnit.type}/${lastUnit.id} at tier ${tier}.`, "info");
31
+ }
@@ -36,6 +36,7 @@ import { computeProgressScore, formatProgressLine } from "./progress-score.js";
36
36
  import { runEnvironmentChecks } from "./doctor-environment.js";
37
37
  import { handleLogs } from "./commands-logs.js";
38
38
  import { handleStart, handleTemplates, getTemplateCompletions } from "./commands-workflow-templates.js";
39
+ import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.js";
39
40
  /** Resolve the effective project root, accounting for worktree paths. */
40
41
  export function projectRoot() {
41
42
  const cwd = process.cwd();
@@ -54,9 +55,41 @@ export function projectRoot() {
54
55
  }
55
56
  return root;
56
57
  }
58
+ /**
59
+ * Check if another process holds the auto-mode session lock.
60
+ * Returns the lock data if a remote session is alive, null otherwise.
61
+ */
62
+ function getRemoteAutoSession(basePath) {
63
+ const lockData = readSessionLockData(basePath);
64
+ if (!lockData)
65
+ return null;
66
+ if (lockData.pid === process.pid)
67
+ return null;
68
+ if (!isSessionLockProcessAlive(lockData))
69
+ return null;
70
+ return { pid: lockData.pid };
71
+ }
72
+ /**
73
+ * Show a steering menu when auto-mode is running in another process.
74
+ * Returns true if a remote session was detected (caller should return early).
75
+ */
76
+ function notifyRemoteAutoActive(ctx, basePath) {
77
+ const remote = getRemoteAutoSession(basePath);
78
+ if (!remote)
79
+ return false;
80
+ ctx.ui.notify(`Auto-mode is running in another process (PID ${remote.pid}).\n` +
81
+ `Use these commands to interact with it:\n` +
82
+ ` /gsd status — check progress\n` +
83
+ ` /gsd discuss — discuss architecture decisions\n` +
84
+ ` /gsd queue — queue the next milestone\n` +
85
+ ` /gsd steer — apply an override to active work\n` +
86
+ ` /gsd capture — fire-and-forget thought\n` +
87
+ ` /gsd stop — stop auto-mode`, "warning");
88
+ return true;
89
+ }
57
90
  export function registerGSDCommand(pi) {
58
91
  pi.registerCommand("gsd", {
59
- 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",
92
+ 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",
60
93
  getArgumentCompletions: (prefix) => {
61
94
  const subcommands = [
62
95
  { cmd: "help", desc: "Categorized command reference with descriptions" },
@@ -70,9 +103,11 @@ export function registerGSDCommand(pi) {
70
103
  { cmd: "quick", desc: "Execute a quick task without full planning overhead" },
71
104
  { cmd: "discuss", desc: "Discuss architecture and decisions" },
72
105
  { cmd: "capture", desc: "Fire-and-forget thought capture" },
106
+ { cmd: "changelog", desc: "Show categorized release notes" },
73
107
  { cmd: "triage", desc: "Manually trigger triage of pending captures" },
74
108
  { cmd: "dispatch", desc: "Dispatch a specific phase directly" },
75
109
  { cmd: "history", desc: "View execution history" },
110
+ { cmd: "rate", desc: "Rate last unit's model tier (over/ok/under) — improves adaptive routing" },
76
111
  { cmd: "undo", desc: "Revert last completed unit" },
77
112
  { cmd: "skip", desc: "Prevent a unit from auto-mode dispatch" },
78
113
  { cmd: "export", desc: "Export milestone/slice results" },
@@ -448,11 +483,18 @@ export async function handleGSDCommand(args, ctx, pi) {
448
483
  await handleForensics(trimmed.replace(/^forensics\s*/, "").trim(), ctx, pi);
449
484
  return;
450
485
  }
486
+ if (trimmed === "changelog" || trimmed.startsWith("changelog ")) {
487
+ const { handleChangelog } = await import("./changelog.js");
488
+ await handleChangelog(trimmed.replace(/^changelog\s*/, "").trim(), ctx, pi);
489
+ return;
490
+ }
451
491
  if (trimmed === "next" || trimmed.startsWith("next ")) {
452
492
  if (trimmed.includes("--dry-run")) {
453
493
  await handleDryRun(ctx, projectRoot());
454
494
  return;
455
495
  }
496
+ if (notifyRemoteAutoActive(ctx, projectRoot()))
497
+ return;
456
498
  const verboseMode = trimmed.includes("--verbose");
457
499
  const debugMode = trimmed.includes("--debug");
458
500
  if (debugMode)
@@ -507,6 +549,11 @@ export async function handleGSDCommand(args, ctx, pi) {
507
549
  await handleUndo(trimmed.replace(/^undo\s*/, "").trim(), ctx, pi, projectRoot());
508
550
  return;
509
551
  }
552
+ if (trimmed === "rate" || trimmed.startsWith("rate ")) {
553
+ const { handleRate } = await import("./commands-rate.js");
554
+ await handleRate(trimmed.replace(/^rate\s*/, "").trim(), ctx, projectRoot());
555
+ return;
556
+ }
510
557
  if (trimmed.startsWith("skip ")) {
511
558
  await handleSkip(trimmed.replace(/^skip\s*/, "").trim(), ctx, projectRoot());
512
559
  return;
@@ -803,7 +850,8 @@ Examples:
803
850
  return;
804
851
  }
805
852
  if (trimmed === "") {
806
- // Bare /gsd defaults to step mode
853
+ if (notifyRemoteAutoActive(ctx, projectRoot()))
854
+ return;
807
855
  await startAuto(ctx, pi, projectRoot(), false, { step: true });
808
856
  return;
809
857
  }
@@ -833,6 +881,7 @@ function showHelp(ctx) {
833
881
  " /gsd visualize Interactive 10-tab TUI (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)",
834
882
  " /gsd queue Show queued/dispatched units and execution order",
835
883
  " /gsd history View execution history [--cost] [--phase] [--model] [N]",
884
+ " /gsd changelog Show categorized release notes [version]",
836
885
  "",
837
886
  "COURSE CORRECTION",
838
887
  " /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,13 +1,13 @@
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
  import { loadFile, parseRoadmap } from "./files.js";
4
4
  import { resolveMilestoneFile, milestonesDir, gsdRoot, resolveGsdRootFile } from "./paths.js";
5
5
  import { deriveState, isMilestoneComplete } from "./state.js";
6
6
  import { saveFile } from "./files.js";
7
- import { listWorktrees, resolveGitDir } from "./worktree-manager.js";
7
+ import { listWorktrees, resolveGitDir, worktreesDir } from "./worktree-manager.js";
8
8
  import { abortAndReset } from "./git-self-heal.js";
9
- import { RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
10
- import { nativeIsRepo, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached } from "./native-git-bridge.js";
9
+ import { RUNTIME_EXCLUSION_PATHS, readIntegrationBranch } from "./git-service.js";
10
+ import { nativeIsRepo, nativeBranchExists, nativeWorktreeList, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached } from "./native-git-bridge.js";
11
11
  import { readCrashLock, isLockProcessAlive, clearLock } from "./crash-recovery.js";
12
12
  import { ensureGitignore } from "./gitignore.js";
13
13
  import { readAllSessionStatuses, isSessionStale, removeSessionStatus } from "./session-status-io.js";
@@ -200,6 +200,75 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
200
200
  catch {
201
201
  // git branch list failed — skip
202
202
  }
203
+ // ── Integration branch existence ──────────────────────────────────────
204
+ // For each active (non-complete) milestone, verify the stored integration
205
+ // branch still exists in git. A missing integration branch blocks merge-back
206
+ // and causes the next merge operation to fail silently.
207
+ try {
208
+ const state = await deriveState(basePath);
209
+ for (const milestone of state.registry) {
210
+ if (milestone.status === "complete")
211
+ continue;
212
+ const integrationBranch = readIntegrationBranch(basePath, milestone.id);
213
+ if (!integrationBranch)
214
+ continue; // No stored branch — skip (not yet set)
215
+ if (!nativeBranchExists(basePath, integrationBranch)) {
216
+ issues.push({
217
+ severity: "error",
218
+ code: "integration_branch_missing",
219
+ scope: "milestone",
220
+ unitId: milestone.id,
221
+ message: `Milestone ${milestone.id} recorded integration branch "${integrationBranch}" but that branch no longer exists in git. Merge-back will fail.`,
222
+ fixable: false,
223
+ });
224
+ }
225
+ }
226
+ }
227
+ catch {
228
+ // Non-fatal — integration branch check failed
229
+ }
230
+ // ── Orphaned worktree directories ────────────────────────────────────
231
+ // Worktree removal can fail after a branch delete, leaving a directory
232
+ // that is no longer registered with git. These orphaned dirs cause
233
+ // "already exists" errors when re-creating the same worktree name.
234
+ try {
235
+ const wtDir = worktreesDir(basePath);
236
+ if (existsSync(wtDir)) {
237
+ const registeredPaths = new Set(nativeWorktreeList(basePath).map(entry => entry.path));
238
+ for (const entry of readdirSync(wtDir)) {
239
+ const fullPath = join(wtDir, entry);
240
+ try {
241
+ if (!statSync(fullPath).isDirectory())
242
+ continue;
243
+ }
244
+ catch {
245
+ continue;
246
+ }
247
+ if (!registeredPaths.has(fullPath)) {
248
+ issues.push({
249
+ severity: "warning",
250
+ code: "worktree_directory_orphaned",
251
+ scope: "project",
252
+ unitId: entry,
253
+ message: `Worktree directory ${fullPath} exists on disk but is not registered with git. Run "git worktree prune" or doctor --fix to remove it.`,
254
+ fixable: true,
255
+ });
256
+ if (shouldFix("worktree_directory_orphaned")) {
257
+ try {
258
+ rmSync(fullPath, { recursive: true, force: true });
259
+ fixesApplied.push(`removed orphaned worktree directory ${fullPath}`);
260
+ }
261
+ catch {
262
+ fixesApplied.push(`failed to remove orphaned worktree directory ${fullPath}`);
263
+ }
264
+ }
265
+ }
266
+ }
267
+ }
268
+ }
269
+ catch {
270
+ // Non-fatal — orphaned worktree directory check failed
271
+ }
203
272
  }
204
273
  // ── Runtime Health Checks ──────────────────────────────────────────────────
205
274
  // Checks for stale crash locks, orphaned completed-units, stale hook state,
@@ -231,6 +300,45 @@ export async function checkRuntimeHealth(basePath, issues, fixesApplied, shouldF
231
300
  catch {
232
301
  // Non-fatal — crash lock check failed
233
302
  }
303
+ // ── Stranded lock directory ────────────────────────────────────────────
304
+ // proper-lockfile creates a `.gsd.lock/` directory as the OS-level lock
305
+ // mechanism. If the process was SIGKILLed or crashed hard, this directory
306
+ // can remain on disk without any live process holding it. The next session
307
+ // fails to acquire the lock until the directory is removed (#1245).
308
+ try {
309
+ const lockDir = join(dirname(root), `${basename(root)}.lock`);
310
+ if (existsSync(lockDir)) {
311
+ const statRes = statSync(lockDir);
312
+ if (statRes.isDirectory()) {
313
+ // Check if any live process actually holds this lock
314
+ const lock = readCrashLock(basePath);
315
+ const lockHolderAlive = lock ? isLockProcessAlive(lock) : false;
316
+ if (!lockHolderAlive) {
317
+ issues.push({
318
+ severity: "error",
319
+ code: "stranded_lock_directory",
320
+ scope: "project",
321
+ unitId: "project",
322
+ message: `Stranded lock directory "${lockDir}" exists but no live process holds the session lock. This blocks new auto-mode sessions from starting.`,
323
+ file: lockDir,
324
+ fixable: true,
325
+ });
326
+ if (shouldFix("stranded_lock_directory")) {
327
+ try {
328
+ rmSync(lockDir, { recursive: true, force: true });
329
+ fixesApplied.push(`removed stranded lock directory ${lockDir}`);
330
+ }
331
+ catch {
332
+ fixesApplied.push(`failed to remove stranded lock directory ${lockDir}`);
333
+ }
334
+ }
335
+ }
336
+ }
337
+ }
338
+ }
339
+ catch {
340
+ // Non-fatal — stranded lock directory check failed
341
+ }
234
342
  // ── Stale parallel sessions ────────────────────────────────────────────
235
343
  try {
236
344
  const parallelStatuses = readAllSessionStatuses(basePath);
@@ -148,27 +148,36 @@ function checkPortConflicts(basePath) {
148
148
  // Try to detect ports from package.json scripts
149
149
  const portsToCheck = new Set();
150
150
  const pkgPath = join(basePath, "package.json");
151
- if (existsSync(pkgPath)) {
152
- try {
153
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
154
- const scripts = pkg.scripts ?? {};
155
- const scriptText = Object.values(scripts).join(" ");
156
- // Look for --port NNNN, -p NNNN, PORT=NNNN, :NNNN patterns
157
- const portMatches = scriptText.matchAll(/(?:--port\s+|(?:^|[^a-z])PORT[=:]\s*|-p\s+|:)(\d{4,5})\b/gi);
158
- for (const m of portMatches) {
159
- const port = parseInt(m[1], 10);
160
- if (port >= 1024 && port <= 65535)
161
- portsToCheck.add(port);
162
- }
163
- }
164
- catch {
165
- // parse failed use defaults
151
+ if (!existsSync(pkgPath)) {
152
+ // No package.json — this isn't a Node.js project. Skip port checks
153
+ // entirely to avoid false positives from system services (e.g., macOS
154
+ // AirPlay Receiver on port 5000). (#1381)
155
+ return [];
156
+ }
157
+ try {
158
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
159
+ const scripts = pkg.scripts ?? {};
160
+ const scriptText = Object.values(scripts).join(" ");
161
+ // Look for --port NNNN, -p NNNN, PORT=NNNN, :NNNN patterns
162
+ const portMatches = scriptText.matchAll(/(?:--port\s+|(?:^|[^a-z])PORT[=:]\s*|-p\s+|:)(\d{4,5})\b/gi);
163
+ for (const m of portMatches) {
164
+ const port = parseInt(m[1], 10);
165
+ if (port >= 1024 && port <= 65535)
166
+ portsToCheck.add(port);
166
167
  }
167
168
  }
168
- // If no ports found in scripts, check common defaults
169
+ catch {
170
+ // parse failed — skip port checks rather than using defaults
171
+ return [];
172
+ }
173
+ // If no ports found in scripts, check common defaults.
174
+ // Filter out port 5000 on macOS — AirPlay Receiver uses it by default (#1381).
169
175
  if (portsToCheck.size === 0) {
170
- for (const p of DEFAULT_DEV_PORTS)
176
+ for (const p of DEFAULT_DEV_PORTS) {
177
+ if (p === 5000 && process.platform === "darwin")
178
+ continue;
171
179
  portsToCheck.add(p);
180
+ }
172
181
  }
173
182
  for (const port of portsToCheck) {
174
183
  const result = tryExec(`lsof -i :${port} -sTCP:LISTEN -t`, basePath);
@@ -19,6 +19,9 @@ import { gsdRoot, resolveGsdRootFile } from "./paths.js";
19
19
  import { readCrashLock, isLockProcessAlive, clearLock } from "./crash-recovery.js";
20
20
  import { abortAndReset } from "./git-self-heal.js";
21
21
  import { rebuildState } from "./doctor.js";
22
+ import { deriveState } from "./state.js";
23
+ import { readIntegrationBranch } from "./git-service.js";
24
+ import { nativeBranchExists, nativeIsRepo } from "./native-git-bridge.js";
22
25
  /** In-memory health history for the current auto-mode session. */
23
26
  let healthHistory = [];
24
27
  /** Count of consecutive units with unresolved errors. */
@@ -156,6 +159,25 @@ export async function preDispatchHealthGate(basePath) {
156
159
  catch {
157
160
  // Non-fatal — dispatch continues without STATE.md if rebuild fails
158
161
  }
162
+ // ── Integration branch existence check ──
163
+ // If the active milestone's recorded integration branch no longer exists in
164
+ // git, the merge-back at the end of the milestone will fail. Block dispatch
165
+ // now to surface this before work is lost.
166
+ try {
167
+ if (nativeIsRepo(basePath)) {
168
+ const state = await deriveState(basePath);
169
+ if (state.activeMilestone) {
170
+ const integrationBranch = readIntegrationBranch(basePath, state.activeMilestone.id);
171
+ if (integrationBranch && !nativeBranchExists(basePath, integrationBranch)) {
172
+ issues.push(`Integration branch "${integrationBranch}" for milestone ${state.activeMilestone.id} no longer exists in git. ` +
173
+ `Restore the branch or update the integration branch before dispatching. Run /gsd doctor for details.`);
174
+ }
175
+ }
176
+ }
177
+ }
178
+ catch {
179
+ // Non-fatal — dispatch continues if state/branch check fails
180
+ }
159
181
  // If we had critical issues that couldn't be auto-healed, block dispatch
160
182
  if (issues.length > 0) {
161
183
  return {