commandmate 0.30.1 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +164 -164
  3. package/.next/app-path-routes-manifest.json +28 -28
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +9 -9
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update-check/route.js +1 -1
  12. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/assistant/conversation/route.js +1 -1
  14. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  15. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/assistant/current-output/route.js +1 -1
  17. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  18. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/assistant/messages/route.js +1 -1
  20. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  21. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/assistant/session/route.js +1 -1
  23. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  24. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/assistant/start/route.js +3 -3
  26. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  27. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/assistant/terminal/route.js +4 -4
  29. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  30. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/assistant/tools/route.js +1 -1
  32. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  33. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/capabilities/route.js +1 -1
  38. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  47. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  48. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/hooks/claude-done/route.js +1 -1
  50. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  51. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  53. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  54. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  55. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  65. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  66. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/repositories/clone/route.js +1 -1
  68. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  69. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/restore/route.js +1 -1
  72. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  73. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/repositories/route.js +1 -1
  75. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  76. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/repositories/scan/route.js +1 -1
  78. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  79. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/repositories/sync/route.js +1 -1
  81. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  82. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/settings/default-agents/route.js +1 -1
  85. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  86. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/skills/[id]/route.js +1 -1
  90. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/skills/route.js +1 -1
  95. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/slash-commands/route.js +1 -1
  97. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  107. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  110. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  113. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  119. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  150. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  153. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  156. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  168. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  172. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  175. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +4 -3
  177. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  179. package/.next/server/app/api/worktrees/[id]/schedules/route.js +4 -3
  180. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  184. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +2 -2
  186. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  187. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  199. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  203. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  207. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  211. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  212. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  215. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  218. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  219. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  220. package/.next/server/app/api/worktrees/route.js +1 -1
  221. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  222. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  223. package/.next/server/app/chat/page.js +2 -2
  224. package/.next/server/app/chat/page.js.nft.json +1 -1
  225. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  226. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  227. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/more/page.js +2 -2
  229. package/.next/server/app/more/page.js.nft.json +1 -1
  230. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  231. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  232. package/.next/server/app/page.js +1 -1
  233. package/.next/server/app/page.js.nft.json +1 -1
  234. package/.next/server/app/page_client-reference-manifest.js +1 -1
  235. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  236. package/.next/server/app/repositories/page.js +2 -2
  237. package/.next/server/app/repositories/page.js.nft.json +1 -1
  238. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  239. package/.next/server/app/review/page.js +1 -1
  240. package/.next/server/app/review/page.js.nft.json +1 -1
  241. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  242. package/.next/server/app/sessions/page.js +1 -1
  243. package/.next/server/app/sessions/page.js.nft.json +1 -1
  244. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  245. package/.next/server/app/skills/[skillId]/page.js +2 -2
  246. package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
  247. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  248. package/.next/server/app/skills/installed/page.js +2 -2
  249. package/.next/server/app/skills/installed/page.js.nft.json +1 -1
  250. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  251. package/.next/server/app/skills/page.js +1 -1
  252. package/.next/server/app/skills/page.js.nft.json +1 -1
  253. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  254. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  255. package/.next/server/app/worktrees/[id]/page.js +10 -10
  256. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  257. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  258. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  259. package/.next/server/app-paths-manifest.json +28 -28
  260. package/.next/server/chunks/1058.js +1 -1
  261. package/.next/server/chunks/1068.js +1 -1
  262. package/.next/server/chunks/1262.js +1 -1
  263. package/.next/server/chunks/1886.js +3 -3
  264. package/.next/server/chunks/1990.js +103 -0
  265. package/.next/server/chunks/2119.js +1 -1
  266. package/.next/server/chunks/2328.js +1 -1
  267. package/.next/server/chunks/2404.js +1 -1
  268. package/.next/server/chunks/2445.js +1 -1
  269. package/.next/server/chunks/261.js +1 -1
  270. package/.next/server/chunks/3123.js +1 -1
  271. package/.next/server/chunks/3241.js +1 -1
  272. package/.next/server/chunks/3480.js +5 -4
  273. package/.next/server/chunks/4299.js +1 -1
  274. package/.next/server/chunks/4393.js +1 -1
  275. package/.next/server/chunks/4443.js +1 -5
  276. package/.next/server/chunks/5017.js +1 -1
  277. package/.next/server/chunks/5043.js +1 -1
  278. package/.next/server/chunks/5164.js +1 -1
  279. package/.next/server/chunks/552.js +2 -2
  280. package/.next/server/chunks/6072.js +1 -1
  281. package/.next/server/chunks/6130.js +1 -1
  282. package/.next/server/chunks/663.js +4 -3
  283. package/.next/server/chunks/6894.js +2 -2
  284. package/.next/server/chunks/7187.js +1 -0
  285. package/.next/server/chunks/7472.js +1 -1
  286. package/.next/server/chunks/{880.js → 7859.js} +6 -6
  287. package/.next/server/chunks/7905.js +1 -1
  288. package/.next/server/chunks/8800.js +2 -2
  289. package/.next/server/chunks/8918.js +7 -0
  290. package/.next/server/chunks/9123.js +2 -2
  291. package/.next/server/chunks/9130.js +4 -4
  292. package/.next/server/chunks/9627.js +1 -1
  293. package/.next/server/chunks/9696.js +2 -2
  294. package/.next/server/chunks/9798.js +1 -1
  295. package/.next/server/middleware-manifest.json +5 -5
  296. package/.next/server/pages/500.html +1 -1
  297. package/.next/server/server-reference-manifest.json +1 -1
  298. package/.next/static/chunks/1783-11c9b4d8a52ebd91.js +1 -0
  299. package/.next/static/chunks/4718-de1224c9e8a6e7fc.js +1 -0
  300. package/.next/static/chunks/6022-2fa0b5a82d4ce7b6.js +1 -0
  301. package/.next/static/chunks/{5229-6c89475b61bd2c8b.js → 6170-951b9f5fe6b4b3b5.js} +1 -1
  302. package/.next/static/chunks/app/chat/{page-9aa2011410895b0d.js → page-37d7615d17d7e2a0.js} +1 -1
  303. package/.next/static/chunks/app/layout-4c2f21e3f653ee4c.js +1 -0
  304. package/.next/static/chunks/app/more/{page-333bba1c8bbc9c11.js → page-353a3924e6d7968e.js} +1 -1
  305. package/.next/static/chunks/app/{page-214f7ffa13a0cf10.js → page-c2bf871d953a1d6f.js} +1 -1
  306. package/.next/static/chunks/app/repositories/{page-4951cac905e50224.js → page-7d0f26df0537254c.js} +1 -1
  307. package/.next/static/chunks/app/review/{page-a0899b2d285318c3.js → page-e3f141b2829973e9.js} +1 -1
  308. package/.next/static/chunks/app/sessions/{page-fb36145ec732092a.js → page-53f188ed9ca49e5f.js} +1 -1
  309. package/.next/static/chunks/app/skills/[skillId]/{page-9099e26b60442873.js → page-80569b720aea59cc.js} +1 -1
  310. package/.next/static/chunks/app/skills/installed/{page-182e32368696d824.js → page-dbd2690ad72da95b.js} +1 -1
  311. package/.next/static/chunks/app/skills/{page-d3fdc88239ebe0ab.js → page-dacd36f9c11aa7da.js} +1 -1
  312. package/.next/static/chunks/app/worktrees/[id]/page-97205088520255a5.js +1 -0
  313. package/.next/static/css/5c13ea243dfdcb66.css +1 -0
  314. package/.next/trace +13 -13
  315. package/README.md +37 -11
  316. package/dist/cli/commands/attach.d.ts +50 -0
  317. package/dist/cli/commands/attach.d.ts.map +1 -0
  318. package/dist/cli/commands/attach.js +204 -0
  319. package/dist/cli/commands/capture.d.ts.map +1 -1
  320. package/dist/cli/commands/capture.js +114 -0
  321. package/dist/cli/commands/instances.d.ts.map +1 -1
  322. package/dist/cli/commands/instances.js +23 -2
  323. package/dist/cli/commands/ls.d.ts.map +1 -1
  324. package/dist/cli/commands/ls.js +41 -1
  325. package/dist/cli/config/cli-dependencies.d.ts.map +1 -1
  326. package/dist/cli/config/cli-dependencies.js +34 -0
  327. package/dist/cli/program.d.ts.map +1 -1
  328. package/dist/cli/program.js +5 -0
  329. package/dist/cli/types/index.d.ts +36 -0
  330. package/dist/cli/types/index.d.ts.map +1 -1
  331. package/dist/config/tmux-pane-config.d.ts +153 -0
  332. package/dist/config/tmux-pane-config.d.ts.map +1 -0
  333. package/dist/config/tmux-pane-config.js +172 -0
  334. package/dist/lib/cli-tools/session-name.d.ts +44 -0
  335. package/dist/lib/cli-tools/session-name.d.ts.map +1 -0
  336. package/dist/lib/cli-tools/session-name.js +57 -0
  337. package/dist/lib/cli-tools/types.d.ts +1 -1
  338. package/dist/lib/cli-tools/types.d.ts.map +1 -1
  339. package/dist/lib/cli-tools/types.js +6 -1
  340. package/dist/lib/cli-tools/validation.d.ts +34 -0
  341. package/dist/lib/cli-tools/validation.d.ts.map +1 -0
  342. package/dist/lib/cli-tools/validation.js +41 -0
  343. package/dist/lib/detection/status-reason.d.ts +18 -0
  344. package/dist/lib/detection/status-reason.d.ts.map +1 -1
  345. package/dist/lib/detection/status-reason.js +18 -0
  346. package/dist/lib/detection/tools/verified-against.d.ts +57 -7
  347. package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
  348. package/dist/lib/detection/tools/verified-against.js +59 -8
  349. package/dist/lib/detection/version-probes.d.ts +26 -5
  350. package/dist/lib/detection/version-probes.d.ts.map +1 -1
  351. package/dist/lib/detection/version-probes.js +28 -6
  352. package/dist/lib/session/tmux-session-surface.d.ts +369 -0
  353. package/dist/lib/session/tmux-session-surface.d.ts.map +1 -0
  354. package/dist/lib/session/tmux-session-surface.js +525 -0
  355. package/dist/server/src/config/cli-tool-timing-config.js +12 -1
  356. package/dist/server/src/config/detection-evidence-config.js +5 -0
  357. package/dist/server/src/config/schedule-config.js +28 -1
  358. package/dist/server/src/lib/cli-tools/antigravity.js +2 -2
  359. package/dist/server/src/lib/cli-tools/base.js +13 -8
  360. package/dist/server/src/lib/cli-tools/claude.js +20 -0
  361. package/dist/server/src/lib/cli-tools/codex.js +205 -61
  362. package/dist/server/src/lib/cli-tools/command-code.js +349 -0
  363. package/dist/server/src/lib/cli-tools/composer-spec.js +6 -0
  364. package/dist/server/src/lib/cli-tools/copilot.js +2 -2
  365. package/dist/server/src/lib/cli-tools/gemini.js +2 -2
  366. package/dist/server/src/lib/cli-tools/graceful-exit.js +16 -1
  367. package/dist/server/src/lib/cli-tools/index.js +4 -1
  368. package/dist/server/src/lib/cli-tools/install-hints.js +131 -0
  369. package/dist/server/src/lib/cli-tools/liveness-spec.js +18 -0
  370. package/dist/server/src/lib/cli-tools/manager.js +2 -0
  371. package/dist/server/src/lib/cli-tools/opencode.js +2 -2
  372. package/dist/server/src/lib/cli-tools/start-availability.js +18 -11
  373. package/dist/server/src/lib/cli-tools/types.js +6 -1
  374. package/dist/server/src/lib/cli-tools/vibe-local.js +2 -2
  375. package/dist/server/src/lib/cmate-parser.js +6 -0
  376. package/dist/server/src/lib/detection/cli-patterns.js +441 -8
  377. package/dist/server/src/lib/detection/opencode-modal-overlay.js +66 -100
  378. package/dist/server/src/lib/detection/selection-shape.js +341 -0
  379. package/dist/server/src/lib/detection/sgr-background.js +210 -0
  380. package/dist/server/src/lib/detection/status-detector.js +6 -0
  381. package/dist/server/src/lib/detection/status-reason.js +18 -0
  382. package/dist/server/src/lib/detection/tools/antigravity/detect.js +38 -15
  383. package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +392 -0
  384. package/dist/server/src/lib/detection/tools/codex/detect.js +83 -2
  385. package/dist/server/src/lib/detection/tools/command-code/detect.js +159 -0
  386. package/dist/server/src/lib/detection/tools/registry.js +6 -4
  387. package/dist/server/src/lib/detection/tools/verified-against.js +59 -8
  388. package/dist/server/src/lib/detection/version-probes.js +28 -6
  389. package/dist/server/src/lib/hooks/sources/antigravity/history.js +101 -21
  390. package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +39 -0
  391. package/dist/server/src/lib/hooks/sources/claude/history.js +245 -21
  392. package/dist/server/src/lib/hooks/sources/claude/transcript.js +175 -13
  393. package/dist/server/src/lib/hooks/sources/codex/history.js +84 -15
  394. package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +130 -17
  395. package/dist/server/src/lib/hooks/sources/codex/relay-install.js +145 -0
  396. package/dist/server/src/lib/hooks/sources/command-code/history.js +865 -0
  397. package/dist/server/src/lib/hooks/sources/command-code/hooks-config.js +390 -0
  398. package/dist/server/src/lib/hooks/sources/command-code/source.js +290 -0
  399. package/dist/server/src/lib/hooks/sources/command-code/tool-id.js +18 -0
  400. package/dist/server/src/lib/hooks/sources/command-code/transcript.js +604 -0
  401. package/dist/server/src/lib/hooks/sources/index.js +3 -1
  402. package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -3
  403. package/dist/server/src/lib/hooks/sources/opencode/transcript.js +24 -28
  404. package/dist/server/src/lib/hooks/sources/registry.js +4 -0
  405. package/dist/server/src/lib/hooks/sources/turn-body.js +77 -19
  406. package/dist/server/src/lib/hooks/stop-history-capture.js +58 -25
  407. package/dist/server/src/lib/job-executor.js +12 -0
  408. package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +6 -0
  409. package/dist/server/src/lib/polling/response-checker.js +112 -7
  410. package/dist/server/src/lib/polling/structured-history-gate.js +15 -8
  411. package/dist/server/src/lib/realtime/types.js +15 -5
  412. package/dist/server/src/lib/response-cleaner.js +24 -1
  413. package/dist/server/src/lib/response-extractor.js +11 -0
  414. package/dist/server/src/lib/session/claude-executor.js +223 -4
  415. package/dist/server/src/lib/session/cli-session.js +52 -0
  416. package/dist/server/src/lib/session/tmux-session-surface.js +525 -0
  417. package/dist/server/src/lib/skills/compatibility-matrix.js +117 -1
  418. package/dist/server/src/lib/tmux/geometry-delegation.js +143 -0
  419. package/dist/server/src/lib/tmux/read-mode-pager.js +76 -10
  420. package/dist/server/src/lib/tmux/read-mode.js +44 -2
  421. package/dist/server/src/lib/tmux/session-hook-scripts.js +249 -0
  422. package/dist/server/src/lib/tmux/session-hooks.js +122 -0
  423. package/dist/server/src/lib/tmux/session-status-options.js +213 -0
  424. package/dist/server/src/lib/tmux/tmux.js +79 -2
  425. package/dist/server/src/lib/version-checker.js +110 -0
  426. package/dist/server/src/lib/ws-server.js +16 -10
  427. package/dist/server/src/types/agent-transcript.js +73 -1
  428. package/dist/server/src/types/terminal-keys.js +131 -3
  429. package/dist/types/terminal-keys.d.ts +100 -3
  430. package/dist/types/terminal-keys.d.ts.map +1 -1
  431. package/dist/types/terminal-keys.js +131 -3
  432. package/package.json +1 -1
  433. package/.next/server/chunks/3099.js +0 -5
  434. package/.next/server/chunks/7824.js +0 -1
  435. package/.next/static/chunks/3916-0e929d089282dc5d.js +0 -1
  436. package/.next/static/chunks/6022-7a7d1760fc9814c7.js +0 -1
  437. package/.next/static/chunks/6381-dbf04a99647f6018.js +0 -1
  438. package/.next/static/chunks/app/layout-6a26ea22d5cf03dc.js +0 -1
  439. package/.next/static/chunks/app/worktrees/[id]/page-aac399392ec8c273.js +0 -1
  440. package/.next/static/css/23f9c40ecc458c77.css +0 -1
  441. /package/.next/static/{pcpB4K6KreMzu2qbhvuRY → nXW4dPkpE_9xUf_9ySRff}/_buildManifest.js +0 -0
  442. /package/.next/static/{pcpB4K6KreMzu2qbhvuRY → nXW4dPkpE_9xUf_9ySRff}/_ssgManifest.js +0 -0
