gsd-pi 2.76.0-dev.fe143342a → 2.77.0-dev.1d17f366c

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 (597) hide show
  1. package/README.md +17 -35
  2. package/dist/claude-cli-check.js +32 -3
  3. package/dist/cli-web-branch.d.ts +1 -0
  4. package/dist/cli-web-branch.js +3 -0
  5. package/dist/cli.js +38 -2
  6. package/dist/extension-discovery.d.ts +6 -0
  7. package/dist/extension-discovery.js +37 -0
  8. package/dist/extension-registry.d.ts +3 -0
  9. package/dist/extension-sort.d.ts +18 -0
  10. package/dist/extension-sort.js +114 -0
  11. package/dist/extension-validator.d.ts +47 -0
  12. package/dist/extension-validator.js +127 -0
  13. package/dist/loader.js +35 -7
  14. package/dist/onboarding.js +45 -0
  15. package/dist/provider-migrations.d.ts +18 -0
  16. package/dist/provider-migrations.js +14 -0
  17. package/dist/resources/extensions/claude-code-cli/readiness.js +4 -3
  18. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +78 -59
  19. package/dist/resources/extensions/cmux/index.js +20 -0
  20. package/dist/resources/extensions/github-sync/templates.js +103 -0
  21. package/dist/resources/extensions/google-search/extension-manifest.json +5 -4
  22. package/dist/resources/extensions/google-search/index.js +3 -375
  23. package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
  24. package/dist/resources/extensions/gsd/auto/loop.js +90 -2
  25. package/dist/resources/extensions/gsd/auto/phases.js +95 -21
  26. package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
  27. package/dist/resources/extensions/gsd/auto/run-unit.js +48 -4
  28. package/dist/resources/extensions/gsd/auto/session.js +18 -1
  29. package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
  30. package/dist/resources/extensions/gsd/auto-dispatch.js +115 -17
  31. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  32. package/dist/resources/extensions/gsd/auto-model-selection.js +1 -1
  33. package/dist/resources/extensions/gsd/auto-post-unit.js +90 -2
  34. package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
  35. package/dist/resources/extensions/gsd/auto-recovery.js +46 -1
  36. package/dist/resources/extensions/gsd/auto-start.js +45 -39
  37. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
  38. package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
  39. package/dist/resources/extensions/gsd/auto-worktree.js +109 -61
  40. package/dist/resources/extensions/gsd/auto.js +97 -31
  41. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +27 -1
  42. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +4 -2
  43. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +11 -0
  44. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -6
  45. package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -6
  46. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
  47. package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
  48. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
  49. package/dist/resources/extensions/gsd/commands-cmux.js +9 -6
  50. package/dist/resources/extensions/gsd/commands-extensions.js +634 -43
  51. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
  52. package/dist/resources/extensions/gsd/dispatch-guard.js +29 -3
  53. package/dist/resources/extensions/gsd/file-lock.js +49 -9
  54. package/dist/resources/extensions/gsd/git-service.js +1 -0
  55. package/dist/resources/extensions/gsd/gitignore.js +2 -0
  56. package/dist/resources/extensions/gsd/gsd-db.js +90 -30
  57. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
  58. package/dist/resources/extensions/gsd/guided-flow.js +212 -9
  59. package/dist/resources/extensions/gsd/health-widget.js +4 -1
  60. package/dist/resources/extensions/gsd/journal.js +17 -2
  61. package/dist/resources/extensions/gsd/key-manager.js +22 -0
  62. package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
  63. package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
  64. package/dist/resources/extensions/gsd/model-router.js +36 -3
  65. package/dist/resources/extensions/gsd/notifications.js +30 -16
  66. package/dist/resources/extensions/gsd/pre-execution-checks.js +31 -6
  67. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +29 -2
  68. package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
  69. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  70. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  71. package/dist/resources/extensions/gsd/prompts/system.md +1 -0
  72. package/dist/resources/extensions/gsd/reports.js +5 -4
  73. package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
  74. package/dist/resources/extensions/gsd/safety/file-change-validator.js +12 -4
  75. package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
  76. package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
  77. package/dist/resources/extensions/gsd/state.js +25 -25
  78. package/dist/resources/extensions/gsd/token-counter.js +22 -5
  79. package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
  80. package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
  81. package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
  82. package/dist/resources/extensions/gsd/uok/audit.js +18 -2
  83. package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
  84. package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
  85. package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
  86. package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
  87. package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
  88. package/dist/resources/extensions/gsd/uok/plan-v2.js +30 -7
  89. package/dist/resources/extensions/gsd/uok/writer.js +82 -0
  90. package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
  91. package/dist/resources/extensions/gsd/worktree-manager.js +1 -0
  92. package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
  93. package/dist/resources/extensions/mcp-client/auth.js +10 -1
  94. package/dist/resources/extensions/mcp-client/index.js +118 -9
  95. package/dist/resources/extensions/shared/cmux-events.js +12 -0
  96. package/dist/resources/extensions/shared/rtk-session-stats.js +1 -2
  97. package/dist/resources/skills/create-skill/SKILL.md +2 -2
  98. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  99. package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  100. package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  101. package/dist/resources/skills/verify-before-complete/SKILL.md +2 -1
  102. package/dist/resources/skills/write-docs/SKILL.md +2 -1
  103. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  106. package/dist/web/standalone/.next/build-manifest.json +3 -3
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  133. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/notifications/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/index.html +1 -1
  190. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  191. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  192. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  193. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  194. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  195. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  196. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  197. package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
  198. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  199. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  201. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  203. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  204. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  205. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
  206. package/dist/web/standalone/.next/static/chunks/{webpack-5fc74f13a25fa1bb.js → webpack-2e68521d7c82f7c2.js} +1 -1
  207. package/dist/welcome-screen.js +6 -1
  208. package/dist/wizard.js +2 -0
  209. package/package.json +16 -14
  210. package/packages/daemon/package.json +2 -2
  211. package/packages/mcp-server/README.md +3 -3
  212. package/packages/mcp-server/dist/env-writer.d.ts +1 -0
  213. package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
  214. package/packages/mcp-server/dist/env-writer.js +74 -6
  215. package/packages/mcp-server/dist/env-writer.js.map +1 -1
  216. package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
  217. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
  218. package/packages/mcp-server/dist/remote-questions.js +732 -0
  219. package/packages/mcp-server/dist/remote-questions.js.map +1 -0
  220. package/packages/mcp-server/dist/server.d.ts +7 -0
  221. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  222. package/packages/mcp-server/dist/server.js +95 -10
  223. package/packages/mcp-server/dist/server.js.map +1 -1
  224. package/packages/mcp-server/dist/session-manager.d.ts +14 -0
  225. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  226. package/packages/mcp-server/dist/session-manager.js +49 -1
  227. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  228. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/workflow-tools.js +15 -6
  230. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  231. package/packages/mcp-server/package.json +9 -3
  232. package/packages/mcp-server/src/env-writer.test.ts +79 -1
  233. package/packages/mcp-server/src/env-writer.ts +76 -6
  234. package/packages/mcp-server/src/mcp-server.test.ts +67 -0
  235. package/packages/mcp-server/src/readers/readers.test.ts +5 -1
  236. package/packages/mcp-server/src/remote-questions.test.ts +294 -0
  237. package/packages/mcp-server/src/remote-questions.ts +916 -0
  238. package/packages/mcp-server/src/server.ts +118 -16
  239. package/packages/mcp-server/src/session-manager.ts +43 -1
  240. package/packages/mcp-server/src/workflow-tools.test.ts +44 -0
  241. package/packages/mcp-server/src/workflow-tools.ts +19 -6
  242. package/packages/mcp-server/tsconfig.test.json +19 -0
  243. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  244. package/packages/native/package.json +6 -1
  245. package/packages/native/src/__tests__/clipboard.test.mjs +69 -23
  246. package/packages/native/tsconfig.tsbuildinfo +1 -1
  247. package/packages/pi-agent-core/package.json +6 -1
  248. package/packages/pi-agent-core/src/agent-loop.test.ts +220 -15
  249. package/packages/pi-ai/dist/models/custom.d.ts +38 -0
  250. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/models/custom.js +41 -0
  252. package/packages/pi-ai/dist/models/custom.js.map +1 -1
  253. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
  254. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  255. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  256. package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
  257. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  258. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  259. package/packages/pi-ai/dist/providers/anthropic.js +8 -3
  260. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  261. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
  262. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
  263. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
  264. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
  265. package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
  266. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  267. package/packages/pi-ai/dist/providers/simple-options.js +16 -1
  268. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  269. package/packages/pi-ai/package.json +6 -1
  270. package/packages/pi-ai/src/models/custom.ts +42 -0
  271. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
  272. package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
  273. package/packages/pi-ai/src/providers/anthropic.ts +9 -3
  274. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
  275. package/packages/pi-ai/src/providers/simple-options.ts +17 -1
  276. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  277. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
  278. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
  280. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/agent-session.js +7 -0
  282. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +25 -0
  284. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +105 -6
  286. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +230 -28
  288. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +30 -2
  290. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/compaction/utils.js +113 -12
  292. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
  294. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +29 -18
  296. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
  298. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
  299. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
  300. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
  301. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +56 -1
  302. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +8 -15
  304. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts +25 -0
  306. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts.map +1 -0
  307. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js +109 -0
  308. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js.map +1 -0
  309. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts +67 -0
  310. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts.map +1 -0
  311. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js +167 -0
  312. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js.map +1 -0
  313. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +3 -2
  314. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/extensions/loader.js +24 -8
  316. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
  318. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  319. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +14 -0
  321. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +11 -0
  324. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -2
  326. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
  328. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
  329. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
  330. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
  331. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/model-registry.js +14 -0
  333. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -1
  335. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  336. package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
  337. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
  339. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  340. package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
  341. package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/session-manager.js +1 -1
  343. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/core/session-manager.test.js +21 -1
  345. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  346. package/packages/pi-coding-agent/dist/core/system-prompt.js +3 -3
  347. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js +2 -1
  349. package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
  351. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
  352. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  353. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
  354. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  355. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
  356. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  357. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
  358. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
  359. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -0
  360. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  361. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
  363. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  364. package/packages/pi-coding-agent/package.json +6 -1
  365. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
  366. package/packages/pi-coding-agent/src/core/agent-session.ts +11 -0
  367. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +368 -28
  368. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +122 -6
  369. package/packages/pi-coding-agent/src/core/compaction/utils.ts +111 -13
  370. package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
  371. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +32 -18
  372. package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +68 -1
  373. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +9 -18
  374. package/packages/pi-coding-agent/src/core/extensions/extension-discovery.ts +119 -0
  375. package/packages/pi-coding-agent/src/core/extensions/extension-registry.ts +222 -0
  376. package/packages/pi-coding-agent/src/core/extensions/loader.ts +24 -11
  377. package/packages/pi-coding-agent/src/core/extensions/runner.ts +2 -0
  378. package/packages/pi-coding-agent/src/core/extensions/types.ts +15 -0
  379. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +13 -0
  380. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -2
  381. package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
  382. package/packages/pi-coding-agent/src/core/model-registry.ts +16 -0
  383. package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -1
  384. package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
  385. package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
  386. package/packages/pi-coding-agent/src/core/session-manager.test.ts +30 -1
  387. package/packages/pi-coding-agent/src/core/session-manager.ts +1 -1
  388. package/packages/pi-coding-agent/src/core/system-prompt.ts +3 -3
  389. package/packages/pi-coding-agent/src/core/tools/path-utils.test.ts +2 -1
  390. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
  391. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
  392. package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
  393. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +14 -0
  394. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
  395. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  396. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +12 -5
  397. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  398. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +21 -0
  399. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  400. package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
  401. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/stdin-buffer.js +20 -0
  403. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  404. package/packages/pi-tui/package.json +6 -1
  405. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -5
  406. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +27 -0
  407. package/packages/pi-tui/src/stdin-buffer.ts +26 -0
  408. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  409. package/packages/rpc-client/package.json +6 -1
  410. package/pkg/package.json +1 -1
  411. package/scripts/install.js +512 -0
  412. package/scripts/lib/workspace-manifest.cjs +86 -0
  413. package/scripts/link-workspace-packages.cjs +5 -17
  414. package/scripts/postinstall.js +9 -178
  415. package/src/resources/extensions/claude-code-cli/readiness.ts +4 -3
  416. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +91 -63
  417. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +114 -12
  418. package/src/resources/extensions/cmux/index.ts +35 -10
  419. package/src/resources/extensions/github-sync/templates.ts +151 -0
  420. package/src/resources/extensions/github-sync/tests/templates.test.ts +59 -0
  421. package/src/resources/extensions/google-search/extension-manifest.json +5 -4
  422. package/src/resources/extensions/google-search/index.ts +9 -470
  423. package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
  424. package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -1
  425. package/src/resources/extensions/gsd/auto/loop.ts +104 -2
  426. package/src/resources/extensions/gsd/auto/phases.ts +123 -21
  427. package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
  428. package/src/resources/extensions/gsd/auto/run-unit.ts +56 -4
  429. package/src/resources/extensions/gsd/auto/session.ts +28 -1
  430. package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
  431. package/src/resources/extensions/gsd/auto/types.ts +1 -1
  432. package/src/resources/extensions/gsd/auto-dispatch.ts +117 -16
  433. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  434. package/src/resources/extensions/gsd/auto-model-selection.ts +1 -1
  435. package/src/resources/extensions/gsd/auto-post-unit.ts +92 -3
  436. package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
  437. package/src/resources/extensions/gsd/auto-recovery.ts +40 -1
  438. package/src/resources/extensions/gsd/auto-start.ts +48 -52
  439. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
  440. package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
  441. package/src/resources/extensions/gsd/auto-worktree.ts +122 -68
  442. package/src/resources/extensions/gsd/auto.ts +105 -35
  443. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -1
  444. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -2
  445. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +11 -0
  446. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -6
  447. package/src/resources/extensions/gsd/bootstrap/system-context.ts +13 -9
  448. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
  449. package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
  450. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
  451. package/src/resources/extensions/gsd/commands-cmux.ts +10 -6
  452. package/src/resources/extensions/gsd/commands-extensions.ts +747 -41
  453. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
  454. package/src/resources/extensions/gsd/dispatch-guard.ts +26 -2
  455. package/src/resources/extensions/gsd/file-lock.ts +84 -11
  456. package/src/resources/extensions/gsd/git-service.ts +1 -0
  457. package/src/resources/extensions/gsd/gitignore.ts +2 -1
  458. package/src/resources/extensions/gsd/gsd-db.ts +92 -32
  459. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
  460. package/src/resources/extensions/gsd/guided-flow.ts +259 -10
  461. package/src/resources/extensions/gsd/health-widget.ts +3 -1
  462. package/src/resources/extensions/gsd/journal.ts +29 -3
  463. package/src/resources/extensions/gsd/key-manager.ts +22 -0
  464. package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
  465. package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
  466. package/src/resources/extensions/gsd/model-router.ts +42 -1
  467. package/src/resources/extensions/gsd/notifications.ts +27 -15
  468. package/src/resources/extensions/gsd/pre-execution-checks.ts +33 -7
  469. package/src/resources/extensions/gsd/preferences-types.ts +8 -0
  470. package/src/resources/extensions/gsd/prompts/discuss-headless.md +29 -2
  471. package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
  472. package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  473. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  474. package/src/resources/extensions/gsd/prompts/system.md +1 -0
  475. package/src/resources/extensions/gsd/reports.ts +5 -4
  476. package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
  477. package/src/resources/extensions/gsd/safety/file-change-validator.ts +16 -3
  478. package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
  479. package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
  480. package/src/resources/extensions/gsd/state.ts +35 -30
  481. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +238 -4
  482. package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
  483. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
  484. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +122 -0
  485. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
  486. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +63 -0
  487. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
  488. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
  489. package/src/resources/extensions/gsd/tests/cmux.test.ts +5 -9
  490. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +15 -0
  491. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
  492. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  493. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  494. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +161 -0
  495. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
  496. package/src/resources/extensions/gsd/tests/derive-state.test.ts +1 -2
  497. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +14 -9
  498. package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
  499. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
  500. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
  501. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +31 -0
  502. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
  503. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +1 -1
  504. package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
  505. package/src/resources/extensions/gsd/tests/exec-history.test.ts +113 -0
  506. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
  507. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +38 -0
  508. package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
  509. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +131 -0
  510. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +296 -1
  511. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
  512. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
  513. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +4 -2
  514. package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
  515. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
  516. package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
  517. package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
  518. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +66 -0
  519. package/src/resources/extensions/gsd/tests/key-manager.test.ts +2 -0
  520. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +76 -0
  521. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  522. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
  523. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  524. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
  525. package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
  526. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +4 -2
  527. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +5 -0
  528. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
  529. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +150 -0
  530. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
  531. package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
  532. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +337 -0
  533. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
  534. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +39 -25
  535. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +181 -0
  536. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
  537. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
  538. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
  539. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
  540. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
  541. package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
  542. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
  543. package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
  544. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
  545. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
  546. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
  547. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +24 -0
  548. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
  549. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
  550. package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
  551. package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
  552. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
  553. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
  554. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
  555. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
  556. package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
  557. package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
  558. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +42 -2
  559. package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
  560. package/src/resources/extensions/gsd/tests/validate-extension-package.test.ts +168 -0
  561. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +138 -5
  562. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +25 -2
  563. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
  564. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
  565. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
  566. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
  567. package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
  568. package/src/resources/extensions/gsd/token-counter.ts +22 -5
  569. package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
  570. package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
  571. package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
  572. package/src/resources/extensions/gsd/uok/audit.ts +20 -2
  573. package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
  574. package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
  575. package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
  576. package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
  577. package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
  578. package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
  579. package/src/resources/extensions/gsd/uok/plan-v2.ts +39 -8
  580. package/src/resources/extensions/gsd/uok/writer.ts +113 -0
  581. package/src/resources/extensions/gsd/workflow-logger.ts +23 -3
  582. package/src/resources/extensions/gsd/worktree-manager.ts +1 -0
  583. package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
  584. package/src/resources/extensions/mcp-client/auth.ts +12 -1
  585. package/src/resources/extensions/mcp-client/index.ts +129 -10
  586. package/src/resources/extensions/shared/cmux-events.ts +59 -0
  587. package/src/resources/extensions/shared/rtk-session-stats.ts +1 -2
  588. package/src/resources/skills/create-skill/SKILL.md +2 -2
  589. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  590. package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  591. package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  592. package/src/resources/skills/verify-before-complete/SKILL.md +2 -1
  593. package/src/resources/skills/write-docs/SKILL.md +2 -1
  594. package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
  595. package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
  596. /package/dist/web/standalone/.next/static/{n21VtX2hZlkpdEUO_nU4z → vidAVJkURvTJ0_V2-64ro}/_buildManifest.js +0 -0
  597. /package/dist/web/standalone/.next/static/{n21VtX2hZlkpdEUO_nU4z → vidAVJkURvTJ0_V2-64ro}/_ssgManifest.js +0 -0
