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,180 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { exec as execCb, spawnSync } from 'child_process'
4
- import { createHash, randomUUID } from 'crypto'
5
- import { chmodSync, copyFileSync, createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, rmSync } from 'fs'
6
- import { arch, homedir, platform } from 'os'
7
- import { dirname, resolve, join } from 'path'
8
- import { Readable } from 'stream'
9
- import { finished } from 'stream/promises'
10
- import extractZip from 'extract-zip'
11
- import { fileURLToPath } from 'url'
12
-
13
- const __dirname = dirname(fileURLToPath(import.meta.url))
14
- const cwd = resolve(__dirname, '..')
15
- const PLAYWRIGHT_SKIP =
16
- process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD === '1' ||
17
- process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD === 'true'
18
- const RTK_SKIP =
19
- process.env.GSD_SKIP_RTK_INSTALL === '1' ||
20
- process.env.GSD_SKIP_RTK_INSTALL === 'true' ||
21
- process.env.GSD_RTK_DISABLED === '1' ||
22
- process.env.GSD_RTK_DISABLED === 'true'
23
-
24
- const RTK_VERSION = '0.33.1'
25
- const RTK_REPO = 'rtk-ai/rtk'
26
- const RTK_ENV = { ...process.env, RTK_TELEMETRY_DISABLED: '1' }
27
- const managedBinDir = join(process.env.GSD_HOME || join(homedir(), '.gsd'), 'agent', 'bin')
28
- const managedBinaryPath = join(managedBinDir, platform() === 'win32' ? 'rtk.exe' : 'rtk')
29
-
30
- function run(cmd) {
31
- return new Promise((resolvePromise) => {
32
- execCb(cmd, { cwd }, (error, stdout, stderr) => {
33
- resolvePromise({ ok: !error, stdout, stderr })
34
- })
35
- })
36
- }
37
-
38
- function logWarn(message) {
39
- process.stderr.write(`[gsd] postinstall: ${message}\n`)
40
- }
41
-
42
- function resolveAssetName() {
43
- const currentPlatform = platform()
44
- const currentArch = arch()
45
- if (currentPlatform === 'darwin' && currentArch === 'arm64') return 'rtk-aarch64-apple-darwin.tar.gz'
46
- if (currentPlatform === 'darwin' && currentArch === 'x64') return 'rtk-x86_64-apple-darwin.tar.gz'
47
- if (currentPlatform === 'linux' && currentArch === 'arm64') return 'rtk-aarch64-unknown-linux-gnu.tar.gz'
48
- if (currentPlatform === 'linux' && currentArch === 'x64') return 'rtk-x86_64-unknown-linux-musl.tar.gz'
49
- if (currentPlatform === 'win32' && currentArch === 'x64') return 'rtk-x86_64-pc-windows-msvc.zip'
50
- return null
51
- }
52
-
53
- function parseChecksums(text) {
54
- const checksums = new Map()
55
- for (const rawLine of text.split(/\r?\n/)) {
56
- const line = rawLine.trim()
57
- if (!line) continue
58
- const match = line.match(/^([a-f0-9]{64})\s+(.+)$/i)
59
- if (!match) continue
60
- checksums.set(match[2], match[1].toLowerCase())
61
- }
62
- return checksums
63
- }
64
-
65
- function sha256File(path) {
66
- const hash = createHash('sha256')
67
- hash.update(readFileSync(path))
68
- return hash.digest('hex')
69
- }
70
-
71
- async function downloadToFile(url, destination) {
72
- const response = await fetch(url, { headers: { 'User-Agent': 'gsd-pi-postinstall' } })
73
- if (!response.ok) {
74
- throw new Error(`download failed (${response.status}) for ${url}`)
75
- }
76
- if (!response.body) {
77
- throw new Error(`download returned no body for ${url}`)
78
- }
79
- const output = createWriteStream(destination)
80
- await finished(Readable.fromWeb(response.body).pipe(output))
81
- }
82
-
83
- function findBinaryRecursively(rootDir, binaryName) {
84
- const stack = [rootDir]
85
- while (stack.length > 0) {
86
- const current = stack.pop()
87
- if (!current) continue
88
- const entries = readdirSync(current, { withFileTypes: true })
89
- for (const entry of entries) {
90
- const fullPath = join(current, entry.name)
91
- if (entry.isFile() && entry.name === binaryName) return fullPath
92
- if (entry.isDirectory()) stack.push(fullPath)
93
- }
94
- }
95
- return null
96
- }
97
-
98
- function validateRtkBinary(binaryPath) {
99
- const result = spawnSync(binaryPath, ['rewrite', 'git status'], {
100
- encoding: 'utf-8',
101
- env: RTK_ENV,
102
- stdio: ['ignore', 'pipe', 'ignore'],
103
- timeout: 5000,
104
- })
105
- return !result.error && result.status === 0 && (result.stdout || '').trim() === 'rtk git status'
106
- }
107
-
108
- async function ensureRtkInstalled() {
109
- if (RTK_SKIP) return
110
- const assetName = resolveAssetName()
111
- if (!assetName) return
112
- if (existsSync(managedBinaryPath) && validateRtkBinary(managedBinaryPath)) return
113
-
114
- const tempRoot = join(managedBinDir, `.rtk-postinstall-${randomUUID().slice(0, 8)}`)
115
- const archivePath = join(tempRoot, assetName)
116
- const extractDir = join(tempRoot, 'extract')
117
- const releaseBase = `https://github.com/${RTK_REPO}/releases/download/v${RTK_VERSION}`
118
-
119
- mkdirSync(tempRoot, { recursive: true })
120
- mkdirSync(managedBinDir, { recursive: true })
121
-
122
- try {
123
- const checksumsResponse = await fetch(`${releaseBase}/checksums.txt`, {
124
- headers: { 'User-Agent': 'gsd-pi-postinstall' },
125
- })
126
- if (!checksumsResponse.ok) {
127
- throw new Error(`failed to fetch RTK checksums (${checksumsResponse.status})`)
128
- }
129
-
130
- const checksums = parseChecksums(await checksumsResponse.text())
131
- const expectedSha = checksums.get(assetName)
132
- if (!expectedSha) {
133
- throw new Error(`missing checksum for ${assetName}`)
134
- }
135
-
136
- await downloadToFile(`${releaseBase}/${assetName}`, archivePath)
137
- const actualSha = sha256File(archivePath)
138
- if (actualSha !== expectedSha) {
139
- throw new Error(`checksum mismatch for ${assetName}`)
140
- }
141
-
142
- mkdirSync(extractDir, { recursive: true })
143
- if (assetName.endsWith('.zip')) {
144
- await extractZip(archivePath, { dir: extractDir })
145
- } else {
146
- const extractResult = spawnSync('tar', ['xzf', archivePath, '-C', extractDir], {
147
- encoding: 'utf-8',
148
- timeout: 30000,
149
- })
150
- if (extractResult.error || extractResult.status !== 0) {
151
- throw new Error(extractResult.error?.message || extractResult.stderr?.trim() || `failed to extract ${assetName}`)
152
- }
153
- }
154
-
155
- const extractedBinary = findBinaryRecursively(extractDir, platform() === 'win32' ? 'rtk.exe' : 'rtk')
156
- if (!extractedBinary) {
157
- throw new Error(`RTK binary not found in ${assetName}`)
158
- }
159
-
160
- copyFileSync(extractedBinary, managedBinaryPath)
161
- if (platform() !== 'win32') {
162
- chmodSync(managedBinaryPath, 0o755)
163
- }
164
-
165
- if (!validateRtkBinary(managedBinaryPath)) {
166
- rmSync(managedBinaryPath, { force: true })
167
- throw new Error('downloaded RTK binary failed validation')
168
- }
169
- } catch (error) {
170
- logWarn(`RTK install skipped: ${error instanceof Error ? error.message : String(error)}`)
171
- } finally {
172
- rmSync(tempRoot, { recursive: true, force: true })
173
- }
174
- }
175
-
176
- if (!PLAYWRIGHT_SKIP) {
177
- await run('npx playwright install chromium')
178
- }
179
-
180
- await ensureRtkInstalled()
3
+ /**
4
+ * GSD Postinstall
5
+ *
6
+ * Thin wrapper that delegates to install.js in postinstall mode
7
+ * (workspace linking + deps only, no global/local npm install).
8
+ */
9
+
10
+ process.env.npm_lifecycle_event = process.env.npm_lifecycle_event || 'postinstall'
11
+ import('./install.js')
@@ -21,10 +21,11 @@ const CLAUDE_COMMAND = process.platform === "win32" ? "claude.cmd" : "claude";
21
21
 
