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
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ /**
3
+ * Phase D of Issue #2317, server side: knowing when a human owns the geometry.
4
+ *
5
+ * `commandmate attach --live` hands a session's window from the pinned
6
+ * 200x1000 canvas to the attached terminal (`window-size latest`) so the agent
7
+ * re-lays-out and the transcript is actually readable, then pins it back on
8
+ * detach. While that handover is in force the session carries `@cm_delegated=1`,
9
+ * and the server has to behave differently in exactly two places:
10
+ *
11
+ * 1. **`reconcileSessionGeometry` must not resize.** Every `send` to a live
12
+ * session reaches `reconcileExistingSession()`, which would snap the window
13
+ * back to 200x1000 mid-read — the #1623 rejection note assumed this happened
14
+ * on every send and it does not, but it does happen on a session restart and
15
+ * on the reuse path, which is enough to break a delegated read.
16
+ * 2. **The poller must not save a scraped reply.** At 44 rows the frame is a
17
+ * fraction of the turn, and every extraction rule in `response-checker` was
18
+ * measured against the 1000-row canvas. claude — the only tool `--live`
19
+ * accepts — writes its History from its own transcript JSONL, so suppressing
20
+ * the scrape loses nothing and prevents a truncated reply being recorded.
21
+ *
22
+ * ## Why the flag is read from tmux rather than held in memory
23
+ *
24
+ * The delegation is performed by the CLI process (`commandmate attach --live`),
25
+ * which is not the server. The tmux session is the only thing both of them can
26
+ * see, and a user option on it is the cheapest shared channel that survives the
27
+ * CLI exiting, the server restarting, and a `client-detached` hook firing when
28
+ * neither is watching.
29
+ *
30
+ * ## Why the read is cached
31
+ *
32
+ * `checkForResponse` runs about every two seconds per active session. A
33
+ * `show-options` per poll would be one extra tmux round-trip per session per
34
+ * poll for a value that changes twice a day, so reads are memoised for
35
+ * {@link DELEGATION_TTL_MS}. The TTL is short enough that the restore edge is
36
+ * observed within one poll of the detach.
37
+ */
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DELEGATION_TTL_MS = void 0;
40
+ exports.isGeometryDelegated = isGeometryDelegated;
41
+ exports.probeGeometryDelegation = probeGeometryDelegation;
42
+ exports.hasHumanClientAttached = hasHumanClientAttached;
43
+ exports.forgetGeometryDelegation = forgetGeometryDelegation;
44
+ exports.resetGeometryDelegationState = resetGeometryDelegationState;
45
+ const child_process_1 = require("child_process");
46
+ const util_1 = require("util");
47
+ const tmux_session_surface_1 = require("../session/tmux-session-surface");
48
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
49
+ /** tmux calls here are interactive-latency, not long-running. */
50
+ const TMUX_TIMEOUT = 5000;
51
+ /**
52
+ * How long a delegation read is reused.
53
+ *
54
+ * One second, against a ~2s poll: short enough that the poll after a detach sees
55
+ * the restore, long enough that the several readers of one session in one poll
56
+ * (the status helper, the response checker) share a single tmux round-trip.
57
+ */
58
+ exports.DELEGATION_TTL_MS = 1000;
59
+ const cache = globalThis.__cmGeometryDelegationCache ??
60
+ (globalThis.__cmGeometryDelegationCache = new Map());
61
+ const lastObserved = globalThis.__cmGeometryDelegationEdge ??
62
+ (globalThis.__cmGeometryDelegationEdge = new Map());
63
+ /**
64
+ * Whether `@cm_delegated` is set to `1` on a session.
65
+ *
66
+ * Never throws: a session that has gone away, or a tmux that is not running, is
67
+ * "not delegated" — the answer that leaves every caller on its normal path.
68
+ *
69
+ * @param sessionName - Target session
70
+ * @param now - Epoch ms, injectable for tests
71
+ */
72
+ async function isGeometryDelegated(sessionName, now = Date.now()) {
73
+ const cached = cache.get(sessionName);
74
+ if (cached && now - cached.readAt < exports.DELEGATION_TTL_MS)
75
+ return cached.delegated;
76
+ let delegated = false;
77
+ try {
78
+ const { stdout } = await execFileAsync('tmux', (0, tmux_session_surface_1.buildShowSessionOptionValueArgs)(sessionName, tmux_session_surface_1.CM_DELEGATED_OPTION), { timeout: TMUX_TIMEOUT });
79
+ delegated = stdout.trim() === '1';
80
+ }
81
+ catch {
82
+ // THE ORDINARY CASE, not an error path. Measured on tmux 3.5a: asking for a
83
+ // user option a session does not carry exits NON-ZERO with
84
+ // `invalid option: @cm_delegated` — it is not an empty string and it is not
85
+ // exit 0. So "this session has never been delegated" arrives here, and it
86
+ // arrives here on every poll of every session, which is why nothing is
87
+ // logged. A session that is gone, and a tmux that is not running, land in
88
+ // the same place and mean the same thing.
89
+ delegated = false;
90
+ }
91
+ cache.set(sessionName, { delegated, readAt: now });
92
+ return delegated;
93
+ }
94
+ /**
95
+ * Read the delegation flag and report the release edge.
96
+ *
97
+ * The edge is what the poller needs: on restore the pane goes back to 1000 rows,
98
+ * so a `last_captured_line` recorded against a 44-row frame indexes into
99
+ * nothing. Resetting the cursor at that moment is what closes both the
100
+ * double-save window (a cursor too low re-saves) and the never-save window (a
101
+ * cursor too high suppresses forever).
102
+ *
103
+ * @param sessionName - Target session
104
+ * @param now - Epoch ms, injectable for tests
105
+ */
106
+ async function probeGeometryDelegation(sessionName, now = Date.now()) {
107
+ const delegated = await isGeometryDelegated(sessionName, now);
108
+ const previous = lastObserved.get(sessionName) ?? false;
109
+ lastObserved.set(sessionName, delegated);
110
+ return { delegated, released: previous && !delegated };
111
+ }
112
+ /**
113
+ * Whether any NON-control-mode client is attached to the session.
114
+ *
115
+ * Used by `reconcileSessionGeometry` as the second half of its skip condition:
116
+ * `@cm_delegated` says "a `--live` attach is in force", this says "somebody is
117
+ * looking at it right now". A control-mode client — CommandMate's own transport
118
+ * — never counts, which is what keeps the server from treating its own
119
+ * connection as a reason to stop pinning the canvas.
120
+ *
121
+ * Never throws; an unreadable client list is "nobody is attached".
122
+ */
123
+ async function hasHumanClientAttached(sessionName) {
124
+ try {
125
+ const { stdout } = await execFileAsync('tmux', (0, tmux_session_surface_1.buildListClientsArgs)(sessionName), {
126
+ timeout: TMUX_TIMEOUT,
127
+ });
128
+ return (0, tmux_session_surface_1.countHumanClients)(stdout) > 0;
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ }
134
+ /** Drop every memo for a session — call when it is known to be gone. */
135
+ function forgetGeometryDelegation(sessionName) {
136
+ cache.delete(sessionName);
137
+ lastObserved.delete(sessionName);
138
+ }
139
+ /** Test seam: drop every memo, for suites that drive several sessions. */
140
+ function resetGeometryDelegationState() {
141
+ cache.clear();
142
+ lastObserved.clear();
143
+ }
@@ -112,18 +112,31 @@ exports.PAGER_SCRIPT_FILENAME = 'cm-read-pane.sh';
112
112
  * stopped.
113
113
  */
114
114
  exports.PAGER_SCRIPT = `#!/bin/sh
115
- # CommandMate reading mode (Issue #1623) — generated file, edits are overwritten.
115
+ # CommandMate reading mode (Issue #1623; --follow added by #2317) — generated file, edits are overwritten.
116
116
  #
117
117
  # Renders the transcript of a CommandMate tmux session with layout-only blank rows
118
118
  # squeezed away, so a pager lands on the composer instead of hundreds of rows of
119
119
  # padding. Invoked by \`prefix+g\` through \`display-popup -E\`; also runnable by hand:
120
120
  #
121
121
  # sh ~/.commandmate/bin/${exports.PAGER_SCRIPT_FILENAME} mcbd-claude-my-worktree
122
+ # sh ~/.commandmate/bin/${exports.PAGER_SCRIPT_FILENAME} --follow mcbd-claude-my-worktree
122
123
  #
123
- # The popup is a SNAPSHOT. Press the key again to refresh it.
124
+ # Without --follow the popup is a SNAPSHOT. Press the key again to refresh it.
125
+ # With --follow (Issue #2317 Phase C) it redraws every CM_READ_FOLLOW_INTERVAL
126
+ # seconds and closes on \`q\`. Neither mode alters the pane, the window or the
127
+ # session — the popup is per-client and leaves nothing behind when it closes.
124
128
  set -u
125
129
 
126
- SESSION="\${1:-}"
130
+ FOLLOW=0
131
+ SESSION=""
132
+ for arg in "$@"; do
133
+ case "$arg" in
134
+ --follow|-f) FOLLOW=1 ;;
135
+ -*) ;;
136
+ *) if [ -z "$SESSION" ]; then SESSION="$arg"; fi ;;
137
+ esac
138
+ done
139
+
127
140
  if [ -z "$SESSION" ]; then
128
141
  SESSION=$(tmux display-message -p '#{session_name}' 2>/dev/null) || SESSION=""
129
142
  fi
@@ -137,6 +150,65 @@ case "$LINES_BACK" in
137
150
  ''|*[!0-9]*) LINES_BACK=1000 ;;
138
151
  esac
139
152
 
153
+ # LC_ALL is pinned for awk ONLY (not for less, which still renders UTF-8 box
154
+ # drawing in the user's locale). Under gawk in a UTF-8 locale, sprintf("%c",194)
155
+ # yields U+00C2 rather than the byte 0xC2 and the NBSP fold below silently stops
156
+ # matching. See SQUEEZE_AWK_LOCALE in read-mode-pager.ts.
157
+ cm_read_render() {
158
+ tmux capture-pane -pe -t "=$SESSION:" -S "-$LINES_BACK" -E - \\
159
+ | LC_ALL=${exports.SQUEEZE_AWK_LOCALE} awk '${exports.SQUEEZE_AWK_PROGRAM}'
160
+ }
161
+
162
+ if [ "$FOLLOW" = "1" ]; then
163
+ INTERVAL="\${CM_READ_FOLLOW_INTERVAL:-2}"
164
+ case "$INTERVAL" in
165
+ ''|*[!0-9]*) INTERVAL=2 ;;
166
+ esac
167
+ if [ "$INTERVAL" -lt 1 ]; then INTERVAL=1; fi
168
+ # The key check below waits 0.2s per tick (stty \`time 2\`), so one tick is a
169
+ # fifth of a second and the key is answered long before the next redraw.
170
+ TICKS=$((INTERVAL * 5))
171
+
172
+ OLD_STTY=$(stty -g 2>/dev/null) || OLD_STTY=""
173
+ cm_read_restore_tty() {
174
+ if [ -n "$OLD_STTY" ]; then stty "$OLD_STTY" 2>/dev/null || true; fi
175
+ printf '\\033[?25h'
176
+ }
177
+ trap 'cm_read_restore_tty' EXIT
178
+ trap 'cm_read_restore_tty; exit 0' INT TERM
179
+ # \`min 0 time 2\` is what makes a single-byte read non-blocking-with-a-deadline:
180
+ # it returns after 0.2s with nothing when no key was pressed. Without it the
181
+ # loop would either block forever on the key or busy-spin between redraws.
182
+ if [ -n "$OLD_STTY" ]; then stty -icanon -echo min 0 time 2 2>/dev/null || true; fi
183
+ printf '\\033[?25l'
184
+
185
+ ROWS=$(tput lines 2>/dev/null) || ROWS=40
186
+ case "$ROWS" in
187
+ ''|*[!0-9]*) ROWS=40 ;;
188
+ esac
189
+ BODY_ROWS=$((ROWS - 2))
190
+ if [ "$BODY_ROWS" -lt 1 ]; then BODY_ROWS=1; fi
191
+
192
+ while :; do
193
+ FRAME=$(cm_read_render | tail -n "$BODY_ROWS")
194
+ printf '\\033[H\\033[2J%s\\n' "$FRAME"
195
+ printf '\\033[7m[CommandMate] following %s — press q to close\\033[0m' "$SESSION"
196
+ TICK=0
197
+ while [ "$TICK" -lt "$TICKS" ]; do
198
+ if [ -n "$OLD_STTY" ]; then
199
+ KEY=$(dd bs=1 count=1 2>/dev/null)
200
+ case "$KEY" in
201
+ q|Q) exit 0 ;;
202
+ esac
203
+ else
204
+ sleep 1
205
+ TICK="$TICKS"
206
+ fi
207
+ TICK=$((TICK + 1))
208
+ done
209
+ done
210
+ fi
211
+
140
212
  if [ -n "\${CM_READ_PAGER:-}" ]; then
141
213
  PAGER_CMD="$CM_READ_PAGER"
142
214
  elif command -v less >/dev/null 2>&1; then
@@ -145,13 +217,7 @@ else
145
217
  PAGER_CMD="cat"
146
218
  fi
147
219
 
148
- # LC_ALL is pinned for awk ONLY (not for less, which still renders UTF-8 box
149
- # drawing in the user's locale). Under gawk in a UTF-8 locale, sprintf("%c",194)
150
- # yields U+00C2 rather than the byte 0xC2 and the NBSP fold below silently stops
151
- # matching. See SQUEEZE_AWK_LOCALE in read-mode-pager.ts.
152
- tmux capture-pane -pe -t "=$SESSION:" -S "-$LINES_BACK" -E - \\
153
- | LC_ALL=${exports.SQUEEZE_AWK_LOCALE} awk '${exports.SQUEEZE_AWK_PROGRAM}' \\
154
- | $PAGER_CMD
220
+ cm_read_render | $PAGER_CMD
155
221
 
156
222
  # Without a pager the popup would close before anything could be read.
157
223
  if [ "$PAGER_CMD" = "cat" ]; then
@@ -45,9 +45,11 @@
45
45
  * (`CM_READ_MODE=off` + restart), not a shutdown side effect.
46
46
  */
47
47
  Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.DEFAULT_READ_MODE_KEY = exports.MCBD_SESSION_PREFIX = void 0;
48
+ exports.READ_MODE_FOLLOW_ENV = exports.DEFAULT_READ_MODE_KEY = exports.MCBD_SESSION_PREFIX = void 0;
49
49
  exports.getPagerScriptPath = getPagerScriptPath;
50
50
  exports.isReadModeEnabled = isReadModeEnabled;
51
+ exports.isReadModeFollowEnabled = isReadModeFollowEnabled;
52
+ exports.buildPopupCommand = buildPopupCommand;
51
53
  exports.resolveReadModeKey = resolveReadModeKey;
52
54
  exports.quoteForTmuxCommand = quoteForTmuxCommand;
53
55
  exports.buildBindKeyArgs = buildBindKeyArgs;
@@ -79,6 +81,26 @@ const TMUX_TIMEOUT = 5000;
79
81
  exports.MCBD_SESSION_PREFIX = 'mcbd-';
80
82
  /** Key bound under the prefix table when `CM_READ_MODE_KEY` is unset. */
81
83
  exports.DEFAULT_READ_MODE_KEY = 'g';
84
+ /**
85
+ * Environment variable that makes `prefix + <key>` open the FOLLOWING popup
86
+ * instead of the snapshot one (Issue #2317, Phase C).
87
+ *
88
+ * ## Why one key and an option, rather than a second binding
89
+ *
90
+ * Issue #2317 offers two shapes for the follow mode — a second bound key
91
+ * (`CM_READ_MODE_FOLLOW_KEY`, default `G`) or a switch — and leaves the choice
92
+ * to implementation. This is the switch, for a reason that outlives the choice:
93
+ * a `bind-key` writes the tmux server's GLOBAL prefix table, which every session
94
+ * on the machine inherits including ones CommandMate knows nothing about. #2317
95
+ * 決定事項 2 says the new surface must stay session-scoped; a SECOND global key
96
+ * would have doubled the one global intervention the feature was allowed to
97
+ * keep. An environment variable costs no key table at all.
98
+ *
99
+ * The follow popup remains reachable two other ways with no key at all:
100
+ * `commandmate capture <id> --pane --follow`, and the opt-in
101
+ * `CM_READ_MODE_AUTO_POPUP=on`, which opens it on attach.
102
+ */
103
+ exports.READ_MODE_FOLLOW_ENV = 'CM_READ_MODE_FOLLOW';
82
104
  /**
83
105
  * Accepted `CM_READ_MODE_KEY` values: a single alphanumeric, an F-key, either
84
106
  * optionally with a `C-` / `M-` / `S-` modifier. Deliberately narrow — a typo
@@ -104,6 +126,26 @@ function isReadModeEnabled() {
104
126
  const raw = (process.env.CM_READ_MODE ?? '').trim().toLowerCase();
105
127
  return raw !== 'off' && raw !== '0' && raw !== 'false';
106
128
  }
129
+ /** True when the operator asked `prefix + <key>` to follow rather than snapshot. */
130
+ function isReadModeFollowEnabled() {
131
+ return (process.env[exports.READ_MODE_FOLLOW_ENV] ?? '').trim().toLowerCase() === 'on';
132
+ }
133
+ /**
134
+ * The shell command the popup runs: the pager script, plus `--follow` when the
135
+ * operator asked for it.
136
+ *
137
+ * One word per argument and no quoting of its own — {@link quoteForTmuxCommand}
138
+ * wraps the WHOLE line, so tmux hands `/bin/sh` a single command string. That is
139
+ * the same shape the snapshot form has always had; the flag rides inside the
140
+ * quotes rather than after them, because a word after the closing quote would be
141
+ * a second argument to `display-popup`, not to the script.
142
+ *
143
+ * @param scriptPath - Absolute path of the materialized pager script
144
+ * @param follow - Whether to append `--follow`
145
+ */
146
+ function buildPopupCommand(scriptPath, follow) {
147
+ return follow ? `${scriptPath} --follow` : scriptPath;
148
+ }
107
149
  /**
108
150
  * Resolve the configured key, or undefined when it is malformed.
109
151
  * @returns The key to bind, or undefined if `CM_READ_MODE_KEY` fails validation
@@ -283,7 +325,7 @@ async function reconcileReadModeBinding() {
283
325
  detail: 'display-popup requires tmux 3.2+; use `commandmate capture <id> --pane` instead',
284
326
  };
285
327
  }
286
- const quoted = quoteForTmuxCommand(scriptPath);
328
+ const quoted = quoteForTmuxCommand(buildPopupCommand(scriptPath, isReadModeFollowEnabled()));
287
329
  if (quoted === undefined) {
288
330
  return { installed: false, outcome: 'unsafe-script-path', key, scriptPath };
289
331
  }
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ /**
3
+ * The shell scripts session-scoped tmux hooks run (Issue #2317, Phases C and D).
4
+ *
5
+ * ## Why the text is embedded rather than shipped as a file
6
+ *
7
+ * The same reason `read-mode-pager.ts` gives for `cm-read-pane.sh`:
8
+ * `package.json`'s `files` list does not publish `scripts/`, and an `npx`
9
+ * install lives in a cache npm may garbage-collect out from under a hook that
10
+ * outlives the process which installed it. Embedding the text and materializing
11
+ * it into `~/.commandmate/bin/` gives every hook one absolute path that is
12
+ * stable across global / local / npx installs.
13
+ *
14
+ * ## Why the hooks call scripts instead of doing the work inline
15
+ *
16
+ * Measured on tmux 3.5a (Issue #2317 技術検証): a hook body of the shape
17
+ * `if-shell -F '#{…}' '<command>'` is accepted by `set-hook` and then never
18
+ * fires — silently, with no error anywhere. A
19
+ * `run-shell -b '<script> #{session_name} #{client_control_mode}'` DOES fire.
20
+ * So the formats are handed to a script and every branch is taken in `sh`.
21
+ *
22
+ * The hook environment is the tmux SERVER's, which carries `TMUX` — so the bare
23
+ * `tmux` these scripts call reaches the same server that fired the hook, private
24
+ * socket included. That is verified, not assumed: the whole live probe for this
25
+ * Issue ran under `tmux -L cm2317` and the scripts reached that server.
26
+ *
27
+ * ## Both scripts refuse to touch a session that is not CommandMate's
28
+ *
29
+ * A hook is session-scoped, so in principle it can only fire on the session it
30
+ * was installed on. The `mcbd-` guard is still there because these scripts are
31
+ * also runnable by hand and because a session can be renamed.
32
+ */
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.AUTO_POPUP_SCRIPT = exports.LIVE_DELEGATE_SCRIPT = exports.LIVE_RESTORE_SCRIPT = exports.AUTO_POPUP_SCRIPT_FILENAME = exports.LIVE_DELEGATE_SCRIPT_FILENAME = exports.LIVE_RESTORE_SCRIPT_FILENAME = void 0;
35
+ exports.getScriptDir = getScriptDir;
36
+ exports.getScriptPath = getScriptPath;
37
+ exports.materializeScript = materializeScript;
38
+ exports.materializeLiveRestoreScript = materializeLiveRestoreScript;
39
+ exports.materializeLiveDelegateScript = materializeLiveDelegateScript;
40
+ exports.materializeAutoPopupScript = materializeAutoPopupScript;
41
+ const fs_1 = require("fs");
42
+ const os_1 = require("os");
43
+ const path_1 = require("path");
44
+ const tmux_pane_config_1 = require("../../config/tmux-pane-config");
45
+ const tmux_session_surface_1 = require("../session/tmux-session-surface");
46
+ const read_mode_pager_1 = require("./read-mode-pager");
47
+ /** Basename of the Phase D geometry-restore script. */
48
+ exports.LIVE_RESTORE_SCRIPT_FILENAME = 'cm-live-restore.sh';
49
+ /** Basename of the Phase D geometry-delegation script. */
50
+ exports.LIVE_DELEGATE_SCRIPT_FILENAME = 'cm-live-delegate.sh';
51
+ /** Basename of the Phase C auto-popup script. */
52
+ exports.AUTO_POPUP_SCRIPT_FILENAME = 'cm-auto-popup.sh';
53
+ /**
54
+ * Restore a session's pinned canvas once no human client is attached.
55
+ *
56
+ * NOT a hook body — tmux 3.5a never fires a session-scoped `client-detached`
57
+ * (see the measurement table in `live-attach.ts`). Two things run this sequence:
58
+ * `commandmate attach --live` when `attach-session` returns, and the server's
59
+ * status poll (`reconcileDelegatedGeometry`) for every case where the CLI never
60
+ * got to — it was killed, the terminal window was closed, or the detach happened
61
+ * from a client this process never saw. This script is the third, manual, path:
62
+ * the escape hatch for a session left delegated while no server is running.
63
+ *
64
+ * The control-mode test is the whole reason the client count is not simply
65
+ * `#{session_attached}`: CommandMate's own transport attaches as a `tmux -C`
66
+ * client and never leaves, so a session with the human gone still reports
67
+ * `session_attached=1`. `client_control_mode` is `1` for those and `0` for a
68
+ * terminal, so the restore waits for the HUMAN count to reach zero
69
+ * (Issue #2317 受入条件 Phase D 4).
70
+ */
71
+ exports.LIVE_RESTORE_SCRIPT = `#!/bin/sh
72
+ # CommandMate live-attach restore (Issue #2317) — generated file, edits are overwritten.
73
+ #
74
+ # sh ~/.commandmate/bin/${exports.LIVE_RESTORE_SCRIPT_FILENAME} <session> [control_mode] [width] [height]
75
+ #
76
+ # Pins the session's window back to CommandMate's canvas once no human client is
77
+ # attached to it any more. Safe to run when nothing is delegated: it then simply
78
+ # re-applies the geometry the session already has.
79
+ set -u
80
+
81
+ SESSION="\${1:-}"
82
+ CONTROL_MODE="\${2:-0}"
83
+ WIDTH="\${3:-${tmux_pane_config_1.TUI_PANE_WIDTH}}"
84
+ HEIGHT="\${4:-${tmux_pane_config_1.TUI_PANE_HEIGHT}}"
85
+
86
+ case "$SESSION" in
87
+ ${tmux_session_surface_1.MCBD_SESSION_PREFIX}*) ;;
88
+ *) exit 0 ;;
89
+ esac
90
+
91
+ # A control-mode client detaching is CommandMate's own transport reconnecting,
92
+ # not the human leaving. Doing the restore here would fight the human's attach.
93
+ if [ "$CONTROL_MODE" = "1" ]; then
94
+ exit 0
95
+ fi
96
+
97
+ # Anyone left who is NOT a control client? Then the geometry is still theirs.
98
+ HUMANS=$(tmux list-clients -t "=$SESSION:" -F '#{client_control_mode}' 2>/dev/null \\
99
+ | grep -c -v '^1$') || HUMANS=0
100
+ if [ "\${HUMANS:-0}" -gt 0 ]; then
101
+ exit 0
102
+ fi
103
+
104
+ tmux set-window-option -t "=$SESSION:" window-size manual 2>/dev/null || exit 0
105
+ tmux resize-window -t "=$SESSION:" -x "$WIDTH" -y "$HEIGHT" 2>/dev/null || true
106
+ tmux set-option -u -t "=$SESSION:" @cm_delegated 2>/dev/null || true
107
+ `;
108
+ /**
109
+ * Hand a session's geometry to the terminal that just attached.
110
+ *
111
+ * The opt-in half of Phase D: `commandmate attach --live` performs these two
112
+ * writes itself, and this script is what makes a HAND-ROLLED `tmux attach`
113
+ * behave the same way when the operator asked for it with
114
+ * `CM_LIVE_ATTACH_HOOK=on`.
115
+ *
116
+ * claude-only by session-name prefix, and that is not a shortcut. The session
117
+ * name is `mcbd-<tool>-<worktree>`, no other CLI tool id begins with `claude`,
118
+ * and the script has nothing but the name to go on — a hook fires with tmux
119
+ * formats, not with CommandMate's roster. Widening it means widening
120
+ * `LIVE_ATTACH_TOOLS` too, and that needs the per-tool re-measurement
121
+ * Issue #2317 puts out of scope.
122
+ */
123
+ exports.LIVE_DELEGATE_SCRIPT = `#!/bin/sh
124
+ # CommandMate live-attach delegate (Issue #2317) — generated file, edits are overwritten.
125
+ #
126
+ # sh ~/.commandmate/bin/${exports.LIVE_DELEGATE_SCRIPT_FILENAME} <session> <control_mode> [client]
127
+ #
128
+ # Hands the session's window from CommandMate's pinned canvas to the terminal
129
+ # that just attached, so an alternate-screen agent re-lays-out and its transcript
130
+ # becomes readable. Installed as a session-scoped \`client-attached[0]\` hook only
131
+ # when CM_LIVE_ATTACH_HOOK=on; \`commandmate attach --live\` does the same two
132
+ # writes itself and needs no hook.
133
+ #
134
+ # The window is put back by whoever notices the human is gone first: the CLI on
135
+ # return from attach-session, or the server's status poll. This script never
136
+ # restores — the attach edge is the only edge tmux 3.5a lets a session-scoped
137
+ # hook see.
138
+ set -u
139
+
140
+ SESSION="\${1:-}"
141
+ CONTROL_MODE="\${2:-0}"
142
+
143
+ case "$SESSION" in
144
+ ${tmux_session_surface_1.MCBD_SESSION_PREFIX}claude-*) ;;
145
+ *) exit 0 ;;
146
+ esac
147
+
148
+ # A control-mode client is CommandMate's own transport. Handing it the geometry
149
+ # would resize the canvas to whatever that connection negotiated, which is the
150
+ # #1163 regression this whole feature is built to avoid.
151
+ if [ "$CONTROL_MODE" = "1" ]; then
152
+ exit 0
153
+ fi
154
+
155
+ # Raised BEFORE the size change, so a status poll landing between the two sees
156
+ # "delegated, still pinned" rather than "not delegated, 44 rows".
157
+ tmux set-option -t "=$SESSION:" @cm_delegated 1 2>/dev/null || exit 0
158
+ tmux set-window-option -t "=$SESSION:" window-size latest 2>/dev/null || true
159
+ `;
160
+ /**
161
+ * Open the following transcript popup when a human attaches (Phase C, opt-in).
162
+ *
163
+ * Default off, and it has to be: the popup owns the keyboard until `q` is
164
+ * pressed, so opening it unasked would make every attach start by taking input
165
+ * away from the composer. `CM_READ_MODE_AUTO_POPUP=on` is the opt-in, and even
166
+ * then the control-mode test below keeps it from firing for CommandMate's own
167
+ * transport — a popup opened on a control client would be a popup nobody can
168
+ * see and nobody can close.
169
+ */
170
+ exports.AUTO_POPUP_SCRIPT = `#!/bin/sh
171
+ # CommandMate auto read popup (Issue #2317) — generated file, edits are overwritten.
172
+ #
173
+ # sh ~/.commandmate/bin/${exports.AUTO_POPUP_SCRIPT_FILENAME} <session> <control_mode> <client>
174
+ #
175
+ # Opens the following transcript popup for a human client attaching to a
176
+ # CommandMate session. Never opens for a control-mode client.
177
+ set -u
178
+
179
+ SESSION="\${1:-}"
180
+ CONTROL_MODE="\${2:-0}"
181
+ CLIENT="\${3:-}"
182
+
183
+ case "$SESSION" in
184
+ ${tmux_session_surface_1.MCBD_SESSION_PREFIX}*) ;;
185
+ *) exit 0 ;;
186
+ esac
187
+
188
+ if [ "$CONTROL_MODE" = "1" ]; then
189
+ exit 0
190
+ fi
191
+
192
+ PAGER_SCRIPT="$HOME/.commandmate/bin/${read_mode_pager_1.PAGER_SCRIPT_FILENAME}"
193
+ [ -x "$PAGER_SCRIPT" ] || exit 0
194
+
195
+ if [ -n "$CLIENT" ]; then
196
+ tmux display-popup -c "$CLIENT" -w 90% -h 85% -E "sh \\"$PAGER_SCRIPT\\" --follow \\"$SESSION\\"" 2>/dev/null || true
197
+ else
198
+ tmux display-popup -w 90% -h 85% -E "sh \\"$PAGER_SCRIPT\\" --follow \\"$SESSION\\"" 2>/dev/null || true
199
+ fi
200
+ `;
201
+ /** Directory every materialized CommandMate script lives in. */
202
+ function getScriptDir() {
203
+ return (0, path_1.join)((0, os_1.homedir)(), '.commandmate', 'bin');
204
+ }
205
+ /** Absolute path of a materialized script. */
206
+ function getScriptPath(filename) {
207
+ return (0, path_1.join)(getScriptDir(), filename);
208
+ }
209
+ /**
210
+ * Write a script to `~/.commandmate/bin/<filename>` if its content changed.
211
+ *
212
+ * Idempotent by content comparison so a restart does not churn the file's mtime,
213
+ * and re-executable after a `chmod` accident because the mode is re-applied —
214
+ * the same contract `materializePagerScript()` has had since #1623.
215
+ *
216
+ * @param filename - Basename to write
217
+ * @param content - Full script text
218
+ * @returns The absolute path written
219
+ */
220
+ function materializeScript(filename, content) {
221
+ const scriptPath = getScriptPath(filename);
222
+ (0, fs_1.mkdirSync)((0, path_1.dirname)(scriptPath), { recursive: true });
223
+ let current;
224
+ if ((0, fs_1.existsSync)(scriptPath)) {
225
+ try {
226
+ current = (0, fs_1.readFileSync)(scriptPath, 'utf-8');
227
+ }
228
+ catch {
229
+ current = undefined;
230
+ }
231
+ }
232
+ if (current !== content) {
233
+ (0, fs_1.writeFileSync)(scriptPath, content, { mode: 0o755 });
234
+ }
235
+ (0, fs_1.chmodSync)(scriptPath, 0o755);
236
+ return scriptPath;
237
+ }
238
+ /** Materialize the Phase D restore script and return its absolute path. */
239
+ function materializeLiveRestoreScript() {
240
+ return materializeScript(exports.LIVE_RESTORE_SCRIPT_FILENAME, exports.LIVE_RESTORE_SCRIPT);
241
+ }
242
+ /** Materialize the Phase D delegate script and return its absolute path. */
243
+ function materializeLiveDelegateScript() {
244
+ return materializeScript(exports.LIVE_DELEGATE_SCRIPT_FILENAME, exports.LIVE_DELEGATE_SCRIPT);
245
+ }
246
+ /** Materialize the Phase C auto-popup script and return its absolute path. */
247
+ function materializeAutoPopupScript() {
248
+ return materializeScript(exports.AUTO_POPUP_SCRIPT_FILENAME, exports.AUTO_POPUP_SCRIPT);
249
+ }