@@ -28,6 +28,12 @@ const prompt_dedup_1 = require("./prompt-dedup");
28
28
  const prompt_dedup_state_1 = require("./prompt-dedup-state");
29
29
  const response_dedup_1 = require("./response-dedup");
30
30
  const structured_history_gate_1 = require("./structured-history-gate");
31
+ // Issue #2317 Phase D: while a human holds the pane's geometry, the frame is
32
+ // their terminal (44 rows), not the 1000-row canvas every rule below was
33
+ // measured against. See the block in `checkForResponse` for what that changes.
34
+ const session_name_1 = require("../../lib/cli-tools/session-name");
35
+ const geometry_delegation_1 = require("../../lib/tmux/geometry-delegation");
36
+ const tmux_session_surface_1 = require("../../lib/session/tmux-session-surface");
31
37
  const response_poller_core_1 = require("./response-poller-core");
32
38
  const push_1 = require("../../lib/push");
33
39
  // Issue #1790: imported by deep path, not through `@/lib/push`. Suites that
@@ -246,13 +252,21 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
246
252
  // silently delete another tool's boundary, and a boundary that stops existing
247
253
  // does not fail loudly: it puts terminal furniture back into History.
248
254
  const openCodeCleanLines = cliToolId === 'opencode' ? lines.map(cli_patterns_1.stripAnsi) : null;