22
22
  /**
23
23
  * Windows installs vary: some environments expose `claude.cmd` (npm shim),
24
- * others expose a `claude` shim on PATH (for example Git Bash wrappers).
25
- * Try both to avoid false "not installed" results in readiness checks.
24
+ * `claude.exe` (direct binary install), or a bare `claude` shim on PATH
25
+ * (for example Git Bash wrappers). Try all three to avoid false "not
26
+ * installed" results in readiness checks.
26
27
  */
27
- const CLAUDE_COMMAND_CANDIDATES = process.platform === "win32" ? [CLAUDE_COMMAND, "claude"] : [CLAUDE_COMMAND];
28
+ const CLAUDE_COMMAND_CANDIDATES = process.platform === "win32" ? [CLAUDE_COMMAND, "claude.exe", "claude"] : [CLAUDE_COMMAND];
28
29
 
29
30
  function execClaude(args: string[]): Buffer {
30
31
  let lastError: unknown;
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * The SDK runs the full agentic loop (multi-turn, tool execution, compaction)
5
5
  * in one call. This adapter translates the SDK's streaming output into
6
- * AssistantMessageEvents for TUI rendering, then strips tool-call blocks from
7
- * the final AssistantMessage so GSD's agent loop doesn't try to dispatch them.
6
+ * AssistantMessageEvents for TUI rendering, then preserves externally executed
7
+ * tool-call blocks on the final AssistantMessage so Agent Core can render them
8
+ * while `externalToolExecution` prevents local redispatch.
8
9
  */
9
10
 
10
11
  import type {
@@ -692,18 +693,22 @@ export function makeAbortedMessage(model: string, lastTextContent: string): Assi
692
693
  /**
693
694
  * Resolve the Claude Code permission mode for the current run.
694
695
  *
695
- * GSD subagents run underneath a host Claude Code session the user has
696
- * already consented to, and their work (edits, shell inspection, MCP calls)
697
- * spans the full workflow toolset. Defaulting the inner SDK to
698
- * `bypassPermissions` avoids per-tool approval prompts that offer no
699
- * meaningful safety beyond what the host session and the subagent prompts
700
- * already enforce. `GSD_CLAUDE_CODE_PERMISSION_MODE` lets security-conscious
701
- * users opt into a stricter mode (`acceptEdits`, `default`, `plan`).
696
+ * Defaults to `acceptEdits`, which auto-approves file reads/edits but
697
+ * surfaces a permission dialog for dangerous operations (e.g. general Bash,
698
+ * Agent, WebFetch). This prevents tools outside the allowlist from being
699
+ * silently denied the SDK emits an `extension_ui_request` event so the
700
+ * user sees a prompt instead of a silent refusal that Claude Code mistakes
701
+ * for user rejection (#4383).
702
702
  *
703
- * Tradeoff: bypass means a prompt-injection payload read from an untrusted
704
- * file could trigger tool calls without a second gate. Accepted for GSD
705
- * because the workflow is explicit user intent and the alternative
706
- * (#4099) is continuous approval fatigue that blocks real work.
703
+ * Set `GSD_CLAUDE_CODE_PERMISSION_MODE` to `bypassPermissions` to restore
704
+ * the old always-approve behaviour, or to `default` / `plan` for stricter
705
+ * modes.
706
+ *
707
+ * When `GSD_HEADLESS=1` is set (auto-mode / non-interactive runs), the
708
+ * default flips to `bypassPermissions` because there is no UI to approve
709
+ * permission dialogs — `acceptEdits` would hang verification commands like
710
+ * `npx tsc --noEmit` or `npx vitest run` indefinitely (#4657). Explicit
711
+ * overrides still win, so users can opt back into `acceptEdits` in headless.
707
712
  */
708
713
  export async function resolveClaudePermissionMode(
709
714
  env: NodeJS.ProcessEnv = process.env,
@@ -712,6 +717,12 @@ export async function resolveClaudePermissionMode(
712
717
  if (override === "bypassPermissions" || override === "acceptEdits" || override === "default" || override === "plan") {
713
718
  return override;
714
719
  }
720
+ if (env.GSD_HEADLESS === "1") {
721
+ console.warn(
722
+ "[claude-code-cli] Headless mode detected (GSD_HEADLESS=1): defaulting permissionMode to 'bypassPermissions' so verification Bash commands can run. Set GSD_CLAUDE_CODE_PERMISSION_MODE=acceptEdits to opt out.",
723
+ );
724
+ return "bypassPermissions";
725
+ }
715
726
  return "bypassPermissions";
716
727
  }
717
728
 
@@ -773,20 +784,24 @@ export function buildSdkOptions(
773
784
  const { reasoning, ...sdkExtraOptions } = extraOptions;
774
785
  const mcpServers = buildWorkflowMcpServers();
775
786
  const permissionMode = overrides?.permissionMode ?? "bypassPermissions";
776
- const disallowedTools = ["AskUserQuestion"];
777
- // Pre-authorize the safe built-ins and every registered workflow MCP
778
- // server's tools. `acceptEdits` mode (the interactive default) only
779
- // auto-approves file edits Read/Glob/Grep, basic shell inspection, and
780
- // every `mcp__gsd-workflow__*` call still surface as "This command
781
- // requires approval" and block GSD actions (#4099).
787
+ // Globally unblock all tools. Users reported that the `acceptEdits` default
788
+ // plus a narrow allowlist silently declined most Bash/Agent/WebFetch calls
789
+ // when `extensionUIContext` wasn't threaded through. Default to
790
+ // bypassPermissions and an empty disallow list so every tool — including
791
+ // `AskUserQuestion` and every `mcp__*` workflow tool is auto-approved.
792
+ // Opt back into gated mode with GSD_CLAUDE_CODE_PERMISSION_MODE=acceptEdits.
793
+ const disallowedTools: string[] = [];
782
794
  const allowedTools = [
783
795
  "Read",
784
796
  "Write",
785
797
  "Edit",
786
798
  "Glob",
787
799
  "Grep",
788
- "Bash(ls:*)",
789
- "Bash(pwd)",
800
+ "Bash",
801
+ "Agent",
802
+ "WebFetch",
803
+ "WebSearch",
804
+ "AskUserQuestion",
790
805
  ...(mcpServers ? Object.keys(mcpServers).map((serverName) => `mcp__${serverName}__*`) : []),
791
806
  ];
792
807
  const supportsAdaptive = modelSupportsAdaptiveThinking(modelId);
@@ -994,6 +1009,49 @@ function attachExternalResultsToToolBlocks(
994
1009
  }
995
1010
  }
996
1011
 
1012
+ /**
1013
+ * Build the final assistant content that Agent Core consumes in
1014
+ * `externalToolExecution` mode. This preserves tool-call blocks, attaches any
1015
+ * SDK-produced external results by tool-call id, and then appends the final
1016
+ * text/thinking blocks for the completed turn.
1017
+ */
1018
+ export function buildFinalAssistantContent(params: {
1019
+ intermediateToolBlocks: AssistantMessage["content"];
1020
+ pendingContent?: AssistantMessage["content"];
1021
+ toolResultsById: ReadonlyMap<string, ExternalToolResultPayload>;
1022
+ lastThinkingContent?: string;
1023
+ lastTextContent?: string;
1024
+ fallbackResultText?: string;
1025
+ }): AssistantMessage["content"] {
1026
+ const mergedToolBlocks = [...params.intermediateToolBlocks];
1027
+ if (params.pendingContent) {
1028
+ mergePendingToolCalls(mergedToolBlocks, params.pendingContent);
1029
+ }
1030
+ attachExternalResultsToToolBlocks(mergedToolBlocks, params.toolResultsById);
1031
+
1032
+ const finalContent: AssistantMessage["content"] = [...mergedToolBlocks];
1033
+ if (params.pendingContent && params.pendingContent.length > 0) {
1034
+ for (const block of params.pendingContent) {
1035
+ if (block.type === "text" || block.type === "thinking") {
1036
+ finalContent.push(block);
1037
+ }
1038
+ }
1039
+ } else {
1040
+ if (params.lastThinkingContent) {
1041
+ finalContent.push({ type: "thinking", thinking: params.lastThinkingContent });
1042
+ }
1043
+ if (params.lastTextContent) {
1044
+ finalContent.push({ type: "text", text: params.lastTextContent });
1045
+ }
1046
+ }
1047
+
1048
+ if (finalContent.length === 0 && params.fallbackResultText) {
1049
+ finalContent.push({ type: "text", text: params.fallbackResultText });
1050
+ }
1051
+
1052
+ return finalContent;
1053
+ }
1054
+
997
1055
  /**
998
1056
  * Merge tool-call blocks from the active partial-message builder into the
999
1057
  * running list of intermediate tool calls, preserving order and de-duping
@@ -1025,8 +1083,9 @@ export function mergePendingToolCalls(
1025
1083
  * GSD streamSimple function that delegates to the Claude Agent SDK.
1026
1084
  *
1027
1085
  * Emits AssistantMessageEvent deltas for real-time TUI rendering
1028
- * (thinking, text, tool calls). The final AssistantMessage has tool-call
1029
- * blocks stripped so the agent loop ends the turn without local dispatch.
1086
+ * (thinking, text, tool calls). The final AssistantMessage preserves
1087
+ * SDK-executed tool-call blocks for Agent Core's `externalToolExecution`
1088
+ * path, which renders the results without dispatching the tools locally.
1030
1089
  */
1031
1090
  export function streamViaClaudeCode(
1032
1091
  model: Model<any>,
@@ -1227,46 +1286,15 @@ async function pumpSdkMessages(
1227
1286
  // -- Result (terminal) --
1228
1287
  case "result": {
1229
1288
  const result = msg as SDKResultMessage;
1230
-
1231
- // Build final message. Include intermediate tool calls so the
1232
- // agent loop's externalToolExecution path emits tool_execution
1233
- // events for proper TUI rendering, followed by the text response.
1234
- const finalContent: AssistantMessage["content"] = [];
1235
-
1236
- // If the final turn ended without a synthetic user message
1237
- // (e.g. stop_reason: "tool_use" followed directly by result,
1238
- // or a turn with text but no tool execution), the `builder`
1239
- // still holds toolCall blocks that were never pushed into
1240
- // `intermediateToolBlocks`. Fold them in here so they aren't
1241
- // dropped from the final AssistantMessage.
1242
- if (builder) {
1243
- mergePendingToolCalls(intermediateToolBlocks, builder.message.content);
1244
- }
1245
-
1246
- // Add tool calls from intermediate turns first (renders above text)
1247
- attachExternalResultsToToolBlocks(intermediateToolBlocks, toolResultsById);
1248
- finalContent.push(...intermediateToolBlocks);
1249
-
1250
- // Add text/thinking from the last turn
1251
- if (builder && builder.message.content.length > 0) {
1252
- for (const block of builder.message.content) {
1253
- if (block.type === "text" || block.type === "thinking") {
1254
- finalContent.push(block);
1255
- }
1256
- }
1257
- } else {
1258
- if (lastThinkingContent) {
1259
- finalContent.push({ type: "thinking", thinking: lastThinkingContent });
1260
- }
1261
- if (lastTextContent) {
1262
- finalContent.push({ type: "text", text: lastTextContent });
1263
- }
1264
- }
1265
-
1266
- // Fallback: use the SDK's result text if we have no content
1267
- if (finalContent.length === 0 && result.subtype === "success" && result.result) {
1268
- finalContent.push({ type: "text", text: result.result });
1269
- }
1289
+ const finalContent = buildFinalAssistantContent({
1290
+ intermediateToolBlocks,
1291
+ pendingContent: builder?.message.content,
1292
+ toolResultsById,
1293
+ lastThinkingContent,
1294
+ lastTextContent,
1295
+ fallbackResultText:
1296
+ result.subtype === "success" && result.result ? result.result : undefined,
1297
+ });
1270
1298
 
1271
1299
  const finalMessage: AssistantMessage = {
1272
1300
  role: "assistant",
@@ -8,6 +8,7 @@ import {
8
8
  getResultErrorMessage,
9
9
  makeAbortedMessage,
10
10
  mergePendingToolCalls,
11
+ buildFinalAssistantContent,
11
12
  resolveClaudePermissionMode,
12
13
  buildPromptFromContext,
13
14
  buildSdkQueryPrompt,
@@ -539,6 +540,71 @@ describe("stream-adapter — Claude Code external tool results", () => {
539
540
  },
540
541
  ]);
541
542
  });
543
+
544
+ test("buildFinalAssistantContent preserves intermediate tool calls with attached external results", () => {
545
+ const finalContent = buildFinalAssistantContent({
546
+ intermediateToolBlocks: [
547
+ {
548
+ type: "toolCall",
549
+ id: "tool-bash-1",
550
+ name: "bash",
551
+ arguments: { command: "echo hi" },
552
+ } as any,
553
+ ],
554
+ pendingContent: [{ type: "text", text: "All done." }],
555
+ toolResultsById: new Map([
556
+ [
557
+ "tool-bash-1",
558
+ {
559
+ content: [{ type: "text", text: "hi\n" }],
560
+ details: { source: "claude-code" },
561
+ isError: false,
562
+ },
563
+ ],
564
+ ]),
565
+ });
566
+
567
+ assert.equal(finalContent[0]?.type, "toolCall");
568
+ assert.deepEqual((finalContent[0] as any).externalResult, {
569
+ content: [{ type: "text", text: "hi\n" }],
570
+ details: { source: "claude-code" },
571
+ isError: false,
572
+ });
573
+ assert.deepEqual(finalContent[1], { type: "text", text: "All done." });
574
+ });
575
+
576
+ test("buildFinalAssistantContent keeps final-turn tool calls when result arrives without a synthetic user boundary", () => {
577
+ const finalContent = buildFinalAssistantContent({
578
+ intermediateToolBlocks: [],
579
+ pendingContent: [
580
+ {
581
+ type: "toolCall",
582
+ id: "tool-read-1",
583
+ name: "read",
584
+ arguments: { path: "README.md" },
585
+ } as any,
586
+ { type: "text", text: "Read complete." },
587
+ ],
588
+ toolResultsById: new Map([
589
+ [
590
+ "tool-read-1",
591
+ {
592
+ content: [{ type: "text", text: "file contents" }],
593
+ details: { path: "README.md" },
594
+ isError: false,
595
+ },
596
+ ],
597
+ ]),
598
+ });
599
+
600
+ assert.equal(finalContent[0]?.type, "toolCall");
601
+ assert.deepEqual((finalContent[0] as any).externalResult, {
602
+ content: [{ type: "text", text: "file contents" }],
603
+ details: { path: "README.md" },
604
+ isError: false,
605
+ });
606
+ assert.deepEqual(finalContent[1], { type: "text", text: "Read complete." });
607
+ });
542
608
  });
543
609
 
544
610
  describe("stream-adapter — session persistence (#2859)", () => {
@@ -695,15 +761,18 @@ describe("stream-adapter — session persistence (#2859)", () => {
695
761
  assert.equal(srv.env.GSD_CLI_PATH, "/tmp/gsd");
696
762
  assert.equal(srv.env.GSD_PERSIST_WRITE_GATE_STATE, "1");
697
763
  assert.equal(srv.env.GSD_WORKFLOW_PROJECT_ROOT, "/tmp/project");
698
- assert.deepEqual(options.disallowedTools, ["AskUserQuestion"]);
764
+ assert.deepEqual(options.disallowedTools, []);
699
765
  assert.deepEqual(options.allowedTools, [
700
766
  "Read",
701
767
  "Write",
702
768
  "Edit",
703
769
  "Glob",
704
770
  "Grep",
705
- "Bash(ls:*)",
706
- "Bash(pwd)",
771
+ "Bash",
772
+ "Agent",
773
+ "WebFetch",
774
+ "WebSearch",
775
+ "AskUserQuestion",
707
776
  "mcp__gsd-workflow__*",
708
777
  ]);
709
778
  } finally {
@@ -715,7 +784,7 @@ describe("stream-adapter — session persistence (#2859)", () => {
715
784
  }
716
785
  });
717
786
 
718
- test("buildSdkOptions disables AskUserQuestion for custom workflow MCP server names", () => {
787
+ test("buildSdkOptions auto-approves every tool for custom workflow MCP server names", () => {
719
788
  const prev = {
720
789
  GSD_WORKFLOW_MCP_COMMAND: process.env.GSD_WORKFLOW_MCP_COMMAND,
721
790
  GSD_WORKFLOW_MCP_NAME: process.env.GSD_WORKFLOW_MCP_NAME,
@@ -733,15 +802,18 @@ describe("stream-adapter — session persistence (#2859)", () => {
733
802
  const options = buildSdkOptions("claude-sonnet-4-20250514", "test");
734
803
  const mcpServers = options.mcpServers as Record<string, any>;
735
804
  assert.ok(mcpServers?.["custom-workflow"], "expected custom workflow server config");
736
- assert.deepEqual(options.disallowedTools, ["AskUserQuestion"]);
805
+ assert.deepEqual(options.disallowedTools, []);
737
806
  assert.deepEqual(options.allowedTools, [
738
807
  "Read",
739
808
  "Write",
740
809
  "Edit",
741
810
  "Glob",
742
811
  "Grep",
743
- "Bash(ls:*)",
744
- "Bash(pwd)",
812
+ "Bash",
813
+ "Agent",
814
+ "WebFetch",
815
+ "WebSearch",
816
+ "AskUserQuestion",
745
817
  "mcp__custom-workflow__*",
746
818
  ]);
747
819
  } finally {
@@ -779,9 +851,9 @@ describe("stream-adapter — session persistence (#2859)", () => {
779
851
  const mcpServers = (options as any).mcpServers;
780
852
  if (mcpServers) {
781
853
  assert.ok(mcpServers["gsd-workflow"], "if present, must be gsd-workflow");
782
- assert.deepEqual((options as any).disallowedTools, ["AskUserQuestion"]);
854
+ assert.deepEqual((options as any).disallowedTools, []);
783
855
  } else {
784
- assert.deepEqual((options as any).disallowedTools, ["AskUserQuestion"]);
856
+ assert.deepEqual((options as any).disallowedTools, []);
785
857
  }
786
858
  rmSync(emptyDir, { recursive: true, force: true });
787
859
  } finally {
@@ -828,7 +900,7 @@ describe("stream-adapter — session persistence (#2859)", () => {
828
900
  assert.equal(srv.env.GSD_CLI_PATH, "/tmp/gsd");
829
901
  assert.equal(srv.env.GSD_PERSIST_WRITE_GATE_STATE, "1");
830
902
  assert.equal(srv.env.GSD_WORKFLOW_PROJECT_ROOT, resolvedRepoDir);
831
- assert.deepEqual(options.disallowedTools, ["AskUserQuestion"]);
903
+ assert.deepEqual(options.disallowedTools, []);
832
904
  } finally {
833
905
  process.chdir(originalCwd);
834
906
  rmSync(repoDir, { recursive: true, force: true });
@@ -1216,11 +1288,15 @@ describe("stream-adapter — permission mode (F10)", () => {
1216
1288
  }
1217
1289
  }
1218
1290
 
1219
- test("buildSdkOptions defaults to bypassPermissions for backwards compatibility", () => {
1291
+ test("buildSdkOptions defaults to bypassPermissions (globally unblocks all tools)", () => {
1220
1292
  clearWorkflowMcpEnv();
1221
1293
  const opts = buildSdkOptions("claude-sonnet-4-6", "test");
1222
1294
  assert.equal(opts.permissionMode, "bypassPermissions");
1223
- assert.equal(opts.allowDangerouslySkipPermissions, true);
1295
+ assert.equal(
1296
+ opts.allowDangerouslySkipPermissions,
1297
+ true,
1298
+ "allowDangerouslySkipPermissions must be true when permissionMode is bypassPermissions",
1299
+ );
1224
1300
  });
1225
1301
 
1226
1302
  test("buildSdkOptions respects explicit acceptEdits override", () => {
@@ -1234,6 +1310,11 @@ describe("stream-adapter — permission mode (F10)", () => {
1234
1310
  );
1235
1311
  });
1236
1312
 
1313
+ test("resolveClaudePermissionMode defaults to bypassPermissions when no env var is set (globally unblocks all tools)", async () => {
1314
+ const mode = await resolveClaudePermissionMode({});
1315
+ assert.equal(mode, "bypassPermissions");
1316
+ });
1317
+
1237
1318
  test("resolveClaudePermissionMode honours the GSD_CLAUDE_CODE_PERMISSION_MODE env override", async () => {
1238
1319
  const env = { GSD_CLAUDE_CODE_PERMISSION_MODE: "acceptEdits" } as NodeJS.ProcessEnv;
1239
1320
  const mode = await resolveClaudePermissionMode(env);
@@ -1249,6 +1330,27 @@ describe("stream-adapter — permission mode (F10)", () => {
1249
1330
  `expected bypass or acceptEdits, got ${mode}`,
1250
1331
  );
1251
1332
  });
1333
+
1334
+ test("resolveClaudePermissionMode flips to bypassPermissions when GSD_HEADLESS=1 (#4657)", async () => {
1335
+ const originalWarn = console.warn;
1336
+ console.warn = () => {};
1337
+ try {
1338
+ const env = { GSD_HEADLESS: "1" } as NodeJS.ProcessEnv;
1339
+ const mode = await resolveClaudePermissionMode(env);
1340
+ assert.equal(mode, "bypassPermissions");
1341
+ } finally {
1342
+ console.warn = originalWarn;
1343
+ }
1344
+ });
1345
+
1346
+ test("resolveClaudePermissionMode: explicit override wins over GSD_HEADLESS=1", async () => {
1347
+ const env = {
1348
+ GSD_HEADLESS: "1",
1349
+ GSD_CLAUDE_CODE_PERMISSION_MODE: "acceptEdits",
1350
+ } as NodeJS.ProcessEnv;
1351
+ const mode = await resolveClaudePermissionMode(env);
1352
+ assert.equal(mode, "acceptEdits");
1353
+ });
1252
1354
  });
1253
1355
 
1254
1356
  describe("stream-adapter — Windows Claude path lookup (#3770)", () => {