@@ -1,5 +1,6 @@
1
1
  import { logWarning } from "../workflow-logger.js";
2
- import { checkAutoStartAfterDiscuss } from "../guided-flow.js";
2
+ import { checkAutoStartAfterDiscuss, maybeHandleReadyPhraseWithoutFiles, maybeHandleEmptyIntentTurn, resetEmptyTurnCounter, } from "../guided-flow.js";
3
+ import { clearPathCache } from "../paths.js";
3
4
  import { getAutoDashboardData, getAutoModeStartModel, isAutoActive, pauseAuto, setCurrentDispatchedModelId } from "../auto.js";
4
5
  import { getNextFallbackModel, resolveModelWithFallbacksForUnit } from "../preferences.js";
5
6
  import { pauseAutoForProviderError } from "../provider-error-pause.js";
@@ -49,10 +50,32 @@ async function pauseTransientWithBackoff(cls, pi, ctx, errorDetail, isRateLimit)
49
50
  });
50
51
  }
51
52
  export async function handleAgentEnd(pi, event, ctx) {
53
+ // #4648 — Invalidate the directory-listing cache before any artifact-existence
54
+ // checks. The LLM may have written milestone files (CONTEXT.md, ROADMAP.md,
55
+ // PROJECT.md, REQUIREMENTS.md) via tool calls during the turn that just
56
+ // ended. `paths.ts` caches readdir() results without a TTL, so without this
57
+ // flush, `resolveMilestoneFile` returns the pre-write listing and the guards
58
+ // below (`checkAutoStartAfterDiscuss` and `maybeHandleReadyPhraseWithoutFiles`)
59
+ // falsely report files as missing — producing a spurious "ready signal
60
+ // rejected" loop even though the files are on disk.
61
+ clearPathCache();
52
62
  if (checkAutoStartAfterDiscuss()) {
53
63
  clearDiscussionFlowState();
54
64
  return;
55
65
  }
66
+ // #4573 — When the LLM emits "Milestone X ready." but the required files
67
+ // are missing, `checkAutoStartAfterDiscuss` returns false silently. Surface
68
+ // that and nudge the LLM to complete the writes before the user hits the
69
+ // downstream "All milestones complete" warning loop.
70
+ if (maybeHandleReadyPhraseWithoutFiles(event))
71
+ return;
72
+ // #4573 — Empty-turn recovery: if the LLM announced intent in prose but
73
+ // emitted no tool calls, nudge it to execute. Fires only when auto-mode is
74
+ // active or a discussion autostart is pending (non-auto interactive discuss
75
+ // is user-driven). Runs before `isAutoActive` early return so pending
76
+ // discussions (where isAutoActive may be false) still get recovered.
77
+ if (maybeHandleEmptyIntentTurn(event, isAutoActive()))
78
+ return;
56
79
  if (!isAutoActive())
57
80
  return;
58
81
  if (isSessionSwitchInFlight())
@@ -286,6 +309,9 @@ export async function handleAgentEnd(pi, event, ctx) {
286
309
  // ── Success path ─────────────────────────────────────────────────────────
287
310
  try {
288
311
  resetRetryState(retryState);
312
+ // #4573 — Reset the empty-turn counter on any successful agent turn so
313
+ // transient stalls don't accumulate across independent units.
314
+ resetEmptyTurnCounter();
289
315
  resolveAgentEnd(event);
290
316
  }
291
317
  catch (err) {
@@ -3,6 +3,8 @@ import { resetTransientRetryState } from "./agent-end-recovery.js";
3
3
  import { resetSessionTimeoutState } from "../auto/phases.js";
4
4
  const defaultDeps = {
5
5
  getSnapshot: () => getAutoDashboardData(),
6
+ resetTransientRetryState,
7
+ resetSessionTimeoutState,
6
8
  startAuto,
7
9
  };
8
10
  export async function resumeAutoAfterProviderDelay(pi, ctx, deps = defaultDeps) {
@@ -18,8 +20,8 @@ export async function resumeAutoAfterProviderDelay(pi, ctx, deps = defaultDeps)
18
20
  // Reset retry counters before restarting — without this, counters
19
21
  // accumulate across pause/resume cycles and permanently lock out
20
22
  // auto-resume after their respective MAX thresholds.
21
- resetTransientRetryState();
22
- resetSessionTimeoutState();
23
+ deps.resetTransientRetryState();
24
+ deps.resetSessionTimeoutState();
23
25
  await deps.startAuto(ctx, pi, snapshot.basePath, false, { step: snapshot.stepMode });
24
26
  return "resumed";
25
27
  }
@@ -12,6 +12,13 @@ import { registerHooks } from "./register-hooks.js";
12
12
  import { registerShortcuts } from "./register-shortcuts.js";
13
13
  import { writeCrashLog } from "./crash-log.js";
14
14
  import { logWarning } from "../workflow-logger.js";
15
+ // Static import so cmux event listeners are registered synchronously during
16
+ // extension bootstrap. Prior implementation used `void import().then()` which
17
+ // queued listener registration as a microtask — any CMUX_CHANNELS emit fired
18
+ // in the same event loop turn as registration (e.g. from a provider-error
19
+ // session hook calling startAuto) would be silently dropped because Node's
20
+ // EventEmitter does not buffer events for late subscribers.
21
+ import { initCmuxEventListeners } from "../../cmux/index.js";
15
22
  export { writeCrashLog } from "./crash-log.js";
16
23
  export function handleRecoverableExtensionProcessError(err) {
17
24
  if (err.code === "EPIPE") {
@@ -89,6 +96,10 @@ export function registerGsdExtension(pi) {
89
96
  ["memory-tools", () => registerMemoryTools(pi)],
90
97
  ["exec-tools", () => registerExecTools(pi)],
91
98
  ["shortcuts", () => registerShortcuts(pi)],
99
+ // cmux is a library (no pi), so gsd sets up the event listeners on its
100
+ // behalf using the shared event channel contract. Registration is
101
+ // synchronous — see the import comment above for the rationale.
102
+ ["cmux-events", () => initCmuxEventListeners(pi.events)],
92
103
  ["hooks", () => registerHooks(pi, ecosystemHandlers)],
93
104
  ["ecosystem", () => {
94
105
  void loadEcosystemExtensions(pi, ecosystemHandlers).catch((err) => {
@@ -13,12 +13,12 @@ import { loadToolApiKeys } from "../commands-config.js";
13
13
  import { loadFile, saveFile, formatContinue } from "../files.js";
14
14
  import { deriveState } from "../state.js";
15
15
  import { getAutoDashboardData, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto.js";
16
- import { hideFooter } from "../auto-dashboard.js";
17
16
  import { isParallelActive, shutdownParallel } from "../parallel-orchestrator.js";
18
17
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
19
18
  import { saveActivityLog } from "../activity-log.js";
20
19
  import { resetAskUserQuestionsCache } from "../../ask-user-questions.js";
21
- import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult } from "../safety/evidence-collector.js";
20
+ import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
21
+ import { parseUnitId } from "../unit-id.js";
22
22
  import { classifyCommand } from "../safety/destructive-guard.js";
23
23
  import { logWarning as safetyLogWarning } from "../workflow-logger.js";
24
24
  import { installNotifyInterceptor } from "./notify-interceptor.js";
@@ -37,7 +37,9 @@ export function registerHooks(pi, ecosystemHandlers) {
37
37
  initNotificationStore(process.cwd());
38
38
  installNotifyInterceptor(ctx);
39
39
  initNotificationWidget(ctx);
40
- initHealthWidget(ctx);
40
+ if (!isAutoActive()) {
41
+ initHealthWidget(ctx);
42
+ }
41
43
  resetWriteGateState();
42
44
  resetToolCallLoopGuard();
43
45
  resetAskUserQuestionsCache();
@@ -79,7 +81,7 @@ export function registerHooks(pi, ecosystemHandlers) {
79
81
  }
80
82
  loadToolApiKeys();
81
83
  if (isAutoActive()) {
82
- ctx.ui.setFooter(hideFooter);
84
+ ctx.ui.setWidget("gsd-health", undefined);
83
85
  }
84
86
  });
85
87
  pi.on("session_switch", async (_event, ctx) => {
@@ -101,7 +103,7 @@ export function registerHooks(pi, ecosystemHandlers) {
101
103
  }
102
104
  loadToolApiKeys();
103
105
  if (isAutoActive()) {
104
- ctx.ui.setFooter(hideFooter);
106
+ ctx.ui.setWidget("gsd-health", undefined);
105
107
  }
106
108
  });
107
109
  pi.on("before_agent_start", async (event, ctx) => {
@@ -441,7 +443,7 @@ export function registerHooks(pi, ecosystemHandlers) {
441
443
  pi.on("tool_execution_start", async (event) => {
442
444
  if (!isAutoActive())
443
445
  return;
444
- markToolStart(event.toolCallId);
446
+ markToolStart(event.toolCallId, event.toolName);
445
447
  });
446
448
  pi.on("tool_execution_end", async (event) => {
447
449
  markToolEnd(event.toolCallId);
@@ -456,6 +458,15 @@ export function registerHooks(pi, ecosystemHandlers) {
456
458
  // Safety harness: record tool execution results for evidence cross-referencing
457
459
  if (isAutoActive()) {
458
460
  safetyRecordToolResult(event.toolCallId, event.toolName, event.result, event.isError);
461
+ // Persist evidence to disk after each tool result so it survives a session
462
+ // restart mid-unit (Bug #4385 — non-persisted evidence false positives).
463
+ const dash = getAutoDashboardData();
464
+ if (dash.basePath && dash.currentUnit?.type === "execute-task") {
465
+ const { milestone: pMid, slice: pSid, task: pTid } = parseUnitId(dash.currentUnit.id);
466
+ if (pMid && pSid && pTid) {
467
+ saveEvidenceToDisk(dash.basePath, pMid, pSid, pTid);
468
+ }
469
+ }
459
470
  }
460
471
  });
461
472
  pi.on("model_select", async (_event, ctx) => {
@@ -16,7 +16,6 @@ import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-comma
16
16
  import { deriveState } from "../state.js";
17
17
  import { formatOverridesSection, formatShortcut, loadActiveOverrides, loadFile, parseContinue, parseSummary } from "../files.js";
18
18
  import { toPosixPath } from "../../shared/mod.js";
19
- import { markCmuxPromptShown, shouldPromptToEnableCmux } from "../../cmux/index.js";
20
19
  import { autoEnableCmuxPreferences } from "../commands-cmux.js";
21
20
  const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
22
21
  /**
@@ -87,13 +86,19 @@ export async function buildBeforeAgentStartResult(event, ctx) {
87
86
  shortcutShell: formatShortcut("Ctrl+Alt+B"),
88
87
  });
89
88
  let loadedPreferences = loadEffectiveGSDPreferences();
90
- if (shouldPromptToEnableCmux(loadedPreferences?.preferences)) {
91
- markCmuxPromptShown();
92
- if (autoEnableCmuxPreferences()) {
93
- loadedPreferences = loadEffectiveGSDPreferences();
94
- ctx.ui.notify("cmux detected — auto-enabled. Run /gsd cmux off to disable.", "info");
89
+ try {
90
+ const { markCmuxPromptShown, shouldPromptToEnableCmux } = await import("../../cmux/index.js");
91
+ if (shouldPromptToEnableCmux(loadedPreferences?.preferences)) {
92
+ markCmuxPromptShown();
93
+ if (autoEnableCmuxPreferences()) {
94
+ loadedPreferences = loadEffectiveGSDPreferences();
95
+ ctx.ui.notify("cmux detected — auto-enabled. Run /gsd cmux off to disable.", "info");
96
+ }
95
97
  }
96
98
  }
99
+ catch (e) {
100
+ logWarning("bootstrap", `cmux prompt setup skipped: ${e.message}`);
101
+ }
97
102
  let preferenceBlock = "";
98
103
  if (loadedPreferences) {
99
104
  const cwd = process.cwd();
@@ -24,8 +24,29 @@ const QUEUE_SAFE_TOOLS = new Set([
24
24
  /**
25
25
  * Bash commands that are read-only / investigative — safe during queue mode.
26
26
  * Matches the leading command in a bash invocation.
27
+ *
28
+ * Extension policy: add commands here when they are read-only / diagnostic.
29
+ * Never add commands that mutate project state (write files, run builds that
30
+ * emit artifacts, install packages, etc.).
31
+ *
32
+ * Current read-only additions (Bug #4385):
33
+ * npm run <diagnostic> — read-only diagnostic scripts: test, lint, typecheck, etc.
34
+ * NOT: build, install, compile, generate, deploy (artifact-producing)
35
+ * npm ls/list/info — inspect installed packages (read-only)
36
+ * npm outdated/audit — security/update checks (read-only)
37
+ * npx <pkg> — run a package binary without installing globally
38
+ * tsx — TypeScript runner used for dry-run / inspection scripts
39
+ * node --print — evaluate and print an expression, no side effects
40
+ * python / python3 — script inspection, version checks
41
+ * pip / pip3 show — show installed package info (read-only)
42
+ * jq — read-only JSON query
43
+ * yq — read-only YAML query
44
+ * curl -s / curl --silent — fetch for inspection (no -o / no output redirect)
45
+ * openssl version — version / certificate inspection
46
+ * env / printenv — print environment variables
47
+ * true / false — shell no-ops / test exit codes
27
48
  */
28
- const BASH_READ_ONLY_RE = /^\s*(cat|head|tail|less|more|wc|file|stat|du|df|which|type|echo|printf|ls|find|grep|rg|awk|sed\b(?!.*-i)|sort|uniq|diff|comm|tr|cut|tee\s+-a\s+\/dev\/null|git\s+(log|show|diff|status|branch|tag|remote|rev-parse|ls-files|blame|shortlog|describe|stash\s+list|config\s+--get|cat-file)|gh\s+(issue|pr|api|repo|release)\s+(view|list|diff|status|checks)|mkdir\s+-p\s+\.gsd|rtk\s)/;
49
+ const BASH_READ_ONLY_RE = /^\s*(cat|head|tail|less|more|wc|file|stat|du|df|which|type|echo|printf|ls|find|grep|rg|awk|sed\b(?!.*-i)|sort|uniq|diff|comm|tr|cut|tee\s+-a\s+\/dev\/null|git\s+(log|show|diff|status|branch|tag|remote|rev-parse|ls-files|blame|shortlog|describe|stash\s+list|config\s+--get|cat-file)|gh\s+(issue|pr|api|repo|release)\s+(view|list|diff|status|checks)|mkdir\s+-p\s+\.gsd|rtk\s|npm\s+run\s+(test|test:\w+|lint|lint:\w+|typecheck|type-check|type-check:\w+|check|verify|audit|outdated|format:check|ci|validate)\b|npm\s+(ls|list|info|view|show|outdated|audit|explain|doctor|ping|--version|-v)\b|npx\s|tsx\s|node\s+(--print|--version|-v\b)|python[23]?\s+(-c\s+'[^']*'|--version|-V\b|-m\s+(pip\s+show|pip\s+list|site))|pip[23]?\s+(show|list|freeze|check|index\s+versions)\b|jq\s|yq\s|curl\s+(-s\b|--silent\b)(?!\s+[^|>]*\s-[oO]\b)(?!\s+[^|>]*\s--output\b)[^|>]*$|openssl\s+(version|x509|s_client)|env\b|printenv\b|true\b|false\b)/;
29
50
  const verifiedDepthMilestones = new Set();
30
51
  let activeQueuePhase = false;
31
52
  /**
@@ -99,10 +120,21 @@ function normalizeWriteGateSnapshot(value) {
99
120
  pendingGateId: typeof record.pendingGateId === "string" ? record.pendingGateId : null,
100
121
  };
101
122
  }
123
+ const EMPTY_SNAPSHOT = {
124
+ verifiedDepthMilestones: [],
125
+ activeQueuePhase: false,
126
+ pendingGateId: null,
127
+ };
102
128
  export function loadWriteGateSnapshot(basePath = process.cwd()) {
103
129
  const path = writeGateSnapshotPath(basePath);
104
- if (!existsSync(path))
130
+ if (!existsSync(path)) {
131
+ // When persist mode is active and the file has been deleted, treat it as a
132
+ // full state reset so deleting the file clears the HARD BLOCK gate.
133
+ // In non-persist mode the file is never written, so fall back to in-memory.
134
+ if (shouldPersistWriteGateSnapshot())
135
+ return EMPTY_SNAPSHOT;
105
136
  return currentWriteGateSnapshot();
137
+ }
106
138
  try {
107
139
  return normalizeWriteGateSnapshot(JSON.parse(readFileSync(path, "utf-8")));
108
140
  }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * clean-root-preflight.ts — Preflight gate for dirty working trees before milestone merges.
3
+ *
4
+ * #2909: Adds a fast-path git status check before milestone completion merges.
5
+ * When the working tree is dirty the user is warned and changes are auto-stashed
6
+ * so the merge can proceed cleanly. After the merge completes, postflightPopStash
7
+ * restores the stashed changes.
8
+ *
9
+ * Design constraints (from Trek-e approval):
10
+ * - Warn the user before stashing (no silent surprises)
11
+ * - git stash push / git stash pop only — no custom stash management layer
12
+ * - Stash/pop errors are logged but MUST NOT block the merge
13
+ * - Fast-path status check — clean trees pay no extra cost
14
+ */
15
+ import { execFileSync } from "node:child_process";
16
+ import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
17
+ import { logWarning } from "./workflow-logger.js";
18
+ import { nativeHasChanges } from "./native-git-bridge.js";
19
+ /**
20
+ * Check the working tree for dirty files before a milestone merge.
21
+ *
22
+ * Clean tree path: O(1) — returns immediately with stashPushed=false.
23
+ *
24
+ * Dirty tree path:
25
+ * 1. Emits a warning notification via the provided `notify` callback.
26
+ * 2. Runs `git stash push --include-untracked -m "gsd-preflight-stash"`.
27
+ * 3. Returns stashPushed=true so the caller knows to call postflightPopStash.
28
+ *
29
+ * Any stash error is logged but does NOT throw — the merge proceeds regardless.
30
+ */
31
+ export function preflightCleanRoot(basePath, milestoneId, notify) {
32
+ // Fast-path: clean tree — nothing to do
33
+ let isDirty = false;
34
+ try {
35
+ isDirty = nativeHasChanges(basePath);
36
+ }
37
+ catch (err) {
38
+ // If the status check itself fails, treat as clean and let the merge decide
39
+ logWarning("preflight", `clean-root status check failed: ${err instanceof Error ? err.message : String(err)}`);
40
+ return { stashPushed: false, summary: "" };
41
+ }
42
+ if (!isDirty) {
43
+ return { stashPushed: false, summary: "" };
44
+ }
45
+ // Warn the user before stashing
46
+ const warnMsg = `Working tree has uncommitted changes before milestone ${milestoneId} merge. Auto-stashing to allow clean merge (stash will be restored after merge).`;
47
+ notify(warnMsg, "warning");
48
+ // Push the stash
49
+ try {
50
+ execFileSync("git", ["stash", "push", "--include-untracked", "-m", "gsd-preflight-stash"], {
51
+ cwd: basePath,
52
+ stdio: ["ignore", "pipe", "pipe"],
53
+ encoding: "utf-8",
54
+ env: GIT_NO_PROMPT_ENV,
55
+ });
56
+ return {
57
+ stashPushed: true,
58
+ summary: `Stashed uncommitted changes before merge (milestone ${milestoneId}).`,
59
+ };
60
+ }
61
+ catch (err) {
62
+ // Stash failure is non-fatal — log and let the merge attempt proceed
63
+ const msg = `git stash push failed before merge of milestone ${milestoneId}: ${err instanceof Error ? err.message : String(err)}`;
64
+ logWarning("preflight", msg);
65
+ notify(`Auto-stash failed before milestone ${milestoneId} merge — proceeding anyway. ${msg}`, "warning");
66
+ return { stashPushed: false, summary: `stash-push-failed: ${msg}` };
67
+ }
68
+ }
69
+ /**
70
+ * Restore stashed changes after a milestone merge completes.
71
+ *
72
+ * Only called when preflightCleanRoot returned stashPushed=true.
73
+ * Any pop error (e.g. conflict) is logged and notified but does NOT throw —
74
+ * the merge already completed successfully.
75
+ */
76
+ export function postflightPopStash(basePath, milestoneId, notify) {
77
+ try {
78
+ execFileSync("git", ["stash", "pop"], {
79
+ cwd: basePath,
80
+ stdio: ["ignore", "pipe", "pipe"],
81
+ encoding: "utf-8",
82
+ env: GIT_NO_PROMPT_ENV,
83
+ });
84
+ notify(`Restored stashed changes after milestone ${milestoneId} merge.`, "info");
85
+ }
86
+ catch (err) {
87
+ // Pop conflicts mean the merged code collides with the stashed changes.
88
+ // Log a warning — the user needs to resolve manually, but the merge succeeded.
89
+ const msg = `git stash pop failed after merge of milestone ${milestoneId}: ${err instanceof Error ? err.message : String(err)}. Run "git stash pop" manually to restore your changes.`;
90
+ logWarning("preflight", msg);
91
+ notify(msg, "warning");
92
+ }
93
+ }
@@ -17,6 +17,22 @@ import { validateDefinition } from "../../definition-loader.js";
17
17
  import { formatPluginInfo, listPluginsFormatted, resolvePlugin, } from "../../workflow-plugins.js";
18
18
  import { dispatchOneshot } from "../../workflow-dispatch.js";
19
19
  import { fetchWorkflowSource, globalInstallDir, inferPluginName, installPlugin, previewContent, projectInstallDir, resolveSourceUrl, uninstallPlugin, validateFetchedContent, } from "../../workflow-install.js";
20
+ /**
21
+ * Refuses interactive commands that mutate durable .gsd/ planning state while
22
+ * auto-mode holds the worktree. Returns true if the command was blocked and
23
+ * the caller should return immediately; false if it is safe to proceed.
24
+ *
25
+ * Auto-mode's squash merge performs a pre-merge dirty-tree check; concurrent
26
+ * writes by interactive commands between that check and the merge itself
27
+ * cause __dirty_working_tree__ failures (#4704).
28
+ */
29
+ function requireNotAutoActive(commandName, ctx) {
30
+ if (!isAutoActive())
31
+ return false;
32
+ ctx.ui.notify(`${commandName} cannot run while auto-mode is active.\n` +
33
+ `Stop auto-mode first with /gsd stop, then run ${commandName}.`, "error");
34
+ return true;
35
+ }
20
36
  // ─── Custom Workflow Subcommands ─────────────────────────────────────────
21
37
  const RESERVED_SUBCOMMANDS = new Set([
22
38
  "new", "run", "list", "validate", "pause", "resume",
@@ -394,12 +410,16 @@ async function handleCustomWorkflow(sub, ctx, pi) {
394
410
  export async function handleWorkflowCommand(trimmed, ctx, pi) {
395
411
  // ── /gsd do — natural language routing (must be early to route to other commands) ──
396
412
  if (trimmed === "do" || trimmed.startsWith("do ")) {
413
+ if (requireNotAutoActive("/gsd do", ctx))
414
+ return true;
397
415
  const { handleDo } = await import("../../commands-do.js");
398
416
  await handleDo(trimmed.replace(/^do\s*/, "").trim(), ctx, pi);
399
417
  return true;
400
418
  }
401
419
  // ── Backlog management ──
402
420
  if (trimmed === "backlog" || trimmed.startsWith("backlog ")) {
421
+ if (requireNotAutoActive("/gsd backlog", ctx))
422
+ return true;
403
423
  const { handleBacklog } = await import("../../commands-backlog.js");
404
424
  await handleBacklog(trimmed.replace(/^backlog\s*/, "").trim(), ctx, pi);
405
425
  return true;
@@ -410,23 +430,26 @@ export async function handleWorkflowCommand(trimmed, ctx, pi) {
410
430
  return handleCustomWorkflow(sub, ctx, pi);
411
431
  }
412
432
  if (trimmed === "queue") {
433
+ if (requireNotAutoActive("/gsd queue", ctx))
434
+ return true;
413
435
  await showQueue(ctx, pi, projectRoot());
414
436
  return true;
415
437
  }
416
438
  if (trimmed === "discuss") {
439
+ if (requireNotAutoActive("/gsd discuss", ctx))
440
+ return true;
417
441
  await showDiscuss(ctx, pi, projectRoot());
418
442
  return true;
419
443
  }
420
444
  if (trimmed === "quick" || trimmed.startsWith("quick ")) {
421
- if (isAutoActive()) {
422
- ctx.ui.notify("/gsd quick cannot run while auto-mode is active.\n" +
423
- "Stop auto-mode first with /gsd stop, then run /gsd quick.", "error");
445
+ if (requireNotAutoActive("/gsd quick", ctx))
424
446
  return true;
425
- }
426
447
  await handleQuick(trimmed.replace(/^quick\s*/, "").trim(), ctx, pi);
427
448
  return true;
428
449
  }
429
450
  if (trimmed === "new-milestone") {
451
+ if (requireNotAutoActive("/gsd new-milestone", ctx))
452
+ return true;
430
453
  const basePath = projectRoot();
431
454
  const headlessContextPath = join(gsdRoot(basePath), "runtime", "headless-context.md");
432
455
  if (existsSync(headlessContextPath)) {
@@ -452,6 +475,8 @@ export async function handleWorkflowCommand(trimmed, ctx, pi) {
452
475
  return true;
453
476
  }
454
477
  if (trimmed === "park" || trimmed.startsWith("park ")) {
478
+ if (requireNotAutoActive("/gsd park", ctx))
479
+ return true;
455
480
  const basePath = projectRoot();
456
481
  const arg = trimmed.replace(/^park\s*/, "").trim();
457
482
  let targetId = arg;
@@ -474,6 +499,8 @@ export async function handleWorkflowCommand(trimmed, ctx, pi) {
474
499
  return true;
475
500
  }
476
501
  if (trimmed === "unpark" || trimmed.startsWith("unpark ")) {
502
+ if (requireNotAutoActive("/gsd unpark", ctx))
503
+ return true;
477
504
  const basePath = projectRoot();
478
505
  const arg = trimmed.replace(/^unpark\s*/, "").trim();
479
506
  let targetId = arg;
@@ -1,5 +1,4 @@
1
1
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
- import { clearCmuxSidebar, CmuxClient, detectCmuxEnvironment, resolveCmuxConfig } from "../cmux/index.js";
3
2
  import { saveFile } from "./files.js";
4
3
  import { getProjectGSDPreferencesPath, loadEffectiveGSDPreferences, loadProjectGSDPreferences, } from "./preferences.js";
5
4
  import { ensurePreferencesFile, serializePreferencesToFrontmatter } from "./commands-prefs-wizard.js";
@@ -63,7 +62,8 @@ async function writeProjectCmuxPreferences(ctx, updater) {
63
62
  function resolveProjectPreferencesWritePath() {
64
63
  return loadProjectGSDPreferences()?.path ?? getProjectGSDPreferencesPath();
65
64
  }
66
- function formatCmuxStatus() {
65
+ async function formatCmuxStatus() {
66
+ const { CmuxClient, detectCmuxEnvironment, resolveCmuxConfig } = await import("../cmux/index.js");
67
67
  const loaded = loadEffectiveGSDPreferences();
68
68
  const detected = detectCmuxEnvironment();
69
69
  const resolved = resolveCmuxConfig(loaded?.preferences);
@@ -87,7 +87,8 @@ function formatCmuxStatus() {
87
87
  `Capabilities: access=${accessMode}, methods=${methods}`,
88
88
  ].join("\n");
89
89
  }
90
- function ensureCmuxAvailableForEnable(ctx) {
90
+ async function ensureCmuxAvailableForEnable(ctx) {
91
+ const { detectCmuxEnvironment } = await import("../cmux/index.js");
91
92
  const detected = detectCmuxEnvironment();
92
93
  if (detected.available)
93
94
  return true;
@@ -97,11 +98,11 @@ function ensureCmuxAvailableForEnable(ctx) {
97
98
  export async function handleCmux(args, ctx) {
98
99
  const trimmed = args.trim();
99
100
  if (!trimmed || trimmed === "status") {
100
- ctx.ui.notify(formatCmuxStatus(), "info");
101
+ ctx.ui.notify(await formatCmuxStatus(), "info");
101
102
  return;
102
103
  }
103
104
  if (trimmed === "on") {
104
- if (!ensureCmuxAvailableForEnable(ctx))
105
+ if (!await ensureCmuxAvailableForEnable(ctx))
105
106
  return;
106
107
  await writeProjectCmuxPreferences(ctx, (prefs) => {
107
108
  prefs.cmux = {
@@ -122,6 +123,7 @@ export async function handleCmux(args, ctx) {
122
123
  await writeProjectCmuxPreferences(ctx, (prefs) => {
123
124
  prefs.cmux = { ...(prefs.cmux ?? {}), enabled: false };
124
125
  });
126
+ const { clearCmuxSidebar } = await import("../cmux/index.js");
125
127
  clearCmuxSidebar(effective);
126
128
  ctx.ui.notify("cmux integration disabled in project preferences.", "info");
127
129
  return;
@@ -130,7 +132,7 @@ export async function handleCmux(args, ctx) {
130
132
  if (parts.length === 2 && ["notifications", "sidebar", "splits", "browser"].includes(parts[0]) && ["on", "off"].includes(parts[1])) {
131
133
  const feature = parts[0];
132
134
  const enabled = parts[1] === "on";
133
- if (enabled && !ensureCmuxAvailableForEnable(ctx))
135
+ if (enabled && !await ensureCmuxAvailableForEnable(ctx))
134
136
  return;
135
137
  await writeProjectCmuxPreferences(ctx, (prefs) => {
136
138
  const next = { ...(prefs.cmux ?? {}) };
@@ -140,6 +142,7 @@ export async function handleCmux(args, ctx) {
140
142
  prefs.cmux = next;
141
143
  });
142
144
  if (!enabled && feature === "sidebar") {
145
+ const { clearCmuxSidebar } = await import("../cmux/index.js");
143
146
  clearCmuxSidebar(loadEffectiveGSDPreferences()?.preferences);
144
147
  }
145
148
  const note = feature === "browser" && enabled