255
+ // Issue #2250: Command Code is the fourth. Its landmark is its own — the
256
+ // `❯ Ask your question...` composer fenced by two full-pane rules, with the
257
+ // permission-mode row underneath — and it is load-bearing rather than tidy:
258
+ // that placeholder is drawn with the same `❯ <text>` shape as a transcript
259
+ // echo, so without the boundary `findRecentUserPromptIndex` anchors the turn
260
+ // on the FOOTER and every reply extracts as empty (#1289's defect, verbatim).
249
261
  const chromeStart = cliToolId === 'claude'
250
262
  ? (0, cli_patterns_1.findClaudeChromeStart)(lines)
251
263
  : cliToolId === 'copilot'
252
264
  ? (0, cli_patterns_1.findCopilotChromeStart)(lines)
253
- : openCodeCleanLines
254
- ? (0, cli_patterns_1.findOpenCodeChromeStart)(openCodeCleanLines)
255
- : -1;
265
+ : cliToolId === 'command-code'
266
+ ? (0, cli_patterns_1.findCommandCodeChromeStart)(lines)
267
+ : openCodeCleanLines
268
+ ? (0, cli_patterns_1.findOpenCodeChromeStart)(openCodeCleanLines)
269
+ : -1;
256
270
  const contentEnd = chromeStart >= 0 ? chromeStart : totalLines;
257
271
  const BUFFER_RESET_TOLERANCE = 25;
258
272
  const bufferShrank = totalLines > 0 && lastCapturedLine > BUFFER_RESET_TOLERANCE && (totalLines + BUFFER_RESET_TOLERANCE) < lastCapturedLine;
@@ -330,7 +344,16 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
330
344
  return -1;
331
345
  };
332
346
  // Early check for interactive prompts (before extraction logic)
