commandmate 0.30.2 → 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 (440) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +160 -160
  3. package/.next/app-path-routes-manifest.json +27 -27
  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 +27 -27
  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 +1 -1
  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/pages-manifest.json +1 -1
  298. package/.next/server/server-reference-manifest.json +1 -1
  299. package/.next/static/chunks/1783-11c9b4d8a52ebd91.js +1 -0
  300. package/.next/static/chunks/4718-de1224c9e8a6e7fc.js +1 -0
  301. package/.next/static/chunks/6022-2fa0b5a82d4ce7b6.js +1 -0
  302. package/.next/static/chunks/{5229-6c89475b61bd2c8b.js → 6170-951b9f5fe6b4b3b5.js} +1 -1
  303. package/.next/static/chunks/app/chat/{page-9aa2011410895b0d.js → page-37d7615d17d7e2a0.js} +1 -1
  304. package/.next/static/chunks/app/layout-4c2f21e3f653ee4c.js +1 -0
  305. package/.next/static/chunks/app/more/{page-333bba1c8bbc9c11.js → page-353a3924e6d7968e.js} +1 -1
  306. package/.next/static/chunks/app/{page-214f7ffa13a0cf10.js → page-c2bf871d953a1d6f.js} +1 -1
  307. package/.next/static/chunks/app/repositories/{page-4951cac905e50224.js → page-7d0f26df0537254c.js} +1 -1
  308. package/.next/static/chunks/app/review/{page-a0899b2d285318c3.js → page-e3f141b2829973e9.js} +1 -1
  309. package/.next/static/chunks/app/sessions/{page-fb36145ec732092a.js → page-53f188ed9ca49e5f.js} +1 -1
  310. package/.next/static/chunks/app/skills/[skillId]/{page-9099e26b60442873.js → page-80569b720aea59cc.js} +1 -1
  311. package/.next/static/chunks/app/skills/installed/{page-182e32368696d824.js → page-dbd2690ad72da95b.js} +1 -1
  312. package/.next/static/chunks/app/skills/{page-d3fdc88239ebe0ab.js → page-dacd36f9c11aa7da.js} +1 -1
  313. package/.next/static/chunks/app/worktrees/[id]/page-97205088520255a5.js +1 -0
  314. package/.next/static/css/5c13ea243dfdcb66.css +1 -0
  315. package/.next/trace +13 -13
  316. package/README.md +37 -11
  317. package/dist/cli/commands/attach.d.ts +50 -0
  318. package/dist/cli/commands/attach.d.ts.map +1 -0
  319. package/dist/cli/commands/attach.js +204 -0
  320. package/dist/cli/commands/capture.d.ts.map +1 -1
  321. package/dist/cli/commands/capture.js +114 -0
  322. package/dist/cli/commands/instances.d.ts.map +1 -1
  323. package/dist/cli/commands/instances.js +23 -2
  324. package/dist/cli/commands/ls.d.ts.map +1 -1
  325. package/dist/cli/commands/ls.js +41 -1
  326. package/dist/cli/config/cli-dependencies.d.ts.map +1 -1
  327. package/dist/cli/config/cli-dependencies.js +34 -0
  328. package/dist/cli/program.d.ts.map +1 -1
  329. package/dist/cli/program.js +5 -0
  330. package/dist/cli/types/index.d.ts +36 -0
  331. package/dist/cli/types/index.d.ts.map +1 -1
  332. package/dist/config/tmux-pane-config.d.ts +153 -0
  333. package/dist/config/tmux-pane-config.d.ts.map +1 -0
  334. package/dist/config/tmux-pane-config.js +172 -0
  335. package/dist/lib/cli-tools/session-name.d.ts +44 -0
  336. package/dist/lib/cli-tools/session-name.d.ts.map +1 -0
  337. package/dist/lib/cli-tools/session-name.js +57 -0
  338. package/dist/lib/cli-tools/types.d.ts +1 -1
  339. package/dist/lib/cli-tools/types.d.ts.map +1 -1
  340. package/dist/lib/cli-tools/types.js +6 -1
  341. package/dist/lib/cli-tools/validation.d.ts +34 -0
  342. package/dist/lib/cli-tools/validation.d.ts.map +1 -0
  343. package/dist/lib/cli-tools/validation.js +41 -0
  344. package/dist/lib/detection/status-reason.d.ts +18 -0
  345. package/dist/lib/detection/status-reason.d.ts.map +1 -1
  346. package/dist/lib/detection/status-reason.js +18 -0
  347. package/dist/lib/detection/tools/verified-against.d.ts +57 -7
  348. package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
  349. package/dist/lib/detection/tools/verified-against.js +59 -8
  350. package/dist/lib/detection/version-probes.d.ts +26 -5
  351. package/dist/lib/detection/version-probes.d.ts.map +1 -1
  352. package/dist/lib/detection/version-probes.js +28 -6
  353. package/dist/lib/session/tmux-session-surface.d.ts +369 -0
  354. package/dist/lib/session/tmux-session-surface.d.ts.map +1 -0
  355. package/dist/lib/session/tmux-session-surface.js +525 -0
  356. package/dist/server/src/config/cli-tool-timing-config.js +12 -1
  357. package/dist/server/src/config/detection-evidence-config.js +5 -0
  358. package/dist/server/src/config/schedule-config.js +28 -1
  359. package/dist/server/src/lib/cli-tools/antigravity.js +2 -2
  360. package/dist/server/src/lib/cli-tools/base.js +13 -8
  361. package/dist/server/src/lib/cli-tools/claude.js +20 -0
  362. package/dist/server/src/lib/cli-tools/codex.js +205 -61
  363. package/dist/server/src/lib/cli-tools/command-code.js +349 -0
  364. package/dist/server/src/lib/cli-tools/composer-spec.js +6 -0
  365. package/dist/server/src/lib/cli-tools/copilot.js +2 -2
  366. package/dist/server/src/lib/cli-tools/gemini.js +2 -2
  367. package/dist/server/src/lib/cli-tools/graceful-exit.js +16 -1
  368. package/dist/server/src/lib/cli-tools/index.js +4 -1
  369. package/dist/server/src/lib/cli-tools/install-hints.js +131 -0
  370. package/dist/server/src/lib/cli-tools/liveness-spec.js +18 -0
  371. package/dist/server/src/lib/cli-tools/manager.js +2 -0
  372. package/dist/server/src/lib/cli-tools/opencode.js +2 -2
  373. package/dist/server/src/lib/cli-tools/start-availability.js +18 -11
  374. package/dist/server/src/lib/cli-tools/types.js +6 -1
  375. package/dist/server/src/lib/cli-tools/vibe-local.js +2 -2
  376. package/dist/server/src/lib/cmate-parser.js +6 -0
  377. package/dist/server/src/lib/detection/cli-patterns.js +441 -8
  378. package/dist/server/src/lib/detection/opencode-modal-overlay.js +66 -100
  379. package/dist/server/src/lib/detection/selection-shape.js +341 -0
  380. package/dist/server/src/lib/detection/sgr-background.js +210 -0
  381. package/dist/server/src/lib/detection/status-detector.js +6 -0
  382. package/dist/server/src/lib/detection/status-reason.js +18 -0
  383. package/dist/server/src/lib/detection/tools/antigravity/detect.js +38 -15
  384. package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +392 -0
  385. package/dist/server/src/lib/detection/tools/codex/detect.js +83 -2
  386. package/dist/server/src/lib/detection/tools/command-code/detect.js +159 -0
  387. package/dist/server/src/lib/detection/tools/registry.js +6 -4
  388. package/dist/server/src/lib/detection/tools/verified-against.js +59 -8
  389. package/dist/server/src/lib/detection/version-probes.js +28 -6
  390. package/dist/server/src/lib/hooks/sources/antigravity/history.js +77 -16
  391. package/dist/server/src/lib/hooks/sources/claude/history.js +94 -18
  392. package/dist/server/src/lib/hooks/sources/codex/history.js +84 -15
  393. package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +130 -17
  394. package/dist/server/src/lib/hooks/sources/codex/relay-install.js +145 -0
  395. package/dist/server/src/lib/hooks/sources/command-code/history.js +865 -0
  396. package/dist/server/src/lib/hooks/sources/command-code/hooks-config.js +390 -0
  397. package/dist/server/src/lib/hooks/sources/command-code/source.js +290 -0
  398. package/dist/server/src/lib/hooks/sources/command-code/tool-id.js +18 -0
  399. package/dist/server/src/lib/hooks/sources/command-code/transcript.js +604 -0
  400. package/dist/server/src/lib/hooks/sources/index.js +3 -1
  401. package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -3
  402. package/dist/server/src/lib/hooks/sources/opencode/transcript.js +24 -28
  403. package/dist/server/src/lib/hooks/sources/registry.js +4 -0
  404. package/dist/server/src/lib/hooks/sources/turn-body.js +77 -19
  405. package/dist/server/src/lib/job-executor.js +12 -0
  406. package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +6 -0
  407. package/dist/server/src/lib/polling/response-checker.js +112 -7
  408. package/dist/server/src/lib/polling/structured-history-gate.js +15 -8
  409. package/dist/server/src/lib/realtime/types.js +15 -5
  410. package/dist/server/src/lib/response-cleaner.js +24 -1
  411. package/dist/server/src/lib/response-extractor.js +11 -0
  412. package/dist/server/src/lib/session/claude-executor.js +223 -4
  413. package/dist/server/src/lib/session/cli-session.js +52 -0
  414. package/dist/server/src/lib/session/tmux-session-surface.js +525 -0
  415. package/dist/server/src/lib/skills/compatibility-matrix.js +117 -1
  416. package/dist/server/src/lib/tmux/geometry-delegation.js +143 -0
  417. package/dist/server/src/lib/tmux/read-mode-pager.js +76 -10
  418. package/dist/server/src/lib/tmux/read-mode.js +44 -2
  419. package/dist/server/src/lib/tmux/session-hook-scripts.js +249 -0
  420. package/dist/server/src/lib/tmux/session-hooks.js +122 -0
  421. package/dist/server/src/lib/tmux/session-status-options.js +213 -0
  422. package/dist/server/src/lib/tmux/tmux.js +79 -2
  423. package/dist/server/src/lib/version-checker.js +110 -0
  424. package/dist/server/src/lib/ws-server.js +16 -10
  425. package/dist/server/src/types/agent-transcript.js +73 -1
  426. package/dist/server/src/types/terminal-keys.js +131 -3
  427. package/dist/types/terminal-keys.d.ts +100 -3
  428. package/dist/types/terminal-keys.d.ts.map +1 -1
  429. package/dist/types/terminal-keys.js +131 -3
  430. package/package.json +1 -1
  431. package/.next/server/chunks/3099.js +0 -5
  432. package/.next/server/chunks/7824.js +0 -1
  433. package/.next/static/chunks/3916-0e929d089282dc5d.js +0 -1
  434. package/.next/static/chunks/6022-7a7d1760fc9814c7.js +0 -1
  435. package/.next/static/chunks/6381-147dde2a967e9458.js +0 -1
  436. package/.next/static/chunks/app/layout-6a26ea22d5cf03dc.js +0 -1
  437. package/.next/static/chunks/app/worktrees/[id]/page-2f73d69187936627.js +0 -1
  438. package/.next/static/css/23f9c40ecc458c77.css +0 -1
  439. /package/.next/static/{QXxQbXWoo7ldUyOcv7PCZ → nXW4dPkpE_9xUf_9ySRff}/_buildManifest.js +0 -0
  440. /package/.next/static/{QXxQbXWoo7ldUyOcv7PCZ → nXW4dPkpE_9xUf_9ySRff}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -50,14 +50,24 @@ If this is the kind of AI development workflow you want, [give the repo a star](
50
50
  | **Skills Catalog** | Install and update official Skills per worktree, from the web UI or `commandmate skill` | The method is installed for the agent to read, not kept in someone's head |
51
51
  | **Never miss a waiting agent** | A waiting agent shows up as a badge, a toast, the tab title, the PWA app badge and a push notification | You find out the moment an agent needs you, even away from the desk |
52
52
  | **Git Worktree Sessions** | One session per worktree, parallel execution | Multiple issues progress simultaneously without interference |
53
- | **Multi-Agent Support** | Choose Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity or local models per worktree | Pick the right agent for each task |
53
+ | **Multi-Agent Support** | Choose Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity, Command Code or local models per worktree | Pick the right agent for each task |
54
54
  | **Auto Yes Mode** | Agent runs without stopping for confirmations | Optional unattended mode for trusted workflows — review the Security section before enabling |
55
55
  | **Web UI (Desktop & Mobile)** | Full session control from any browser | Monitor and steer from your desk or your phone |
56
+ | **Conversation view** | Switch a session's output between the raw terminal and a chat transcript — replies render in full, tool runs and approvals fold into chips, and a TUI dialog is answerable from the chat surface | Follow the run and answer it — from your desk or your phone — without reading the TUI |
56
57
  | **File Viewer & Markdown Editor** | Browse and edit worktree files in the browser | Review changes and update AI instructions without opening an IDE |
57
58
  | **Screenshot Instructions** | Attach images to your prompts | Snap a bug → "Fix this" — the agent sees the screenshot |
58
59
  | **Scheduled Execution** | Cron-based auto-run via CMATE.md | Daily reviews, nightly tests — agents work on a schedule |
59
60
  | **Token Authentication** | SHA-256 hashed token + HTTPS + rate limiting | Secure remote access — no credentials leaked, brute-force protected |
60
61
 
62
+ ### Supported agents
63
+
64
+ All eight are first-class. Each one gets the same treatment inside CommandMate — its own launch path, its own hook source and its own status detection — so the worktree session, the task contract, the verification gates and the evidence trail behave the same way whichever agent you pick.
65
+
66
+ - **Claude Code**, **Codex**, **Gemini CLI**, **Copilot**, **Antigravity** — choose per worktree, per task.
67
+ - **OpenCode** — the open-source terminal agent, driven through the same contract-and-gate path as the rest.
68
+ - **Command Code** — driven the same way, its hooks and its transcript included.
69
+ - **Local models** (`vibe-local`) — run the same loop against a model you host yourself.
70
+
61
71
  ---
62
72
 
63
73
  ## Use Cases
@@ -341,20 +351,36 @@ commandmate start -p 3001
341
351
 
342
352
  ### Session stuck or not responding?
343
353
 
344
- Check tmux sessions directly. CommandMate manages sessions with the naming format `mcbd-{tool}-{worktree}`:
354
+ Look at the session with CommandMate's own commands they resolve the tmux session name for you:
345
355
 
346
356
  ```bash
347
- # List all CommandMate sessions
348
- tmux list-sessions | grep mcbd
357
+ # What every worktree's agent is doing, and the tmux session it runs in
358
+ commandmate ls
359
+ commandmate ls --json | jq -r '.[] | "\(.id)\t\(.tmuxSession)"'
360
+
361
+ # Read the transcript WITHOUT attaching
362
+ commandmate capture <worktree-id> --pane --tail 60
363
+ commandmate capture <worktree-id> --pane --follow # follow a reply as it is generated
349
364
 
350
- # View session output (without attaching)
351
- tmux capture-pane -t "mcbd-claude-feature-123" -p
365
+ # Attach this terminal (detach with Ctrl+b then d)
366
+ commandmate attach <worktree-id>
367
+ commandmate attach <worktree-id> --live # re-lay out to your terminal (claude only)
368
+ ```
369
+
370
+ **Why a bare `tmux attach` looks empty.** A CommandMate session is pinned to a 200x1000 canvas so
371
+ `capture-pane` keeps enough history for status detection. Alternate-screen agents (claude / opencode /
372
+ copilot) draw their transcript at the top of that canvas and their composer at the bottom, and tmux
373
+ follows the cursor — so a normal-sized terminal sees the composer, blank rows, and not one line of the
374
+ conversation. Nothing is broken. Read it with `capture --pane` above, with `prefix + g` while
375
+ attached, or hand the window to your terminal with `attach --live`.
352
376
 
353
- # Attach to inspect (detach with Ctrl+b then d)
354
- tmux attach -t "mcbd-claude-feature-123"
377
+ From tmux itself, without attaching at all:
378
+
379
+ ```bash
380
+ tmux ls -F '#{session_name} #{@cm_status} #{@cm_tool}/#{@cm_instance}'
355
381
 
356
- # Kill a broken session
357
- tmux kill-session -t "mcbd-claude-feature-123"
382
+ # Kill a broken session (`=name:` is an exact match; quote it — zsh eats a bare `=`)
383
+ tmux kill-session -t '=mcbd-claude-feature-123:'
358
384
  ```
359
385
 
360
386
  > **Note:** When attached, avoid typing directly into the session — this can interfere with CommandMate's session management. Use `Ctrl+b` then `d` to detach and operate through the CommandMate UI instead.
@@ -446,7 +472,7 @@ The comparison that matters is not against other products; it is against the way
446
472
  | Evidence | A chat transcript | Commits, gate logs, `verify history`, `report metrics` |
447
473
  | Parallel work | Terminal tabs | One worktree and one contract per task |
448
474
  | When it stops | You notice, eventually | Waiting is surfaced: badge, toast, tab title, push |
449
- | Which agent | Locked to one | Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity, local models |
475
+ | Which agent | Locked to one | Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity, Command Code, local models |
450
476
 
451
477
  </details>
452
478
 
@@ -0,0 +1,50 @@
1
+ /**
2
+ * attach Command - open a worktree's tmux session in this terminal (Issue #2317, Phase A/D)
3
+ *
4
+ * commandmate attach <worktree-id> [--instance <id>] [--read-only] [--live]
5
+ *
6
+ * ## Why this exists when `tmux attach` already does
7
+ *
8
+ * Three reasons, and each one is a thing an operator got wrong before it:
9
+ *
10
+ * 1. **The session name.** It is `mcbd-<tool>-<worktree>[-<suffix>]`, and the
11
+ * suffix depends on the agent-instance roster. `commandmate ls` did not print
12
+ * it, so the name had to be assembled by hand from three facts spread across
13
+ * two commands.
14
+ * 2. **The `=` trap.** The exact-match target form is `'=<name>:'` (Issue #1156),
15
+ * and in zsh an unquoted `=name` is an equals expansion — `tmux attach -t
16
+ * =mcbd-…:` fails with `not found` before tmux ever runs. Measured; it is in
17
+ * the Issue. This command quotes it so nobody has to know.
18
+ * 3. **What you will see.** For an alternate-screen agent a bare attach shows
19
+ * the composer and nothing else — the transcript is at the top of a 1000-row
20
+ * canvas and tmux follows the cursor at row 997. That is not a fault to
21
+ * debug, it is the geometry, and the hint printed before attaching says so
22
+ * and names the three ways to read anyway.
23
+ *
24
+ * ## `--live` is claude-only, and that is a measurement
25
+ *
26
+ * See `LIVE_ATTACH_TOOLS` in `lib/tmux/session-surface.ts`. Every other tool
27
+ * either reads its reply off the pane, or has detection rules measured only at
28
+ * 200x1000, or cannot survive a width change at all.
29
+ */
30
+ import { Command } from 'commander';
31
+ /**
32
+ * The lines printed to stderr before the terminal is handed to tmux.
33
+ *
34
+ * stderr, not stdout: the session takes the screen over immediately afterwards,
35
+ * and a caller piping this command's stdout is not asking for advice.
36
+ *
37
+ * Exported so the test asserts the text a user actually sees rather than a
38
+ * paraphrase of it.
39
+ *
40
+ * @param cliToolId - Resolved CLI tool
41
+ * @param worktreeId - Worktree id, so the hint's commands are copy-pasteable
42
+ * @param sessionName - Resolved tmux session name
43
+ * @param options - The flags as given
44
+ */
45
+ export declare function buildAttachHints(cliToolId: string, worktreeId: string, sessionName: string, options: {
46
+ readOnly?: boolean;
47
+ live?: boolean;
48
+ }): string[];
49
+ export declare function createAttachCommand(): Command;
50
+ //# sourceMappingURL=attach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/attach.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuDpC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,EAAE,CAmCV;AAiDD,wBAAgB,mBAAmB,IAAI,OAAO,CAmE7C"}
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ /**
3
+ * attach Command - open a worktree's tmux session in this terminal (Issue #2317, Phase A/D)
4
+ *
5
+ * commandmate attach <worktree-id> [--instance <id>] [--read-only] [--live]
6
+ *
7
+ * ## Why this exists when `tmux attach` already does
8
+ *
9
+ * Three reasons, and each one is a thing an operator got wrong before it:
10
+ *
11
+ * 1. **The session name.** It is `mcbd-<tool>-<worktree>[-<suffix>]`, and the
12
+ * suffix depends on the agent-instance roster. `commandmate ls` did not print
13
+ * it, so the name had to be assembled by hand from three facts spread across
14
+ * two commands.
15
+ * 2. **The `=` trap.** The exact-match target form is `'=<name>:'` (Issue #1156),
16
+ * and in zsh an unquoted `=name` is an equals expansion — `tmux attach -t
17
+ * =mcbd-…:` fails with `not found` before tmux ever runs. Measured; it is in
18
+ * the Issue. This command quotes it so nobody has to know.
19
+ * 3. **What you will see.** For an alternate-screen agent a bare attach shows
20
+ * the composer and nothing else — the transcript is at the top of a 1000-row
21
+ * canvas and tmux follows the cursor at row 997. That is not a fault to
22
+ * debug, it is the geometry, and the hint printed before attaching says so
23
+ * and names the three ways to read anyway.
24
+ *
25
+ * ## `--live` is claude-only, and that is a measurement
26
+ *
27
+ * See `LIVE_ATTACH_TOOLS` in `lib/tmux/session-surface.ts`. Every other tool
28
+ * either reads its reply off the pane, or has detection rules measured only at
29
+ * 200x1000, or cannot survive a width change at all.
30
+ */
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.buildAttachHints = buildAttachHints;
33
+ exports.createAttachCommand = createAttachCommand;
34
+ const child_process_1 = require("child_process");
35
+ const commander_1 = require("commander");
36
+ const types_1 = require("../types");
37
+ const api_client_1 = require("../utils/api-client");
38
+ const command_helpers_1 = require("../utils/command-helpers");
39
+ const cli_tool_ids_1 = require("../config/cli-tool-ids");
40
+ const agent_target_options_1 = require("../config/agent-target-options");
41
+ const session_target_1 = require("../utils/session-target");
42
+ const session_name_1 = require("../../lib/cli-tools/session-name");
43
+ const tmux_session_surface_1 = require("../../lib/session/tmux-session-surface");
44
+ /** Run one tmux command, inheriting nothing. Returns true on exit 0. */
45
+ function runTmux(args) {
46
+ const result = (0, child_process_1.spawnSync)('tmux', args, { stdio: ['ignore', 'ignore', 'ignore'] });
47
+ return result.status === 0;
48
+ }
49
+ /**
50
+ * Resolve which (tool, instance) pair the worktree id addresses.
51
+ *
52
+ * Through the server's resolver, exactly as `send` / `capture` / `wait` do
53
+ * (Issue #1925): the tool id is half the tmux session name, so a locally-guessed
54
+ * one is a different session. A `--agent` the roster contradicts is a hard error
55
+ * here rather than a warning — attaching is a thing you do WITH a session, and
56
+ * doing it to the wrong one wastes the reader's time in a way a wrong `capture`
57
+ * does not.
58
+ */
59
+ async function resolveTarget(client, worktreeId, options) {
60
+ const target = await (0, session_target_1.resolveSessionTarget)(client, worktreeId, {
61
+ instanceId: options.instance,
62
+ requestedCliTool: options.agent,
63
+ });
64
+ if (target.conflict) {
65
+ console.error(`Error: ${(0, session_target_1.describeSessionTargetConflict)(target.conflict)}`);
66
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
67
+ }
68
+ return {
69
+ cliToolId: target.cliToolId ?? options.agent ?? cli_tool_ids_1.DEFAULT_CLI_TOOL_ID,
70
+ instanceId: target.instanceId ?? options.instance,
71
+ };
72
+ }
73
+ /**
74
+ * The lines printed to stderr before the terminal is handed to tmux.
75
+ *
76
+ * stderr, not stdout: the session takes the screen over immediately afterwards,
77
+ * and a caller piping this command's stdout is not asking for advice.
78
+ *
79
+ * Exported so the test asserts the text a user actually sees rather than a
80
+ * paraphrase of it.
81
+ *
82
+ * @param cliToolId - Resolved CLI tool
83
+ * @param worktreeId - Worktree id, so the hint's commands are copy-pasteable
84
+ * @param sessionName - Resolved tmux session name
85
+ * @param options - The flags as given
86
+ */
87
+ function buildAttachHints(cliToolId, worktreeId, sessionName, options) {
88
+ const hints = [`Attaching to ${sessionName} (${cliToolId}). Detach with Ctrl+b then d.`];
89
+ if ((0, tmux_session_surface_1.usesAltScreen)(cliToolId) && !options.live) {
90
+ hints.push(`${cliToolId} draws its transcript at the top of a 200x1000 canvas and its composer at the`, 'bottom, and tmux follows the cursor — so this attach shows the composer and blank rows,', 'not the conversation. To read it:', ` prefix + g popup, in this terminal`, ` commandmate capture ${worktreeId} --pane --tail 60 without attaching`, ` commandmate capture ${worktreeId} --pane --follow live, without attaching`);
91
+ if ((0, tmux_session_surface_1.isLiveAttachSupported)(cliToolId)) {
92
+ hints.push(` commandmate attach ${worktreeId} --live re-lay-out to this terminal`);
93
+ }
94
+ }
95
+ if (options.readOnly) {
96
+ hints.push('Read-only attach: tmux delivers no keys but the detach one, so prefix + g does NOT open', 'the popup here. Read with `commandmate capture <id> --pane --follow` in another terminal.');
97
+ }
98
+ if (options.live) {
99
+ hints.push('Live attach: this session follows THIS terminal until you detach, then goes back to', '200x1000. The web terminal shows the smaller frame while you are attached.');
100
+ }
101
+ hints.push(`Status without attaching: tmux ls -F '#{session_name} #{@cm_status}'`);
102
+ return hints;
103
+ }
104
+ /**
105
+ * Hand the geometry over, attach, and hand it back (Phase D).
106
+ *
107
+ * The restore runs in a `finally`, so a tmux that exits non-zero — or a
108
+ * `attach-session` interrupted by a signal — still gives the canvas back. The
109
+ * server's poll (`reconcileDelegatedGeometry`) is the second net for the case
110
+ * this process does not survive to run it.
111
+ */
112
+ function attachLive(sessionName, readOnly) {
113
+ for (const args of (0, tmux_session_surface_1.buildDelegateGeometryCommands)(sessionName)) {
114
+ runTmux(args);
115
+ }
116
+ try {
117
+ const result = (0, child_process_1.spawnSync)('tmux', (0, tmux_session_surface_1.buildAttachArgs)(sessionName, readOnly), {
118
+ stdio: 'inherit',
119
+ });
120
+ return result.status ?? types_1.ExitCode.UNEXPECTED_ERROR;
121
+ }
122
+ finally {
123
+ for (const args of (0, tmux_session_surface_1.buildRestoreGeometryCommands)(sessionName)) {
124
+ runTmux(args);
125
+ }
126
+ }
127
+ }
128
+ /**
129
+ * Attach, or switch this tmux client, to `sessionName`.
130
+ *
131
+ * `switch-client` rather than an error when `$TMUX` is set: attaching a session
132
+ * inside another session is what tmux refuses, and switching is what the user
133
+ * meant. When the switch fails — the ambient `$TMUX` is a DIFFERENT tmux server,
134
+ * which is the case CommandMate's own agents run under — the manual command is
135
+ * printed, quoted, rather than a bare "nested sessions" complaint.
136
+ */
137
+ function attachOrSwitch(sessionName, readOnly) {
138
+ if (process.env.TMUX) {
139
+ if (runTmux((0, tmux_session_surface_1.buildSwitchClientArgs)(sessionName)))
140
+ return types_1.ExitCode.SUCCESS;
141
+ console.error('Error: already inside tmux, and this client could not switch to that session '
142
+ + '(a different tmux server?). From a terminal outside tmux, run:\n'
143
+ + ` tmux attach -t '${(0, tmux_session_surface_1.exactSessionTarget)(sessionName)}'`);
144
+ return types_1.ExitCode.UNEXPECTED_ERROR;
145
+ }
146
+ const result = (0, child_process_1.spawnSync)('tmux', (0, tmux_session_surface_1.buildAttachArgs)(sessionName, readOnly), { stdio: 'inherit' });
147
+ return result.status ?? types_1.ExitCode.UNEXPECTED_ERROR;
148
+ }
149
+ function createAttachCommand() {
150
+ const cmd = new commander_1.Command('attach');
151
+ cmd
152
+ .description("Attach this terminal to a worktree's agent tmux session")
153
+ .argument('<worktree-id>', 'Worktree ID')
154
+ .option('--instance <id>', agent_target_options_1.INSTANCE_OPTION_DESCRIPTION)
155
+ .option('--agent <agent>', agent_target_options_1.AGENT_OPTION_DESCRIPTION)
156
+ .option('-r, --read-only', 'Attach without sending any input to the session')
157
+ .option('--live', 'Re-lay the session out to this terminal while attached, restoring 200x1000 on detach (claude only)')
158
+ .option('--token <token>', command_helpers_1.TOKEN_WARNING)
159
+ .action(async (worktreeId, options) => {
160
+ try {
161
+ if (!(0, api_client_1.isValidWorktreeId)(worktreeId)) {
162
+ console.error('Error: Invalid worktree ID format.');
163
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
164
+ }
165
+ if (options.agent && !(0, cli_tool_ids_1.isCliToolId)(options.agent)) {
166
+ console.error('Error: Invalid agent.');
167
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
168
+ }
169
+ if (options.instance && !(0, api_client_1.isValidInstanceId)(options.instance)) {
170
+ console.error('Error: Invalid --instance. Must be an alphanumeric/underscore/hyphen identifier (max 64 chars).');
171
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
172
+ }
173
+ const client = new api_client_1.ApiClient({ token: options.token });
174
+ const { cliToolId, instanceId } = await resolveTarget(client, worktreeId, options);
175
+ if (options.live && !(0, tmux_session_surface_1.isLiveAttachSupported)(cliToolId)) {
176
+ console.error(`Error: --live is not supported for ${cliToolId}. It is claude-only until each other `
177
+ + "agent's detection rules are re-measured at a terminal-sized pane (Issue #2317). "
178
+ + `Attach without it, or read with: commandmate capture ${worktreeId} --pane --follow`);
179
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
180
+ }
181
+ const sessionName = (0, session_name_1.resolveSessionName)(cliToolId, worktreeId, instanceId);
182
+ if (!runTmux(['has-session', '-t', (0, tmux_session_surface_1.exactSessionTarget)(sessionName)])) {
183
+ console.error(`Error: no tmux session named ${sessionName}.\n`
184
+ + ` commandmate ls which worktrees have a running session\n`
185
+ + ` commandmate instances ${worktreeId} which agents this worktree runs`);
186
+ process.exit(types_1.ExitCode.UNEXPECTED_ERROR);
187
+ }
188
+ for (const line of buildAttachHints(cliToolId, worktreeId, sessionName, {
189
+ readOnly: options.readOnly,
190
+ live: options.live,
191
+ })) {
192
+ console.error(line);
193
+ }
194
+ const status = options.live
195
+ ? attachLive(sessionName, Boolean(options.readOnly))
196
+ : attachOrSwitch(sessionName, Boolean(options.readOnly));
197
+ process.exit(status);
198
+ }
199
+ catch (error) {
200
+ (0, command_helpers_1.handleCommandError)(error);
201
+ }
202
+ });
203
+ return cmd;
204
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/capture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8RpC,wBAAgB,oBAAoB,IAAI,OAAO,CAmG9C"}
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/capture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwYpC,wBAAgB,oBAAoB,IAAI,OAAO,CA4H9C"}
@@ -28,6 +28,17 @@ const transcript_squeeze_1 = require("../../lib/tmux/transcript-squeeze");
28
28
  * RESULT instead (see {@link CaptureOptions.tail}).
29
29
  */
30
30
  const PANE_CAPTURE_LINES = 1000;
31
+ /**
32
+ * Default redraw interval of `--pane --follow`, in milliseconds (Issue #2317).
33
+ *
34
+ * Two seconds, matching the response poller's own cadence: a faster redraw
35
+ * cannot show anything the server has not captured yet, and would only add tmux
36
+ * round-trips to a session someone is already watching.
37
+ */
38
+ const DEFAULT_FOLLOW_INTERVAL_MS = 2000;
39
+ /** Floor and ceiling for `--interval`. */
40
+ const MIN_FOLLOW_INTERVAL_MS = 250;
41
+ const MAX_FOLLOW_INTERVAL_MS = 60_000;
31
42
  /**
32
43
  * `promptData.type` the server writes for a frame the detection layer could not
33
44
  * classify (Issue #1708). Mirrors UNCLASSIFIED_PROMPT_TYPE in
@@ -247,6 +258,85 @@ async function capturePane(worktreeId, options) {
247
258
  }
248
259
  (0, pager_1.printMaybePaged)(text);
249
260
  }
261
+ /**
262
+ * Parse and validate `--interval <ms>`.
263
+ *
264
+ * @param raw - Raw option value, if the user passed one
265
+ * @returns The interval in milliseconds
266
+ */
267
+ function parseFollowInterval(raw) {
268
+ if (raw === undefined)
269
+ return DEFAULT_FOLLOW_INTERVAL_MS;
270
+ const value = Number(raw);
271
+ if (!Number.isInteger(value) ||
272
+ value < MIN_FOLLOW_INTERVAL_MS ||
273
+ value > MAX_FOLLOW_INTERVAL_MS) {
274
+ console.error(`Error: --interval must be an integer between ${MIN_FOLLOW_INTERVAL_MS} and ${MAX_FOLLOW_INTERVAL_MS} (milliseconds).`);
275
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
276
+ }
277
+ return value;
278
+ }
279
+ /**
280
+ * `--pane --follow`: redraw the squeezed transcript on an interval (Issue #2317).
281
+ *
282
+ * ## Why this exists next to `prefix + g`
283
+ *
284
+ * The popup #1623 added is a SNAPSHOT and needs a key press to refresh, and it
285
+ * does not work at all under `tmux attach -r` (a read-only client is delivered
286
+ * no keys but the detach one). This is the reading path that needs neither a
287
+ * tmux client nor a key table: it works from any terminal, over ssh, and while
288
+ * somebody else is attached.
289
+ *
290
+ * ## What it does NOT do
291
+ *
292
+ * It never writes. Every iteration makes exactly the request `--pane` already
293
+ * makes — same route, same {@link PANE_CAPTURE_LINES} — so the detection
294
+ * pipeline sees no different payload because a human is watching, and the
295
+ * session's geometry is untouched (Issue #2317 受入条件 Phase C 2).
296
+ *
297
+ * Ctrl-C is the exit, and it needs no handler: SIGINT's default action ends the
298
+ * process, and the alternate screen is left with the cursor restored by the
299
+ * `finally` below.
300
+ */
301
+ async function capturePaneFollow(worktreeId, options) {
302
+ if (!process.stdout.isTTY) {
303
+ console.error('Error: --follow needs a terminal (it redraws the screen). '
304
+ + 'Without one, loop over `commandmate capture <id> --pane --tail N` instead.');
305
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
306
+ }
307
+ const client = new api_client_1.ApiClient({ token: options.token });
308
+ const tail = parseTail(options.tail);
309
+ const intervalMs = parseFollowInterval(options.interval);
310
+ const cliToolId = await resolvePaneCliTool(client, worktreeId, options.agent, options.instance);
311
+ // Hide the cursor while redrawing, and put it back whatever ends the loop.
312
+ process.stdout.write('\u001b[?25l');
313
+ const restoreCursor = () => {
314
+ process.stdout.write('\u001b[?25h');
315
+ };
316
+ process.on('exit', restoreCursor);
317
+ try {
318
+ for (;;) {
319
+ const data = await client.post(`/api/worktrees/${worktreeId}/capture`, {
320
+ cliToolId,
321
+ lines: PANE_CAPTURE_LINES,
322
+ ...(options.instance ? { instanceId: options.instance } : {}),
323
+ });
324
+ const squeezed = (0, transcript_squeeze_1.squeezeTranscript)(data.output ?? '', { tail });
325
+ // The visible rows, minus one for the footer. Slicing HERE rather than
326
+ // asking the server for fewer lines is the same choice `--tail` makes: the
327
+ // squeeze has to run over the whole frame or the blank padding is what
328
+ // gets kept.
329
+ const rows = Math.max(1, (process.stdout.rows || 40) - 1);
330
+ const body = squeezed.text.split('\n').slice(-rows).join('\n');
331
+ process.stdout.write(`\u001b[H\u001b[2J${body}\n`);
332
+ process.stdout.write(`\u001b[7m[CommandMate] ${worktreeId} / ${cliToolId} — Ctrl-C to stop\u001b[0m`);
333
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
334
+ }
335
+ }
336
+ finally {
337
+ restoreCursor();
338
+ }
339
+ }
250
340
  function createCaptureCommand() {
251
341
  const cmd = new commander_1.Command('capture');
252
342
  cmd
@@ -258,6 +348,9 @@ function createCaptureCommand() {
258
348
  .option('--pane', 'Read the raw tmux pane as a transcript, with blank layout rows squeezed')
259
349
  .option('--tail <n>', 'With --pane: keep only the last N lines OF THE SQUEEZED transcript')
260
350
  .option('--raw', 'With --pane: skip the squeeze and print the pane verbatim')
351
+ // Issue #2317: the reading path that needs no tmux client and no key table.
352
+ .option('--follow', 'With --pane: redraw on an interval instead of printing once (Ctrl-C to stop)')
353
+ .option('--interval <ms>', `With --pane --follow: redraw interval in milliseconds (default ${DEFAULT_FOLLOW_INTERVAL_MS})`)
261
354
  // Issue #1685: audit trail of resolved prompts (question/options/answer/answeredBy)
262
355
  .option('--prompts', 'List recent prompts from chat history (including ones Auto-Yes already resolved)')
263
356
  .option('--limit <n>', `With --prompts: number of most recent prompts to list (default ${DEFAULT_PROMPTS_LIMIT})`)
@@ -286,6 +379,23 @@ function createCaptureCommand() {
286
379
  console.error('Error: --tail and --raw require --pane.');
287
380
  process.exit(types_1.ExitCode.CONFIG_ERROR);
288
381
  }
382
+ // Issue #2317: same rule as --tail/--raw. A --follow that silently did
383
+ // nothing outside --pane would look like the flag was accepted.
384
+ if (!options.pane && (options.follow || options.interval !== undefined)) {
385
+ console.error('Error: --follow and --interval require --pane.');
386
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
387
+ }
388
+ if (options.interval !== undefined && !options.follow) {
389
+ console.error('Error: --interval requires --follow.');
390
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
391
+ }
392
+ // The follow loop redraws the screen; --json and --raw are both "give me
393
+ // the bytes", and neither has a meaning that survives being overwritten
394
+ // every two seconds.
395
+ if (options.follow && (options.json || options.raw)) {
396
+ console.error('Error: --follow cannot be combined with --json or --raw.');
397
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
398
+ }
289
399
  // Issue #1685: --prompts reads history, --pane reads the live pane —
290
400
  // asking for both at once has no meaningful answer.
291
401
  if (options.prompts && options.pane) {
@@ -301,6 +411,10 @@ function createCaptureCommand() {
301
411
  return;
302
412
  }
303
413
  if (options.pane) {
414
+ if (options.follow) {
415
+ await capturePaneFollow(worktreeId, options);
416
+ return;
417
+ }
304
418
  await capturePane(worktreeId, options);
305
419
  return;
306
420
  }
@@ -1 +1 @@
1
- {"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,SAAS,EAAwC,MAAM,qBAAqB,CAAC;AAiGtF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,GAAE,oBAA+B,GACpC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAiB7B;AAwND,wBAAgB,sBAAsB,IAAI,OAAO,CAqEhD"}
1
+ {"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,SAAS,EAAwC,MAAM,qBAAqB,CAAC;AA8HtF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,GAAE,oBAA+B,GACpC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAiB7B;AA2ND,wBAAgB,sBAAsB,IAAI,OAAO,CAqEhD"}
@@ -19,6 +19,23 @@ const command_helpers_1 = require("../utils/command-helpers");
19
19
  const cli_tool_ids_1 = require("../config/cli-tool-ids");
20
20
  const agent_instances_1 = require("../utils/agent-instances");
21
21
  const session_target_1 = require("../utils/session-target");
22
+ // Issue #2317: the tmux session name each instance runs in, so `commandmate
23
+ // attach` / `tmux attach` need no hand-assembly of `mcbd-<tool>-<wt>[-<suffix>]`.
24
+ const session_name_1 = require("../../lib/cli-tools/session-name");
25
+ /**
26
+ * The tmux session name for one roster row, or null.
27
+ *
28
+ * @param worktreeId - Worktree ID
29
+ * @param inst - Roster entry
30
+ */
31
+ function deriveInstanceSession(worktreeId, inst) {
32
+ try {
33
+ return (0, session_name_1.resolveSessionName)(inst.cliTool, worktreeId, inst.id);
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
22
39
  /**
23
40
  * Longest session title printed in the table (Issue #2038).
24
41
  *
@@ -39,8 +56,8 @@ function formatInstancesTable(rows) {
39
56
  const headers = [
40
57
  'INSTANCE_ID', 'ALIAS', 'CLI_TOOL', 'RUNNING', 'AUTO_YES', 'MODEL', 'EFFORT',
41
58
  // Issue #2038 appends, exactly as #1785 did, so anything reading this table
42
- // by column position keeps working.
43
- 'SESSION_ID', 'SESSION_TITLE',
59
+ // by column position keeps working. Issue #2317 appends for the same reason.
60
+ 'SESSION_ID', 'SESSION_TITLE', 'TMUX_SESSION',
44
61
  ];
45
62
  const dataRows = rows.map(r => [
46
63
  r.instanceId,
@@ -55,6 +72,7 @@ function formatInstancesTable(rows) {
55
72
  r.reasoningEffort ?? '',
56
73
  r.sessionId ?? '',
57
74
  (r.sessionTitle ?? '').slice(0, MAX_SESSION_TITLE_COLUMN),
75
+ r.tmuxSession ?? '',
58
76
  ]);
59
77
  const colWidths = headers.map((h, i) => Math.max(h.length, ...dataRows.map(r => r[i].length)));
60
78
  const headerLine = headers.map((h, i) => h.padEnd(colWidths[i])).join(' ');
@@ -158,6 +176,9 @@ async function listInstances(worktreeId, options) {
158
176
  // Issue #2038: additive, and absent for every tool that is not opencode.
159
177
  sessionId: opencodeSessions.get(inst.id)?.sessionId ?? null,
160
178
  sessionTitle: opencodeSessions.get(inst.id)?.title ?? null,
179
+ // Issue #2317: additive, and in both the table and `--json` — the table
180
+ // is where somebody who does not know the naming rule will see it.
181
+ tmuxSession: deriveInstanceSession(worktreeId, inst),
161
182
  };
162
183
  }));
163
184
  if (options.json) {
@@ -1 +1 @@
1
- {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/ls.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkJpC;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CA8CzC"}
1
+ {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/ls.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6LpC;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CA8CzC"}
@@ -11,6 +11,10 @@ const api_client_1 = require("../utils/api-client");
11
11
  // and the server must not be able to disagree about what `exited` is spelled.
12
12
  const status_reason_1 = require("../../lib/detection/status-reason");
13
13
  const command_helpers_1 = require("../utils/command-helpers");
14
+ // Issue #2317: the tmux session name, so nobody has to assemble
15
+ // `mcbd-<tool>-<worktree>[-<suffix>]` by hand from two commands' output.
16
+ const cli_tool_ids_1 = require("../config/cli-tool-ids");
17
+ const session_name_1 = require("../../lib/cli-tools/session-name");
14
18
  /**
15
19
  * Derive display status from worktree flags.
16
20
  *
@@ -117,6 +121,35 @@ function formatTable(worktrees) {
117
121
  const dataLines = rows.map(r => r.map((cell, i) => cell.padEnd(colWidths[i])).join(' '));
118
122
  return [headerLine, separator, ...dataLines].join('\n');
119
123
  }
124
+ /**
125
+ * The tmux session name of this worktree's DEFAULT agent, or null (Issue #2317).
126
+ *
127
+ * The default agent's PRIMARY instance, which is the session `commandmate
128
+ * attach <id>` opens with no flags — so the two answers cannot disagree. A
129
+ * worktree running several agents has several sessions, and this field names one
130
+ * of them on purpose: the complete per-instance list is what
131
+ * `commandmate instances <id>` is for, and duplicating it here would put the
132
+ * roster in two places.
133
+ *
134
+ * Null when the row names no default agent, or names one this CLI does not know
135
+ * (a server newer than the CLI), or when the id would not survive
136
+ * `validateSessionName` — the same three cases in which there is no name to
137
+ * give rather than a wrong one.
138
+ *
139
+ * Computed CLIENT-side. The server does not publish it, and asking it to would
140
+ * mean `/api/worktrees` — the sidebar's poll, for every worktree, every couple
141
+ * of seconds — carrying a string derivable from two fields already in the row.
142
+ */
143
+ function deriveTmuxSession(wt) {
144
+ if (!wt.cliToolId || !(0, cli_tool_ids_1.isCliToolId)(wt.cliToolId))
145
+ return null;
146
+ try {
147
+ return (0, session_name_1.resolveSessionName)(wt.cliToolId, wt.id);
148
+ }
149
+ catch {
150
+ return null;
151
+ }
152
+ }
120
153
  /**
121
154
  * Format output based on options [DR1-02]
122
155
  *
@@ -135,7 +168,14 @@ function formatTable(worktrees) {
135
168
  */
136
169
  function formatOutput(worktrees, options) {
137
170
  if (options.json) {
138
- return JSON.stringify(worktrees, null, 2);
171
+ // Issue #2317 appends one key and changes nothing else: every field the
172
+ // server sent still passes through verbatim, so a consumer reading
173
+ // `sessionStatusByCli.<tool>.statusEvidence` is unaffected.
174
+ const rows = worktrees.map((wt) => ({
175
+ ...wt,
176
+ tmuxSession: deriveTmuxSession(wt),
177
+ }));
178
+ return JSON.stringify(rows, null, 2);
139
179
  }
140
180
  if (options.quiet) {
141
181
  return worktrees.map(wt => wt.id).join('\n');
@@ -1 +1 @@
1
- {"version":3,"file":"cli-dependencies.d.ts","sourceRoot":"","sources":["../../../src/cli/config/cli-dependencies.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,eAAe,EAiEzC,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,IAAI,eAAe,EAAE,CAEnD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,eAAe,EAAE,CAE3D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,eAAe,EAAE,CAE3D"}
1
+ {"version":3,"file":"cli-dependencies.d.ts","sourceRoot":"","sources":["../../../src/cli/config/cli-dependencies.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,eAAe,EAmGzC,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,IAAI,eAAe,EAAE,CAEnD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,eAAe,EAAE,CAE3D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,eAAe,EAAE,CAE3D"}