333
- if (cliToolId === 'claude' || cliToolId === 'codex' || cliToolId === 'copilot') {
347
+ //
348
+ // Issue #2250: `command-code` must be here. Its permission dialog draws its
349
+ // highlighted option as `❯ 1. Yes` and keeps a full-pane rule above the block,
350
+ // so `hasPrompt && hasSeparator && !isThinking` below is TRUE while the dialog
351
+ // is waiting for an answer — the turn would be declared finished and the
352
+ // dialog saved as the reply.
353
+ if (cliToolId === 'claude' ||
354
+ cliToolId === 'codex' ||
355
+ cliToolId === 'copilot' ||
356
+ cliToolId === 'command-code') {
334
357
  const fullOutput = lines.join('\n');
335
358
  const promptDetection = detectPromptWithOptions(fullOutput, cliToolId);
336
359
  if (promptDetection.isPrompt) {
@@ -374,8 +397,15 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
374
397
  ? copilotStatusBar === 'idle'
375
398
  : (cliToolId === 'codex' || cliToolId === 'gemini' || cliToolId === 'vibe-local' || cliToolId === 'antigravity') && hasPrompt && !isThinking;
376
399
  const isClaudeComplete = cliToolId === 'claude' && hasPrompt && hasSeparator && !isThinking;
400
+ // Issue #2250: claude's shape, because Command Code's layout is claude's — the
401
+ // composer sits between two full-pane rules and is drawn only when the agent
402
+ // will accept input. Deliberately NOT keyed on `✻ Worked for`: that row is the
403
+ // live turn's, not the transcript's (it is present in `turn-version.txt` and
404
+ // gone from `dialog-create-file.txt`, the same pane one prompt later) and
405
+ // `WorkedDurationNote` omits it entirely for a turn under 1000 ms.
406
+ const isCommandCodeComplete = cliToolId === 'command-code' && hasPrompt && hasSeparator && !isThinking;
377
407
  const isOpenCodeDone = cliToolId === 'opencode' && (0, response_extractor_1.isOpenCodeComplete)(cleanOutputToCheck);
378
- if (isPromptBasedComplete || isClaudeComplete || isOpenCodeDone) {
408
+ if (isPromptBasedComplete || isClaudeComplete || isCommandCodeComplete || isOpenCodeDone) {
379
409
  const responseLines = [];
380
410
  const startIndex = (0, response_extractor_1.resolveExtractionStartIndex)(lastCapturedLine, totalLines, bufferReset, cliToolId, findRecentUserPromptIndex, captureWindowSaturated);
381
411
  let endIndex = totalLines;
@@ -515,6 +545,30 @@ function extractResponse(output, lastCapturedLine, cliToolId, captureWindowLines
515
545
  return incompleteResult(totalLines);
516
546
  }
517
547
  }
548
+ // Issue #2250: Command Code's launch screen is a complete, idle frame --
549
+ // block-art logo, three `#` banner rows, composer drawn between its two
550
+ // rules -- so every check above accepts it, and History would open with
551
+ // `# Command Code v1.40.1 / # models: … / # <cwd>` saved as the agent's
552
+ // first reply before the operator has said anything.
553
+ //
554
+ // The rule is ONE condition and it is a positive one: Command Code echoes
555
+ // every prompt into the transcript as `❯ <text>`, and the launch screen has
556
+ // none. That is the shape #1897 and #2247 both converged on; the anchor
557
+ // heuristics claude carries above (`hasBannerArt` / `hasVersionInfo` /
558
+ // `hasStartupTips`) are deliberately NOT reproduced here, because they are
559
+ // what #2247 had to take back -- a bare version string in a reply is a
560
+ // normal reply, and Command Code prints its own version on every launch.
561
+ //
562
+ // `findRecentUserPromptIndex` is the same `/^[>❯]\s+\S/` scan the extraction
563
+ // anchors on, and it stops at `contentEnd`, so the composer's own dim
564
+ // `❯ Ask your question...` placeholder cannot be mistaken for an echo
565
+ // (#1879's trap).
566
+ if (cliToolId === 'command-code' && findRecentUserPromptIndex(totalLines) < 0) {
567
+ logger.info('Command Code launch screen suppressed, response not saved', {
568
+ responseLength: response.length,
569
+ });
570
+ return incompleteResult(totalLines);
571
+ }
518
572
  // Gemini-specific check
519
573
  if (cliToolId === 'gemini') {
520
574
  const bannerCharCount = (response.match(/[░███]/g) || []).length;
@@ -631,6 +685,36 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
631
685
  (0, response_poller_core_1.stopPolling)(worktreeId, cliToolId, instanceId);
632
686
  return false;
633
687
  }
688
+ // Issue #2317 Phase D: is a human reading this pane at their own terminal
689
+ // size right now, and did they just stop?
690
+ //
691
+ // Asked only for the tools `attach --live` accepts — no other session can be
692
+ // delegated, so asking about one would be a tmux round-trip per poll with a
693
+ // single possible answer. The read itself is memoised for a second
694
+ // (`DELEGATION_TTL_MS`), which is under one poll interval.
695
+ const sessionName = (0, session_name_1.resolveSessionName)(cliToolId, worktreeId, instanceId);
696
+ const delegation = (0, tmux_session_surface_1.isLiveAttachEligibleSession)(sessionName)
697
+ ? await (0, geometry_delegation_1.probeGeometryDelegation)(sessionName)
698
+ : { delegated: false, released: false };
699
+ if (delegation.released) {
700
+ // The canvas is 1000 rows again, so a cursor recorded against a 44-row
701
+ // frame indexes into a pane that no longer exists. Zero is the only value
702
+ // that cannot be wrong in either direction: too low re-saves a turn, too
703
+ // high suppresses every future one. Done BEFORE the state is read below so
704
+ // this poll already sees the reset.
705
+ //
706
+ // A no-op for claude in practice — it renders in the alternate screen, so
707
+ // `lineCountIsCursor` is false and the cursor is not consulted — and that
708
+ // is exactly why it is written here rather than left implicit: the guard
709
+ // has to already be right on the day a scrollback tool is added to
710
+ // `LIVE_ATTACH_TOOLS`.
711
+ (0, db_1.updateSessionState)(db, worktreeId, cliToolId, 0, resolvedInstanceId);
712
+ logger.info('geometry-delegation-released', {
713
+ worktreeId,
714
+ cliToolId,
715
+ instanceId: resolvedInstanceId,
716
+ });
717
+ }
634
718
  // Get session state (last captured line count)
635
719
  const sessionState = (0, db_1.getSessionState)(db, worktreeId, resolvedInstanceId);
636
720
  const lastCapturedLine = sessionState?.lastCapturedLine || 0;
@@ -891,8 +975,25 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
891
975
  worktreePath: worktree.path,
892
976
  transcriptPathHint: claudeMetadata?.logFilePath ?? null,
893
977
  }));
978
+ // Issue #2317 Phase D: the scrape is dropped while the geometry is
979
+ // delegated, and the transcript capture above is what makes that safe.
980
+ //
981
+ // ORDER IS LOAD-BEARING. The delegation test is folded in AFTER the two
982
+ // calls above rather than short-circuiting them: `captureStructuredHistoryTurn`
983
+ // is a WRITE, not a query — it is the moment claude's own transcript becomes
984
+ // a History row — so an `||` that put the delegation first would suppress
985
+ // the scrape and the real reply together, and the turn would vanish. Read as
986
+ // it stands: record the turn from the agent's own file, then drop the pane's
987
+ // copy of it, which at 44 rows is a fraction of the answer hard-wrapped at
988
+ // the reader's terminal width.
989
+ //
990
+ // When the transcript capture answers false (an unreadable or absent file)
991
+ // the turn goes UNRECORDED for as long as the delegation lasts. That is the
992
+ // deliberate trade: a missing row is recoverable, a truncated reply saved as
993
+ // the agent's answer is not.
994
+ const suppressScrapedHistory = structuredHistoryLive || delegation.delegated;
894
995
  // Create Markdown log file for the conversation pair
895
- if (cleanedResponse && !structuredHistoryLive) {
996
+ if (cleanedResponse && !suppressScrapedHistory) {
896
997
  await (0, conversation_logger_1.recordClaudeConversation)(db, worktreeId, cleanedResponse, cliToolId);
897
998
  }
898
999
  // Mark any pending prompts as answered
@@ -913,7 +1014,7 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
913
1014
  // are not byte-comparable — the pane's copy is hard-wrapped at the pane
914
1015
  // width and gutter-prefixed, so no content check could ever recognise them
915
1016
  // as the same reply.
916
- if (!structuredHistoryLive) {
1017
+ if (!suppressScrapedHistory) {
917
1018
  // Create new CLI tool message in database
918
1019
  const message = (0, db_1.createMessage)(db, {
919
1020
  worktreeId,
@@ -936,6 +1037,10 @@ async function checkForResponse(worktreeId, cliToolId, instanceId) {
936
1037
  cliToolId,
937
1038
  instanceId: resolvedInstanceId,
938
1039
  scrapedLength: cleanedResponse.length,
1040
+ // Which of the two reasons suppressed it. Without this the Phase D case
1041
+ // and the ordinary #2041/#2121 handover are one indistinguishable log
1042
+ // line, and "History is missing a turn" has two very different causes.
1043
+ reason: structuredHistoryLive ? 'structured-history' : 'geometry-delegated',
939
1044
  });
940
1045
  }
941
1046
  // Issue #1790: the agent has just produced a reply, so whatever it was
@@ -1,16 +1,17 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Whether somebody better-informed is already recording this turn (Issue #2041,
4
- * extended for Claude Code in #2121, codex in #2197 and antigravity in #2198).
4
+ * extended for Claude Code in #2121, codex in #2197, antigravity in #2198 and
5
+ * Command Code in #2252).
5
6
  *
6
7
  * The poller's job has always been to be the only writer of conversation
7
- * history, because for most of the six tools the terminal is the only place the
8
- * reply exists. Four of them now have a second writer: opencode publishes its
9
- * replies over the SSE stream CommandMate subscribes to (#1763/#2041), and
10
- * claude, codex and antigravity each keep their own transcript file on disk.
11
- * Two writers for one turn would put the same answer in History twice — once as
12
- * the agent wrote it and once as its TUI drew it — so one of them has to stand
13
- * down, and it is the one reading the screen.
8
+ * history, because for most of the seven tools the terminal is the only place
9
+ * the reply exists. Five of them now have a second writer: opencode publishes
10
+ * its replies over the SSE stream CommandMate subscribes to (#1763/#2041), and
11
+ * claude, codex, antigravity and command-code each keep their own transcript
12
+ * file on disk. Two writers for one turn would put the same answer in History
13
+ * twice — once as the agent wrote it and once as its TUI drew it — so one of
14
+ * them has to stand down, and it is the one reading the screen.
14
15
  *
15
16
  * ## Why this is a module and not an `if`
16
17
  *
@@ -74,9 +75,11 @@ const subscription_1 = require("../../lib/hooks/sources/opencode/subscription");
74
75
  const history_1 = require("../../lib/hooks/sources/claude/history");
75
76
  const history_2 = require("../../lib/hooks/sources/codex/history");
76
77
  const history_3 = require("../../lib/hooks/sources/antigravity/history");
78
+ const history_4 = require("../../lib/hooks/sources/command-code/history");
77
79
  const tool_id_1 = require("../../lib/hooks/sources/claude/tool-id");
78
80
  const tool_id_2 = require("../../lib/hooks/sources/codex/tool-id");
79
81
  const tool_id_3 = require("../../lib/hooks/sources/antigravity/tool-id");
82
+ const tool_id_4 = require("../../lib/hooks/sources/command-code/tool-id");
80
83
  const registry_1 = require("../../lib/hooks/sources/registry");
81
84
  const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate');
82
85
  /**
@@ -168,6 +171,10 @@ const PULL_TRANSCRIPT_READERS = {
168
171
  capture: (target, capture) => (0, history_3.captureAntigravityTranscriptTurn)(target, capture),
169
172
  locate: (target, capture) => (0, history_3.resolveAntigravityTranscriptPath)(target, capture),
170
173
  },
174
+ [tool_id_4.COMMAND_CODE_CLI_TOOL_ID]: {
175
+ capture: (target, capture) => (0, history_4.captureCommandCodeTranscriptTurn)(target, capture),
176
+ locate: (target, capture) => (0, history_4.resolveCommandCodeTranscriptPath)(target, capture),
177
+ },
171
178
  };
172
179
  /**
173
180
  * What this tool's source says about who records its replies.
@@ -20,17 +20,27 @@ exports.parseRealtimeEvent = parseRealtimeEvent;
20
20
  */
21
21
  exports.CLIENT_VERSION_MESSAGE_TYPE = 'client_version';
22
22
  /**
23
- * Server → client notice that the running server version differs from this
24
- * tab's bundle version (#1338/#1356). Drives the reload banner.
23
+ * Server → client notice that the bundle the server now serves was built from a
24
+ * different version than this tab's bundle (#1338/#1356/#2271). Drives the
25
+ * reload banner.
25
26
  */
26
27
  exports.VERSION_MISMATCH_EVENT_TYPE = 'version_mismatch';
27
28
  /**
28
- * Whether the running server version and this tab's bundle version have drifted
29
- * apart and the user should be nudged to reload (#1338/#1356).
29
+ * Whether two **build identities** have drifted apart and the user should be
30
+ * nudged to reload (#1338/#1356).
31
+ *
32
+ * Both arguments are the version a bundle was *built from*, never the version
33
+ * installed on disk. Issue #2271: feeding this the runtime `package.json`
34
+ * version on the server side made it fire permanently for everyone, because the
35
+ * release procedure bumps that file and deliberately does not rebuild the
36
+ * running server's `.next` — so "installed > served" is the steady state after
37
+ * every release rather than evidence of anything. `resolveBundleDrift()` in
38
+ * `@/lib/version-checker` is the one caller that resolves the server side, and
39
+ * it resolves it from the build manifest.
30
40
  *
31
41
  * Conservative on purpose (受入条件: 版が一致している間は誤検知しない): an empty or
32
42
  * `'0.0.0'` fallback on either side means "version unknown" and is never treated
33
- * as a mismatch, so a server that cannot resolve its own version stays silent.
43
+ * as a mismatch, so a server that cannot resolve its own build stays silent.
34
44
  */
35
45
  function isVersionMismatch(serverVersion, clientVersion) {
36
46
  if (!serverVersion || !clientVersion)
@@ -160,8 +160,15 @@ function cleanGeminiResponse(response) {
160
160
  * their own by {@link COPILOT_FOLD_MARKER_PATTERN} and
161
161
  * {@link COPILOT_COMMAND_OUTPUT_PATTERN}, so nothing needs a block that can run
162
162
  * away over a whole message.
163
+ *
164
+ * Issue #2269: the verb list moved to {@link COPILOT_TOOL_VERBS}, which
165
+ * `COPILOT_TOOL_ROW_PATTERN` reads as well. 1.0.82 marks most tool rows with a
166
+ * file-type badge rather than `●` and that pattern owns those; `●` is still the
167
+ * marker for a tool row whose file type has no badge (`● Read d.txt 1 line
168
+ * read`, measured) and for the ask-user row (`● Asked user …`), so both markers
169
+ * have to answer to one vocabulary.
163
170
  */
164
- const COPILOT_TOOL_ACTION_PATTERN = /^●\s+(?:Get |Read |Run |Search |Write |Edit |Delete |List |Create |Fetch |Explore |Execute |Install |Model changed to:)/;
171
+ const COPILOT_TOOL_ACTION_PATTERN = new RegExp(`^●\\s+(?:${cli_patterns_1.COPILOT_TOOL_VERBS})[\\s:]`);
165
172
  /**
166
173
  * copilot 1.0.80's tool invocation row (Issue #1897).
167
174
  *
@@ -263,6 +270,22 @@ function cleanCopilotResponse(response) {
263
270
  let inThinkingBlock = false;
264
271
  let inToolOutputBlock = false;
265
272
  for (const line of responseLines) {
273
+ // Issue #2269: tested BEFORE normalisation, for the reason #1897 records at
274
+ // COPILOT_BOX_ROW_PATTERN and then only acted on in the accumulator:
275
+ // `normalizeCopilotLine` deletes every U+2500..U+257F glyph, so by the time
276
+ // COPILOT_SKIP_PATTERNS runs below, every glyph-anchored rule in it is dead
277
+ // in THIS function. That is what let two rows of copilot's launch screen
278
+ // through -- ` ╰─╯╰─╯ Copilot v1.0.82 uses AI.` cleans to a bare version
279
+ // string (1.0.82 split the one-line disclaimer the exact-match rule was
280
+ // written for), and ` └ Enable all permissions …` cleans to prose -- on
281
+ // every call that receives a raw frame rather than accumulated content.
282
+ //
283
+ // Deliberately not resetting the block flags: the reasoning block's own rows
284
+ // are `│ <chain of thought>`, so a box row is the middle of a block far more
285
+ // often than the end of one. That is the behaviour the dead `/^[│└]/` rule
286
+ // below was written with, and this is the live version of it.
287
+ if (cli_patterns_1.COPILOT_BOX_ROW_PATTERN.test(line))
288
+ continue;
266
289
  // Normalize using the same function as TUI accumulator (DRY)
267
290
  const normalized = (0, tui_accumulator_1.normalizeCopilotLine)(line);
268
291
  if (!normalized) {
@@ -203,6 +203,17 @@ function resolveExtractionStartIndex(lastCapturedLine, totalLines, bufferReset,
203
203
  const foundUserPrompt = findRecentUserPromptIndex(totalLines);
204
204
  return foundUserPrompt >= 0 ? foundUserPrompt + 1 : Math.max(0, lastCapturedLine);
205
205
  }
206
+ // Branch 2a''' (Command Code, Issue #2250): same reasoning as agy's above.
207
+ // Command Code is inline-rendered (`#{alternate_on}` = 0, scrollback kept), so
208
+ // `lastCapturedLine` is a real cursor and stays the fallback; but the echo
209
+ // `❯ <message>` is present in every captured turn and is the cleaner boundary,
210
+ // and the caller has already excluded the composer from the search window by
211
+ // trimming the chrome, so the echo this finds is a transcript row rather than
212
+ // the placeholder in the input box.
213
+ if (cliToolId === 'command-code') {
214
+ const foundUserPrompt = findRecentUserPromptIndex(totalLines);
215
+ return foundUserPrompt >= 0 ? foundUserPrompt + 1 : Math.max(0, lastCapturedLine);
216
+ }
206
217
  // Compute bufferWasReset internally (MF-001: responsibility boundary)
207
218
  const bufferWasReset = lastCapturedLine >= totalLines || bufferReset;
208
219
  // Branch 1: Buffer was reset - find the most recent user prompt as anchor
@@ -4,7 +4,7 @@
4
4
  * Issue #294: Executes CLI tool commands for scheduled executions
5
5
  * Issue #379: Added OpenCode support (opencode run)
6
6
  *
7
- * Supported tools: claude, codex, gemini, vibe-local, opencode, copilot, antigravity
7
+ * Supported tools: claude, codex, gemini, vibe-local, opencode, copilot, antigravity, command-code
8
8
  *
9
9
  * Security:
10
10
  * - Uses execFile (not exec) to prevent shell injection
@@ -14,11 +14,13 @@
14
14
  * - Validates cliToolId against ALLOWED_CLI_TOOLS whitelist [SEC-001]
15
15
  */
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.ALLOWED_CLI_TOOLS = exports.MAX_MESSAGE_LENGTH = exports.EXECUTION_TIMEOUT_MS = exports.MAX_STORED_OUTPUT_SIZE = exports.MAX_OUTPUT_SIZE = void 0;
17
+ exports.COMMAND_CODE_EXIT_REASONS = exports.ALLOWED_CLI_TOOLS = exports.MAX_MESSAGE_LENGTH = exports.EXECUTION_TIMEOUT_MS = exports.MAX_STORED_OUTPUT_SIZE = exports.MAX_OUTPUT_SIZE = void 0;
18
18
  exports.getCommandForTool = getCommandForTool;
19
19
  exports.truncateOutput = truncateOutput;
20
20
  exports.buildCliArgs = buildCliArgs;
21
21
  exports.extractOpencodeFinalText = extractOpencodeFinalText;
22
+ exports.extractCommandCodeResult = extractCommandCodeResult;
23
+ exports.describeCommandCodeFailure = describeCommandCodeFailure;
22
24
  exports.executeClaudeCommand = executeClaudeCommand;
23
25
  exports.getActiveProcesses = getActiveProcesses;
24
26
  const child_process_1 = require("child_process");
@@ -62,6 +64,16 @@ function getCommandForTool(cliToolId) {
62
64
  // Issue #990 (Phase C): Antigravity's executable is `agy`, not the tool id.
63
65
  case 'antigravity':
64
66
  return 'agy';
67
+ // Issue #2253: Command Code ships four bins (`cmd` / `cmdc` / `command-code`
68
+ // / `commandcode`) and Epic #2249 決定 1 picked the unambiguous spelling, so
69
+ // the tool id is not the executable here either. Written as a literal to
70
+ // match the two cases above rather than importing
71
+ // `COMMAND_CODE_COMMAND` from `@/lib/cli-tools/command-code`, which would
72
+ // pull the tmux transport into the scheduler's dependency graph; the unit
73
+ // test imports both and asserts they are the same string, so the copy
74
+ // cannot drift.
75
+ case 'command-code':
76
+ return 'commandcode';
65
77
  default:
66
78
  return cliToolId;
67
79
  }
@@ -94,6 +106,7 @@ function truncateOutput(output) {
94
106
  * - vibe-local: [-p <message> -y] or [--model <model> -p <message> -y]
95
107
  * - opencode: run --format json [-m <model>] [--agent <a>] [--variant <v>] [-c] [--title <t>] <message>
96
108
  * - antigravity: -p <message> --dangerously-skip-permissions
109
+ * - command-code: -p <message> --output-format json [--yolo | --permission-mode <permission>]
97
110
  * - others: -p <message> (fallback)
98
111
  *
99
112
  * @param message - Prompt message
@@ -159,6 +172,44 @@ function buildCliArgs(message, cliToolId, permission, options) {
159
172
  args.push(message);
160
173
  return args;
161
174
  }
175
+ case 'command-code': {
176
+ // Issue #2253 (Epic #2249 Phase D): `commandcode -p <message>` runs one
177
+ // prompt non-interactively. `--output-format json` is unconditional for
178
+ // the same reason opencode's `--format json` is: the text format writes a
179
+ // rendered answer with no frame around it, while the json format ends in a
180
+ // single `{"type":"result",…}` line carrying `finalText` and `subtype`,
181
+ // which is what {@link extractCommandCodeResult} reads.
182
+ //
183
+ // ## `--yolo` and `--permission-mode` are different axes, and exclusive here
184
+ //
185
+ // `commandcode --help` lists them separately, and the shipped option
186
+ // declaration in `command-code@1.40.1/dist/cli.mjs` is
187
+ // `.addOption(new Be('--permission-mode <mode>', …).choices(['default',
188
+ // 'standard','plan','auto-accept','dont-ask']))` with `--yolo` as a plain
189
+ // boolean alias of `--dangerously-skip-permissions`. So `--yolo` is not a
190
+ // *value* of the mode flag, and sending both would ask the CLI to run
191
+ // under a mode and to bypass modes at once. A scheduled run has nobody to
192
+ // answer a permission dialog, so the default is `--yolo` and an explicit
193
+ // permission replaces it rather than joining it.
194
+ //
195
+ // The whitelist check follows copilot's shape (SEC4-001) rather than
196
+ // codex's `??`: a permission the dropdown could not have produced falls
197
+ // back to the unattended default instead of reaching the CLI, where an
198
+ // unknown `--permission-mode` value is a `.choices()` rejection and the
199
+ // run would fail before the prompt was ever sent.
200
+ //
201
+ // `--yolo` does not override `.commandcode/settings.json`
202
+ // `permissions.deny`; a denied tool call still ends the run with exit 4,
203
+ // which {@link describeCommandCodeExit} names in the failure reason.
204
+ const args = ['-p', message, '--output-format', 'json'];
205
+ if (schedule_config_1.COMMAND_CODE_PERMISSIONS.includes(permission)) {
206
+ args.push('--permission-mode', permission);
207
+ }
208
+ else {
209
+ args.push('--yolo');
210
+ }
211
+ return args;
212
+ }
162
213
  case 'antigravity':
163
214
  // Issue #990 (Phase C): `agy -p <message>` runs a single prompt non-interactively.
164
215
  // --dangerously-skip-permissions auto-approves tool use so the process does not
@@ -292,6 +343,134 @@ function renderOpencodeErrorFrame(record) {
292
343
  const message = typeof data.message === 'string' ? data.message : '';
293
344
  return message ? `opencode error: ${name}: ${message}` : `opencode error: ${name}`;
294
345
  }
346
+ // =============================================================================
347
+ // command-code `--output-format json` extraction (Issue #2253)
348
+ // =============================================================================
349
+ /**
350
+ * `PRINT_EXIT_CODE`, read off `command-code@1.40.1/dist/cli.mjs`.
351
+ *
352
+ * The bundle declares it as one object —
353
+ * `{SUCCESS:0, ERROR:1, AUTH_ERROR:3, PERMISSION_DENIED:4, RATE_LIMITED:5,
354
+ * CONNECTION_ERROR:6, SERVER_ERROR:7, MAX_TURNS_REACHED:8, NO_RESPONSE:9,
355
+ * INSUFFICIENT_CREDITS:10, INTERRUPTED:130}` — and `classifyPrintModeError`
356
+ * next to it is what picks between them. Issue #2253 lists six of the eleven;
357
+ * all eleven are recorded here because the point of the map is to turn a bare
358
+ * number in an execution log into a sentence, and a code that falls through
359
+ * produces exactly the log line the map exists to replace.
360
+ *
361
+ * 0 is deliberately absent: success is not a failure reason, and a lookup that
362
+ * answers for it would let a caller render "Reason: success" on a run that
363
+ * worked.
364
+ */
365
+ exports.COMMAND_CODE_EXIT_REASONS = {
366
+ 1: 'error',
367
+ 3: 'authentication failed',
368
+ 4: 'permission denied',
369
+ 5: 'rate limited',
370
+ 6: 'connection error',
371
+ 7: 'server error',
372
+ 8: 'max turns reached',
373
+ 9: 'no response',
374
+ 10: 'insufficient credits',
375
+ 130: 'interrupted',
376
+ };
377
+ /**
378
+ * The result line of `commandcode -p … --output-format json`, or null.
379
+ *
380
+ * ## The measured stream
381
+ *
382
+ * One JSON object per line. Every line but the last is `{"type":"event",…}`;
383
+ * the last is the result. Measured on command-code 1.40.1 (fixtures under
384
+ * `tests/fixtures/command-code/headless/`):
385
+ *
386
+ * ```text
387
+ * {"type":"event","event":{"type":"run_start","sessionId":"…"}}
388
+ * {"type":"event","event":{"type":"text_delta","delta":"OK"}}
389
+ * {"type":"event","event":{"type":"run_end","result":{"finalText":"OK",…}}}
390
+ * {"type":"result","subtype":"success","sessionId":"…","stopReason":"end_turn",
391
+ * "usage":{…},"durationMs":1957,"finalText":"OK"}
392
+ * ```
393
+ *
394
+ * ## Why the last result line rather than `run_end`
395
+ *
396
+ * `run_end` carries a `result.finalText` too, and on a successful run they
397
+ * agree. But `buildPrintResultLine` in the bundle emits the result line on the
398
+ * failure path as well, where no `run_end` was ever produced: an empty query
399
+ * answers with exactly one line,
400
+ * `{"type":"result","subtype":"error",…,"finalText":"","error":"Error: No query
401
+ * provided. …"}`, and nothing else. Reading `run_end` would see nothing there.
402
+ *
403
+ * ## Why it never throws and never invents a result
404
+ *
405
+ * Null means "this stdout carried no result line", which the caller renders as
406
+ * raw output rather than as an empty answer — the state a run that dies before
407
+ * `runPrintMode` is actually in (`--model <unknown>` exits 1 with **empty
408
+ * stdout** and the message only on stderr). Unparseable lines are skipped for
409
+ * the reason the opencode reader skips them: a stray `console.log` from a mod
410
+ * lands on the same stdout as the stream.
411
+ *
412
+ * @param stdout - Raw stdout from `commandcode -p … --output-format json`
413
+ * @returns The decoded result line, or null when stdout carried none
414
+ */
415
+ function extractCommandCodeResult(stdout) {
416
+ let found = null;
417
+ for (const line of stdout.split('\n')) {
418
+ const trimmed = line.trim();
419
+ if (!trimmed.startsWith('{'))
420
+ continue;
421
+ let frame;
422
+ try {
423
+ frame = JSON.parse(trimmed);
424
+ }
425
+ catch {
426
+ continue;
427
+ }
428
+ if (typeof frame !== 'object' || frame === null)
429
+ continue;
430
+ const record = frame;
431
+ if (record.type !== 'result')
432
+ continue;
433
+ if (typeof record.subtype !== 'string')
434
+ continue;
435
+ found = {
436
+ subtype: record.subtype,
437
+ finalText: typeof record.finalText === 'string' ? record.finalText : '',
438
+ ...(typeof record.error === 'string' ? { error: record.error } : {}),
439
+ };
440
+ }
441
+ return found;
442
+ }
443
+ /**
444
+ * One line naming why a Command Code run failed, or null when it did not.
445
+ *
446
+ * Both halves are load-bearing, because the CLI can disagree with itself. A run
447
+ * whose answer is blank exits `NO_RESPONSE` (9) while `buildPrintResultLine`
448
+ * still stamps `subtype: "success"` — the subtype is derived from `stopReason`
449
+ * and the exit code from `classifyPrintOutcome`, and only the pair says what
450
+ * happened. So a non-zero exit is a failure whatever the subtype says, and a
451
+ * subtype other than `success` is a failure whatever the exit code says.
452
+ *
453
+ * @param exitCode - Process exit code (null when killed by a signal)
454
+ * @param result - Decoded result line, when stdout carried one
455
+ * @returns A `Reason: …` sentence, or null when the run succeeded
456
+ */
457
+ function describeCommandCodeFailure(exitCode, result) {
458
+ const failedByCode = exitCode !== null && exitCode !== 0;
459
+ const failedBySubtype = result !== null && result.subtype !== 'success';
460
+ if (!failedByCode && !failedBySubtype)
461
+ return null;
462
+ const parts = [];
463
+ if (exitCode !== null && exitCode !== 0) {
464
+ const reason = exports.COMMAND_CODE_EXIT_REASONS[exitCode];
465
+ parts.push(reason ? `exit ${exitCode} (${reason})` : `exit ${exitCode}`);
466
+ }
467
+ if (result) {
468
+ parts.push(`subtype=${result.subtype}`);
469
+ if (result.error)
470
+ parts.push(result.error);
471
+ }
472
+ return `Reason: command-code ${parts.join(' / ')}`;
473
+ }
295
474
  /**
296
475
  * Execute a CLI command in a worktree directory.
297
476
  *
@@ -332,23 +511,43 @@ async function executeClaudeCommand(message, cwd, cliToolId = 'claude', permissi
332
511
  const isMaxBuffer = errCode === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER';
333
512
  // maxBuffer 超過は時間切れではなく「出力過多」なので timeout 扱いにしない。
334
513
  const isTimeout = error.killed || errCode === 'ETIMEDOUT';
514
+ // Issue #2253: command-code writes its whole NDJSON stream *and* a
515
+ // final result line before exiting non-zero — a max-turns run ends at
516
+ // exit 8 with a complete `{"type":"result","subtype":"max_turns",…}`
517
+ // line — so the answer and the CLI's own reason are on stdout even
518
+ // here. Decoding them turns a log that said "Error: Command failed"
519
+ // over a 4KB event dump into the reason plus the text.
520
+ const commandCodeResult = cliToolId === 'command-code'
521
+ ? extractCommandCodeResult(stdout || '')
522
+ : null;
523
+ const exitCodeNumber = typeof errCode === 'number' ? errCode : null;
335
524
  const errorSummary = [
336
525
  `Error: ${error.message}`,
337
526
  `Code: ${errCode ?? 'unknown'}`,
338
527
  `Signal: ${error.signal ?? 'none'}`,
339
528
  isMaxBuffer ? 'Reason: stdout exceeded execFile maxBuffer (output_limit)' : null,
529
+ cliToolId === 'command-code'
530
+ ? describeCommandCodeFailure(exitCodeNumber, commandCodeResult)
531
+ : null,
340
532
  ]
341
533
  .filter((line) => line !== null)
342
534
  .join('\n');
535
+ // `?? stdout` on purpose, matching the success path: a run that died
536
+ // before it could write a result line (an unknown `--model` exits 1
537
+ // with empty stdout and the message on stderr) reports what it did
538
+ // write rather than an empty body.
539
+ const decodedStdout = commandCodeResult
540
+ ? commandCodeResult.finalText
541
+ : (stdout || '');
343
542
  const rawOutput = (0, cli_patterns_1.stripAnsi)([
344
543
  errorSummary,
345
- stdout ? `\n--- stdout ---\n${stdout}` : '',
544
+ decodedStdout ? `\n--- stdout ---\n${decodedStdout}` : '',
346
545
  stderr ? `\n--- stderr ---\n${stderr}` : '',
347
546
  ].join('\n'));
348
547
  const output = truncateOutput(rawOutput);
349
548
  resolve({
350
549
  output,
351
- exitCode: typeof errCode === 'number' ? errCode : null,
550
+ exitCode: exitCodeNumber,
352
551
  status: isTimeout ? 'timeout' : 'failed',
353
552
  error: error.message,
354
553
  });
@@ -358,6 +557,26 @@ async function executeClaudeCommand(message, cwd, cliToolId = 'claude', permissi
358
557
  // stored output is the assistant's answer rather than the event log.
359
558
  // `?? stdout` on purpose: an unrecognised stream is reported verbatim,
360
559
  // never swallowed.
560
+ //
561
+ // Issue #2253: command-code is the same deal one flag over
562
+ // (`--output-format json`), except that its stream also carries the
563
+ // CLI's own verdict. `classifyPrintOutcome` in the bundle can exit 0
564
+ // only on `subtype: "success"`, so this branch is the success case in
565
+ // practice — but the subtype is read rather than assumed, because
566
+ // "the process exited 0" and "the agent answered" are two facts and
567
+ // this layer is the only one that can still see the second.
568
+ if (cliToolId === 'command-code') {
569
+ const result = extractCommandCodeResult(stdout || '');
570
+ const failure = describeCommandCodeFailure(0, result);
571
+ const body = result ? result.finalText : (stdout || '');
572
+ resolve({
573
+ output: truncateOutput((0, cli_patterns_1.stripAnsi)(failure ? `${failure}\n${body}` : body)),
574
+ exitCode: 0,
575
+ status: failure ? 'failed' : 'completed',
576
+ ...(failure ? { error: failure } : {}),
577
+ });
578
+ return;
579
+ }
361
580
  const decoded = cliToolId === 'opencode'
362
581
  ? extractOpencodeFinalText(stdout || '') ?? stdout ?? ''
363
582
  : stdout || '';