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,525 @@
1
+ "use strict";
2
+ /**
3
+ * The tmux "surface" CommandMate publishes on its own sessions (Issue #2317).
4
+ *
5
+ * Everything here is a pure argument builder or a pure predicate — no
6
+ * `child_process`, no `@/` path alias, and one constants import. Three
7
+ * constraints put it here rather than under `lib/tmux/`, and all three are
8
+ * load-bearing:
9
+ *
10
+ * 1. **`tsconfig.cli.json` sets `"paths": {}`.** The CLI bundle resolves nothing
11
+ * through `@/…`, so a module the `attach` command needs may only reach the
12
+ * rest of `src/` through relative specifiers. `lib/tmux/tmux.ts` cannot be
13
+ * that module — it imports `@/lib/cli-tools/validation` and `@/lib/logger`.
14
+ * 2. **The Issue #1922 import guard.** `.eslintrc.json` forbids `src/cli/**`
15
+ * from importing anything matching `**‍/tmux/**`, and its allowlist is
16
+ * explicitly one-way ("may only shrink"). A pure argv builder is not the kind
17
+ * of tmux access that guard exists to stop — it issues no command and opens
18
+ * no session — but the rule is a path pattern, so the module lives on a path
19
+ * the CLI may read. Nothing here can reach tmux: the executors are in
20
+ * `lib/tmux/`, and those are what the guard still covers.
21
+ * 3. **One wire form, two callers.** The server writes `@cm_status` from the
22
+ * status poll and the CLI writes `@cm_delegated` from `attach --live`. If
23
+ * each spelled its own `set-option` argv, the two could disagree about the
24
+ * target form (`=name:` vs `name`), and a bare name prefix-matches — the
25
+ * Issue #1156 leak, in a new place. Tests assert the builders, so a change to
26
+ * the wire form is a change to exactly one line.
27
+ *
28
+ * ## What is deliberately NOT here
29
+ *
30
+ * Anything server-global. Every builder below takes a session name and produces
31
+ * a `-t <session>` form: `set-option -g`, `bind-key` and `set-hook -g` are
32
+ * absent on purpose (Issue #2317 決定事項 2 — the only global tmux mutation
33
+ * CommandMate makes is #1623's `bind-key`, and it stays where it is, in
34
+ * `lib/tmux/read-mode.ts`).
35
+ */
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.ATTACH_HOOK_FORMATS = exports.AUTO_POPUP_ENV = exports.LIVE_ATTACH_HOOK_ENV = exports.AUTO_POPUP_HOOK = exports.DELEGATE_HOOK = exports.ALT_SCREEN_TOOLS = exports.LIVE_ATTACH_TOOLS = exports.TMUX_STATUS_ENV = exports.CM_STATUS_RIGHT_FORMAT = exports.CM_SESSION_OPTIONS = exports.CM_DELEGATED_OPTION = exports.CM_UPDATED_OPTION = exports.CM_INSTANCE_OPTION = exports.CM_TOOL_OPTION = exports.CM_WORKTREE_OPTION = exports.CM_STATUS_OPTION = exports.MCBD_SESSION_PREFIX = void 0;
38
+ exports.exactSessionTarget = exactSessionTarget;
39
+ exports.isCommandMateSession = isCommandMateSession;
40
+ exports.buildSetSessionOptionArgs = buildSetSessionOptionArgs;
41
+ exports.buildUnsetSessionOptionArgs = buildUnsetSessionOptionArgs;
42
+ exports.buildShowSessionOptionArgs = buildShowSessionOptionArgs;
43
+ exports.buildShowSessionOptionValueArgs = buildShowSessionOptionValueArgs;
44
+ exports.buildSetStatusRightArgs = buildSetStatusRightArgs;
45
+ exports.buildUnsetStatusRightArgs = buildUnsetStatusRightArgs;
46
+ exports.isTmuxStatusEnabled = isTmuxStatusEnabled;
47
+ exports.buildSetSessionHookArgs = buildSetSessionHookArgs;
48
+ exports.buildUnsetSessionHookArgs = buildUnsetSessionHookArgs;
49
+ exports.buildShowSessionHooksArgs = buildShowSessionHooksArgs;
50
+ exports.buildWindowSizeArgs = buildWindowSizeArgs;
51
+ exports.buildResizeWindowArgs = buildResizeWindowArgs;
52
+ exports.buildListClientsArgs = buildListClientsArgs;
53
+ exports.countHumanClients = countHumanClients;
54
+ exports.buildAttachArgs = buildAttachArgs;
55
+ exports.buildSwitchClientArgs = buildSwitchClientArgs;
56
+ exports.isLiveAttachSupported = isLiveAttachSupported;
57
+ exports.isLiveAttachEligibleSession = isLiveAttachEligibleSession;
58
+ exports.usesAltScreen = usesAltScreen;
59
+ exports.isLiveAttachHookEnabled = isLiveAttachHookEnabled;
60
+ exports.isAutoPopupEnabled = isAutoPopupEnabled;
61
+ exports.quoteScriptPathForHook = quoteScriptPathForHook;
62
+ exports.buildHookRunShellBody = buildHookRunShellBody;
63
+ exports.buildInstallDelegateHookArgs = buildInstallDelegateHookArgs;
64
+ exports.buildRemoveDelegateHookArgs = buildRemoveDelegateHookArgs;
65
+ exports.buildInstallAutoPopupHookArgs = buildInstallAutoPopupHookArgs;
66
+ exports.buildRemoveAutoPopupHookArgs = buildRemoveAutoPopupHookArgs;
67
+ exports.buildDelegateGeometryCommands = buildDelegateGeometryCommands;
68
+ exports.buildRestoreGeometryCommands = buildRestoreGeometryCommands;
69
+ const tmux_pane_config_1 = require("../../config/tmux-pane-config");
70
+ /**
71
+ * Session-name prefix every CommandMate tmux session carries.
72
+ *
73
+ * `lib/tmux/read-mode.ts` owns a constant of the same name for #1623's key
74
+ * binding; `tests/unit/tmux/session-surface-2317.test.ts` pins the two together
75
+ * so a rename breaks a test instead of silently turning a guard into a permanent
76
+ * "never fire". Not imported from `cli-tools/base.ts` because it is a template
77
+ * literal there, not a constant.
78
+ */
79
+ exports.MCBD_SESSION_PREFIX = 'mcbd-';
80
+ /**
81
+ * Exact-match tmux target for a session (Issue #1156's `=name:` form).
82
+ *
83
+ * The same string `exactTarget()` in `lib/tmux/tmux.ts` produces — that function
84
+ * stays the one the server-side module uses, and the test above pins the two to
85
+ * each other so this copy cannot drift. It exists at all because `tmux.ts` is
86
+ * unreachable from the CLI bundle (see the module docblock).
87
+ *
88
+ * @param sessionName - Exact tmux session name
89
+ * @returns `=<name>:` — exact session match, valid as both a session and a
90
+ * window/pane target
91
+ */
92
+ function exactSessionTarget(sessionName) {
93
+ return `=${sessionName}:`;
94
+ }
95
+ /** True when `sessionName` looks like a session CommandMate created. */
96
+ function isCommandMateSession(sessionName) {
97
+ return sessionName.startsWith(exports.MCBD_SESSION_PREFIX);
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // Phase B: the state CommandMate publishes onto its own sessions
101
+ // ---------------------------------------------------------------------------
102
+ /** User option carrying the session's status word. */
103
+ exports.CM_STATUS_OPTION = '@cm_status';
104
+ /** User option carrying the worktree id the session belongs to. */
105
+ exports.CM_WORKTREE_OPTION = '@cm_worktree';
106
+ /** User option carrying the CLI tool id running in the session. */
107
+ exports.CM_TOOL_OPTION = '@cm_tool';
108
+ /** User option carrying the agent instance id. */
109
+ exports.CM_INSTANCE_OPTION = '@cm_instance';
110
+ /** User option carrying the ISO timestamp of the last status write. */
111
+ exports.CM_UPDATED_OPTION = '@cm_updated';
112
+ /**
113
+ * User option set to `1` while a human client owns the session's geometry
114
+ * (Phase D). Read by the server so it can stand down from resizing and from
115
+ * saving a scraped reply off a terminal-sized frame.
116
+ */
117
+ exports.CM_DELEGATED_OPTION = '@cm_delegated';
118
+ /**
119
+ * Every `@cm_*` option this feature writes, in the order they are removed.
120
+ *
121
+ * The opt-out path (`CM_TMUX_STATUS=off`) iterates this list rather than
122
+ * re-typing names, so an option added above cannot be left behind on a user's
123
+ * tmux server.
124
+ */
125
+ exports.CM_SESSION_OPTIONS = [
126
+ exports.CM_STATUS_OPTION,
127
+ exports.CM_WORKTREE_OPTION,
128
+ exports.CM_TOOL_OPTION,
129
+ exports.CM_INSTANCE_OPTION,
130
+ exports.CM_UPDATED_OPTION,
131
+ exports.CM_DELEGATED_OPTION,
132
+ ];
133
+ /**
134
+ * The session-scoped `status-right` CommandMate installs.
135
+ *
136
+ * A tmux FORMAT, not an interpolated string: the values come from the `@cm_*`
137
+ * options above, so the status line re-renders on every status write without a
138
+ * second write for the line itself. `window_width`x`window_height` is on it
139
+ * because the whole Issue is about a window whose size the reader cannot see —
140
+ * during Phase D delegation it is the fastest way to tell whether the geometry
141
+ * handover actually happened.
142
+ */
143
+ exports.CM_STATUS_RIGHT_FORMAT = '[CommandMate #{@cm_tool}/#{@cm_instance} #{@cm_status}] #{window_width}x#{window_height}';
144
+ /** `tmux set-option -t <session> <name> <value>`. */
145
+ function buildSetSessionOptionArgs(sessionName, option, value) {
146
+ return ['set-option', '-t', exactSessionTarget(sessionName), option, value];
147
+ }
148
+ /** `tmux set-option -u -t <session> <name>` — remove a session-scoped value. */
149
+ function buildUnsetSessionOptionArgs(sessionName, option) {
150
+ return ['set-option', '-u', '-t', exactSessionTarget(sessionName), option];
151
+ }
152
+ /**
153
+ * `tmux show-options -t <session> <name>`.
154
+ *
155
+ * Deliberately WITHOUT `-v`: the empty-vs-set distinction is the whole point of
156
+ * the call at the `status-right` site. Measured on tmux 3.5a — a session that
157
+ * has never had `status-right` set answers with empty stdout and exit 0, and one
158
+ * that has answers `status-right "…"`. `-v` would print an empty line for the
159
+ * first case too, and "the user already customised this session" would become
160
+ * indistinguishable from "nobody has".
161
+ */
162
+ function buildShowSessionOptionArgs(sessionName, option) {
163
+ return ['show-options', '-t', exactSessionTarget(sessionName), option];
164
+ }
165
+ /**
166
+ * `tmux show-options -v -t <session> <name>` — the VALUE alone.
167
+ *
168
+ * The right shape when only the value matters (`@cm_delegated` is `1` or it is
169
+ * nothing). {@link buildShowSessionOptionArgs} is the right shape when the
170
+ * distinction between "set to empty" and "never set" matters, which is the
171
+ * `status-right` case.
172
+ */
173
+ function buildShowSessionOptionValueArgs(sessionName, option) {
174
+ return ['show-options', '-v', '-t', exactSessionTarget(sessionName), option];
175
+ }
176
+ /** `tmux set-option -t <session> status-right '<format>'`. */
177
+ function buildSetStatusRightArgs(sessionName, format) {
178
+ return buildSetSessionOptionArgs(sessionName, 'status-right', format);
179
+ }
180
+ /** `tmux set-option -u -t <session> status-right`. */
181
+ function buildUnsetStatusRightArgs(sessionName) {
182
+ return buildUnsetSessionOptionArgs(sessionName, 'status-right');
183
+ }
184
+ /** Environment variable that turns the Phase B surface off. */
185
+ exports.TMUX_STATUS_ENV = 'CM_TMUX_STATUS';
186
+ /**
187
+ * True unless the operator set `CM_TMUX_STATUS` to `off` / `0` / `false`.
188
+ *
189
+ * Read at CALL time from an injected environment rather than at module load, so
190
+ * a test can flip it without module-registry surgery and so a process started
191
+ * with the variable set is not at the mercy of import order.
192
+ */
193
+ function isTmuxStatusEnabled(env = process.env) {
194
+ const raw = (env[exports.TMUX_STATUS_ENV] ?? '').trim().toLowerCase();
195
+ return raw !== 'off' && raw !== '0' && raw !== 'false';
196
+ }
197
+ // ---------------------------------------------------------------------------
198
+ // Session-scoped hooks
199
+ // ---------------------------------------------------------------------------
200
+ /**
201
+ * `tmux set-hook -t <session> <hook> <command>`.
202
+ *
203
+ * The command is passed as ONE argv element. Do not fold an `if-shell -F` into
204
+ * it: measured on tmux 3.5a (Issue #2317 技術検証), a hook body of the shape
205
+ * `if-shell -F '#{…}' 'display-popup …'` is accepted and then silently never
206
+ * fires. A `run-shell -b '<script> #{session_name} #{client_control_mode}'` that
207
+ * hands the formats to a script DOES fire, so every hook this feature installs
208
+ * has that shape and the branching happens in the script.
209
+ */
210
+ function buildSetSessionHookArgs(sessionName, hook, command) {
211
+ return ['set-hook', '-t', exactSessionTarget(sessionName), hook, command];
212
+ }
213
+ /** `tmux set-hook -u -t <session> <hook>`. */
214
+ function buildUnsetSessionHookArgs(sessionName, hook) {
215
+ return ['set-hook', '-u', '-t', exactSessionTarget(sessionName), hook];
216
+ }
217
+ /** `tmux show-hooks -t <session>` — session-scoped hooks only, never the global table. */
218
+ function buildShowSessionHooksArgs(sessionName) {
219
+ return ['show-hooks', '-t', exactSessionTarget(sessionName)];
220
+ }
221
+ // ---------------------------------------------------------------------------
222
+ // Geometry
223
+ // ---------------------------------------------------------------------------
224
+ /** `tmux set-window-option -t <session> window-size <mode>`. */
225
+ function buildWindowSizeArgs(sessionName, mode) {
226
+ return ['set-window-option', '-t', exactSessionTarget(sessionName), 'window-size', mode];
227
+ }
228
+ /** `tmux resize-window -t <session> -x <w> -y <h>`. */
229
+ function buildResizeWindowArgs(sessionName, width, height) {
230
+ return [
231
+ 'resize-window',
232
+ '-t',
233
+ exactSessionTarget(sessionName),
234
+ '-x',
235
+ String(width),
236
+ '-y',
237
+ String(height),
238
+ ];
239
+ }
240
+ /**
241
+ * `tmux list-clients -t <session> -F '#{client_control_mode}'`.
242
+ *
243
+ * `client_control_mode` is `1` for a `tmux -C` client — which is what
244
+ * CommandMate's own control-mode transport attaches as — and `0` for a human
245
+ * terminal. Phase D hands the geometry back when the HUMAN count reaches zero,
246
+ * so a control client sitting on the session forever must not keep the
247
+ * delegation open (Issue #2317 受入条件 Phase D 4).
248
+ */
249
+ function buildListClientsArgs(sessionName) {
250
+ return ['list-clients', '-t', exactSessionTarget(sessionName), '-F', '#{client_control_mode}'];
251
+ }
252
+ /**
253
+ * Number of human (control-mode `0`) clients in `list-clients` output.
254
+ *
255
+ * Counts lines that are exactly `0`, NOT lines that are "anything but 1". The
256
+ * difference matters twice: `list-clients` exits 0 with EMPTY stdout on a
257
+ * detached session, and a line this function does not recognise is not evidence
258
+ * that a person is looking at the pane. Since the answer gates a resize, "I
259
+ * could not read this" has to mean "nobody is attached" — the reading that
260
+ * leaves `reconcileSessionGeometry` doing its normal job — rather than "somebody
261
+ * is", which would pin a window open on an unparsed byte.
262
+ *
263
+ * `#{client_control_mode}` is `1` for a `tmux -C` client and `0` for a terminal;
264
+ * measured on tmux 3.5a, a human client attached to a CommandMate session
265
+ * reports exactly `0`.
266
+ *
267
+ * @param stdout - Raw stdout of {@link buildListClientsArgs}
268
+ * @returns How many attached clients are humans
269
+ */
270
+ function countHumanClients(stdout) {
271
+ return stdout
272
+ .split('\n')
273
+ .map((line) => line.trim())
274
+ .filter((line) => line === '0').length;
275
+ }
276
+ /** `tmux attach-session -t '=<session>:'`, with `-r` when read-only. */
277
+ function buildAttachArgs(sessionName, readOnly) {
278
+ const args = ['attach-session'];
279
+ if (readOnly)
280
+ args.push('-r');
281
+ args.push('-t', exactSessionTarget(sessionName));
282
+ return args;
283
+ }
284
+ /** `tmux switch-client -t '=<session>:'` — the in-tmux equivalent of attaching. */
285
+ function buildSwitchClientArgs(sessionName) {
286
+ return ['switch-client', '-t', exactSessionTarget(sessionName)];
287
+ }
288
+ // ---------------------------------------------------------------------------
289
+ // Which tools each behaviour applies to
290
+ // ---------------------------------------------------------------------------
291
+ /**
292
+ * CLI tools `attach --live` will hand the pane geometry to (Issue #2317 決定事項 3).
293
+ *
294
+ * claude alone, and the list is a measurement rather than a starting point:
295
+ * claude's reply is written from its own transcript JSONL, so a terminal-sized
296
+ * frame during delegation cannot lose History. Every other tool either reads its
297
+ * reply off the pane (copilot / gemini / vibe-local), or has detection rules
298
+ * that were only ever measured at 200x1000 (codex / antigravity / command-code),
299
+ * or cannot survive a width change at all (opencode paints a sidebar at >=121
300
+ * columns). Widening this set is out of scope for #2317 and requires
301
+ * re-measuring the tool it adds.
302
+ */
303
+ exports.LIVE_ATTACH_TOOLS = ['claude'];
304
+ /** Whether `attach --live` is allowed for a CLI tool. */
305
+ function isLiveAttachSupported(cliToolId) {
306
+ return exports.LIVE_ATTACH_TOOLS.includes(cliToolId);
307
+ }
308
+ /**
309
+ * Whether a tmux session's NAME says it runs a tool `--live` supports.
310
+ *
311
+ * The session name is `mcbd-<tool>-<worktree>` and no supported tool id is a
312
+ * prefix of another, so this is exact rather than a guess. It exists because
313
+ * the two callers that need the answer — the attach hook script's installer and
314
+ * the response poller — hold a session name and nothing else: a hook fires with
315
+ * tmux formats, and the poller must not pay a tmux round-trip to ask about a
316
+ * session that could never be delegated in the first place.
317
+ *
318
+ * @param sessionName - tmux session name
319
+ */
320
+ function isLiveAttachEligibleSession(sessionName) {
321
+ if (!isCommandMateSession(sessionName))
322
+ return false;
323
+ return exports.LIVE_ATTACH_TOOLS.some((tool) => sessionName.startsWith(`${exports.MCBD_SESSION_PREFIX}${tool}-`));
324
+ }
325
+ /**
326
+ * CLI tools that paint their transcript in the terminal's alternate screen.
327
+ *
328
+ * The reason a bare `tmux attach` looks EMPTY for them: the TUI draws the
329
+ * transcript at the top of a 1000-row canvas and its composer at the bottom, and
330
+ * tmux follows the cursor, so a 44-row client sees the composer and nothing
331
+ * else. `attach` prints its hint for exactly these.
332
+ *
333
+ * Deliberately a local list rather than an import of `usesAlternateScreen()`:
334
+ * this module must stay free of `lib/cli-tools`, whose graph the CLI bundle
335
+ * cannot afford (see the module docblock). The two are pinned to each other by
336
+ * `tests/unit/tmux/session-surface-2317.test.ts`, so a tool moving in or out of
337
+ * the alternate screen breaks a test rather than silently dropping the hint.
338
+ */
339
+ exports.ALT_SCREEN_TOOLS = ['claude', 'opencode', 'copilot'];
340
+ /** Whether `attach` should warn that a bare attach shows no transcript. */
341
+ function usesAltScreen(cliToolId) {
342
+ return exports.ALT_SCREEN_TOOLS.includes(cliToolId);
343
+ }
344
+ // ---------------------------------------------------------------------------
345
+ // Phase D: live attach — handing the geometry over and taking it back
346
+ // ---------------------------------------------------------------------------
347
+ /**
348
+ * ## The safety net is a poll, NOT a `client-detached` hook — measured
349
+ *
350
+ * Issue #2317's 技術検証 says a session-scoped `client-detached` hook fires.
351
+ * Re-measured on tmux 3.5a against a private socket before this was written, it
352
+ * does not, and two further facts make the shape unusable:
353
+ *
354
+ * | probe (tmux 3.5a, `tmux -L`) | result |
355
+ * |-----------------------------------------------------|--------|
356
+ * | `set-hook -t <s> client-attached`, human attaches | fires; `#{session_name}` is the session, `#{client_control_mode}` is `0` |
357
+ * | same, control-mode client attaches | does NOT fire |
358
+ * | `set-hook -t <s> client-detached`, human detaches | **never fires** |
359
+ * | `set-hook -g client-detached`, human detaches | fires — but `#{session_name}` is the CLIENT's other session and `#{client_control_mode}` is EMPTY |
360
+ *
361
+ * So the detach edge is unreachable session-scoped, and reaching it globally
362
+ * would both break 決定事項 2 (no global tmux mutation) and arrive without the
363
+ * session identity the restore needs. The restore therefore runs from the status
364
+ * poll instead — `reconcileDelegatedGeometry()` in `lib/tmux/session-hooks.ts` —
365
+ * which sees every session every couple of seconds, needs no tmux state of its
366
+ * own, and covers cases a hook could not anyway: the CLI being killed, the
367
+ * terminal window being closed, and a detach from some other client.
368
+ *
369
+ * The `client-attached` edge DOES work session-scoped, and that is the one the
370
+ * opt-in hooks below are installed on.
371
+ *
372
+ * Both opt-in features hang off that same edge, and a tmux hook name without an
373
+ * index IS `[0]`: installing two of them unindexed would mean the second
374
+ * silently replaced the first. Measured on tmux 3.5a — `client-attached[0]` and
375
+ * `client-attached[1]` both fire, and `set-hook -u` removes one without
376
+ * disturbing the other.
377
+ */
378
+ exports.DELEGATE_HOOK = 'client-attached[0]';
379
+ /** @see DELEGATE_HOOK */
380
+ exports.AUTO_POPUP_HOOK = 'client-attached[1]';
381
+ /**
382
+ * Environment variable that also installs the geometry hand-over for a session
383
+ * the user attached to BY HAND (`tmux attach`), not through
384
+ * `commandmate attach --live`.
385
+ *
386
+ * Opt-in, because installing it unasked would mean a hand-rolled `tmux attach`
387
+ * silently changes a session's geometry — the one thing Issue #2317 決定事項 1
388
+ * says must not happen by default.
389
+ */
390
+ exports.LIVE_ATTACH_HOOK_ENV = 'CM_LIVE_ATTACH_HOOK';
391
+ /**
392
+ * Environment variable that opens the following read popup on attach (Phase C).
393
+ * Default off; see `AUTO_POPUP_SCRIPT` for why.
394
+ */
395
+ exports.AUTO_POPUP_ENV = 'CM_READ_MODE_AUTO_POPUP';
396
+ /** True when the operator opted into the attach-time geometry hand-over. */
397
+ function isLiveAttachHookEnabled(env = process.env) {
398
+ return (env[exports.LIVE_ATTACH_HOOK_ENV] ?? '').trim().toLowerCase() === 'on';
399
+ }
400
+ /** True when the operator opted into the automatic read popup. */
401
+ function isAutoPopupEnabled(env = process.env) {
402
+ return (env[exports.AUTO_POPUP_ENV] ?? '').trim().toLowerCase() === 'on';
403
+ }
404
+ /**
405
+ * Quote a path for the `sh` command a tmux hook runs.
406
+ *
407
+ * Double quotes rather than single, because the whole shell-command is already
408
+ * inside tmux's own single quotes and tmux's lexer does not process escapes
409
+ * inside those — a `'\''` would end the tmux string, not the shell one.
410
+ *
411
+ * Returns undefined for a path carrying any character that would change the
412
+ * meaning of a double-quoted word (`"`, `$`, a backtick, a backslash) or that
413
+ * cannot appear on a command line at all (newline / carriage return). Callers
414
+ * treat that as "install no hook": a home directory nobody can quote safely is a
415
+ * reason to fall back to the CLI's own hand-over, not a reason to run a command
416
+ * whose parse is a guess.
417
+ *
418
+ * @param path - Absolute script path
419
+ * @returns The double-quoted word, or undefined when it cannot be represented
420
+ */
421
+ function quoteScriptPathForHook(path) {
422
+ if (/["$`\\\n\r]/.test(path))
423
+ return undefined;
424
+ return `"${path}"`;
425
+ }
426
+ /**
427
+ * The `run-shell` body of a session-scoped hook.
428
+ *
429
+ * `-b` because a hook that blocks the tmux server for the length of a shell
430
+ * script is a hook that makes tmux feel broken.
431
+ *
432
+ * The formats are passed as separate words and consumed as `$1`, `$2`, `$3` by
433
+ * the script, which is why none of them is quoted here — a tmux format that
434
+ * expanded to something with a space would be split, and all three of these
435
+ * (`session_name`, `client_control_mode`, `client_name`) are single words by
436
+ * construction.
437
+ *
438
+ * @param quotedScriptPath - Result of {@link quoteScriptPathForHook}
439
+ * @param formats - tmux formats to hand the script
440
+ * @param extraArgs - Literal words appended after the formats
441
+ * @returns The command string to hand to `set-hook`
442
+ */
443
+ function buildHookRunShellBody(quotedScriptPath, formats, extraArgs = []) {
444
+ const words = [quotedScriptPath, ...formats, ...extraArgs].join(' ');
445
+ return `run-shell -b '${words}'`;
446
+ }
447
+ /**
448
+ * Formats every attach hook hands to its script.
449
+ *
450
+ * `#{client_name}` is included for both because the auto-popup needs it
451
+ * (`display-popup -c <client>`) and the delegate script ignores extra arguments
452
+ * — one format list is one thing to keep right.
453
+ */
454
+ exports.ATTACH_HOOK_FORMATS = [
455
+ '#{session_name}',
456
+ '#{client_control_mode}',
457
+ '#{client_name}',
458
+ ];
459
+ /**
460
+ * `set-hook -t <session> client-attached[0] 'run-shell -b …'`, or undefined when
461
+ * the script path cannot be quoted safely.
462
+ *
463
+ * @param sessionName - Target session
464
+ * @param scriptPath - Absolute path of the materialized delegate script
465
+ */
466
+ function buildInstallDelegateHookArgs(sessionName, scriptPath) {
467
+ const quoted = quoteScriptPathForHook(scriptPath);
468
+ if (quoted === undefined)
469
+ return undefined;
470
+ return buildSetSessionHookArgs(sessionName, exports.DELEGATE_HOOK, buildHookRunShellBody(quoted, exports.ATTACH_HOOK_FORMATS));
471
+ }
472
+ /** `set-hook -u -t <session> client-attached[0]`. */
473
+ function buildRemoveDelegateHookArgs(sessionName) {
474
+ return buildUnsetSessionHookArgs(sessionName, exports.DELEGATE_HOOK);
475
+ }
476
+ /**
477
+ * `set-hook -t <session> client-attached[1] 'run-shell -b …'`, or undefined when
478
+ * the script path cannot be quoted safely.
479
+ */
480
+ function buildInstallAutoPopupHookArgs(sessionName, scriptPath) {
481
+ const quoted = quoteScriptPathForHook(scriptPath);
482
+ if (quoted === undefined)
483
+ return undefined;
484
+ return buildSetSessionHookArgs(sessionName, exports.AUTO_POPUP_HOOK, buildHookRunShellBody(quoted, exports.ATTACH_HOOK_FORMATS));
485
+ }
486
+ /** `set-hook -u -t <session> client-attached[1]`. */
487
+ function buildRemoveAutoPopupHookArgs(sessionName) {
488
+ return buildUnsetSessionHookArgs(sessionName, exports.AUTO_POPUP_HOOK);
489
+ }
490
+ /**
491
+ * The tmux commands that hand a session's geometry to the attaching terminal.
492
+ *
493
+ * Ordered: the flag is raised BEFORE `window-size latest`, so a status poll that
494
+ * lands between the two sees "delegated, still 200x1000" — which suppresses the
495
+ * scraped save one poll early — rather than "not delegated, 44 rows", which
496
+ * would save a truncated reply. The cheap failure is the safe one.
497
+ *
498
+ * @param sessionName - Target session
499
+ * @returns Argument vectors, to run in order
500
+ */
501
+ function buildDelegateGeometryCommands(sessionName) {
502
+ return [
503
+ buildSetSessionOptionArgs(sessionName, exports.CM_DELEGATED_OPTION, '1'),
504
+ buildWindowSizeArgs(sessionName, 'latest'),
505
+ ];
506
+ }
507
+ /**
508
+ * The tmux commands that take a session's geometry back.
509
+ *
510
+ * The mirror image of {@link buildDelegateGeometryCommands}, and ordered the
511
+ * other way for the same reason: the canvas is restored first and the flag is
512
+ * dropped last, so no poll can ever see "not delegated" while the pane is still
513
+ * the size of somebody's terminal.
514
+ *
515
+ * @param sessionName - Target session
516
+ * @param width - Canvas width (defaults to the pinned {@link TUI_PANE_WIDTH})
517
+ * @param height - Canvas height (defaults to the pinned {@link TUI_PANE_HEIGHT})
518
+ */
519
+ function buildRestoreGeometryCommands(sessionName, width = tmux_pane_config_1.TUI_PANE_WIDTH, height = tmux_pane_config_1.TUI_PANE_HEIGHT) {
520
+ return [
521
+ buildWindowSizeArgs(sessionName, 'manual'),
522
+ buildResizeWindowArgs(sessionName, width, height),
523
+ buildUnsetSessionOptionArgs(sessionName, exports.CM_DELEGATED_OPTION),
524
+ ];
525
+ }
@@ -98,6 +98,21 @@ const MEASURED_DATE_2026_07_26 = '2026-07-26';
98
98
  */
99
99
  const OPENCODE_EVIDENCE_SOURCE = 'https://github.com/Kewton/CommandMate/blob/main/docs/design/opencode-server-live-verification.md#11-issue-2036--2037-opencode-11822-2026-08-25';
100
100
  const MEASURED_DATE_2026_08_25 = '2026-08-25';
101
+ /**
102
+ * Evidence reference for the Command Code 1.49.0 measurement (Issue #2302).
103
+ *
104
+ * The reference doc carries the harness, both controls and the raw CLI output,
105
+ * which is the half of a row a reader can actually check.
106
+ */
107
+ const COMMAND_CODE_EVIDENCE_SOURCE = 'https://github.com/Kewton/CommandMate/blob/main/docs/reference/skill-agent-compatibility.md#8-command-code-probe-log-issue-2302';
108
+ const MEASURED_DATE_2026_09_05 = '2026-09-05';
109
+ /**
110
+ * Evidence reference for the Copilot 1.0.83 measurement (Issue #2302).
111
+ *
112
+ * The same probe log also carries a Gemini 0.58.0 discovery measurement that is
113
+ * deliberately *not* recorded as a row — see the `gemini` entry below.
114
+ */
115
+ const OTHER_AGENTS_EVIDENCE_SOURCE = 'https://github.com/Kewton/CommandMate/blob/main/docs/reference/skill-agent-compatibility.md#9-gemini--copilot-probe-log-issue-2302';
101
116
  function unmeasuredEntry(agent) {
102
117
  return {
103
118
  agent,
@@ -180,6 +195,16 @@ const AGENT_DISCOVERY_MATRIX = [
180
195
  reloadKey: exports.AGENT_RELOAD_MESSAGE_KEYS.SESSION_RESTART_NO_SLASH,
181
196
  skipReasonKey: null,
182
197
  },
198
+ // Issue #2302 *did* measure gemini 0.58.0 — `gemini skills list --all`
199
+ // returns `.agents/skills` with an absolute path, and `.claude/skills`
200
+ // planted at the same moment does not appear. It is still recorded as
201
+ // unmeasured here, on purpose: the invocation axis could not be measured at
202
+ // all (sign-in fails with "This client is no longer supported for Gemini Code
203
+ // Assist for individuals", so the TUI never reaches a composer), and landing
204
+ // the half-row is a change to `tests/integration/skills-agent-discovery-probe.test.ts`,
205
+ // which pins gemini as its example of an Agent with no measurement. The
206
+ // probe log is kept so the next pass starts from evidence rather than zero:
207
+ // `docs/reference/skill-agent-compatibility.md` §9.1.
183
208
  unmeasuredEntry('gemini'),
184
209
  unmeasuredEntry('vibe-local'),
185
210
  {
@@ -224,11 +249,102 @@ const AGENT_DISCOVERY_MATRIX = [
224
249
  reloadKey: exports.AGENT_RELOAD_MESSAGE_KEYS.SESSION_RESTART,
225
250
  skipReasonKey: null,
226
251
  },
227
- unmeasuredEntry('copilot'),
252
+ {
253
+ agent: 'copilot',
254
+ // Issue #2302, GitHub Copilot CLI 1.0.83. The only Agent so far measured to
255
+ // read *both* CommandMate install roots from one listing: `copilot skill
256
+ // list` returns `.github/skills` (positive control), `.agents/skills` and
257
+ // `.claude/skills`, and the byte-identical dual-root install appears once
258
+ // rather than twice.
259
+ //
260
+ // `copilot skill --help` claims those roots too. That claim is not the
261
+ // evidence — the probe Skills are, one per root with its own token.
262
+ discoveryRoots: [constants_1.SKILL_INSTALL_ROOT_PREFIX, constants_1.SKILL_CLAUDE_INSTALL_ROOT_PREFIX],
263
+ discovery: {
264
+ outcome: 'verified',
265
+ evidenceKind: 'mechanical',
266
+ labelKey: exports.AGENT_AXIS_OUTCOME_LABEL_KEYS.verified,
267
+ evidenceKindKey: exports.AGENT_EVIDENCE_KIND_LABEL_KEYS.mechanical,
268
+ limitationKey: null,
269
+ },
270
+ invocation: {
271
+ // Typing `/probe` in Copilot's own composer offers all four planted
272
+ // Skills, `.claude/skills` included. Controls: `/zzzznotacommand` matched
273
+ // nothing and `/hel` matched the built-in commands, so the palette was
274
+ // filtering rather than listing everything.
275
+ //
276
+ // Measured at the palette, which is what this axis is — the same standard
277
+ // the Claude row was measured to. The model was not signed in during the
278
+ // probe, so a Skill actually running end to end is *not* claimed here.
279
+ outcome: 'verified',
280
+ evidenceKind: 'mechanical',
281
+ labelKey: exports.AGENT_AXIS_OUTCOME_LABEL_KEYS.verified,
282
+ evidenceKindKey: exports.AGENT_EVIDENCE_KIND_LABEL_KEYS.mechanical,
283
+ limitationKey: null,
284
+ },
285
+ testedVersion: '1.0.83',
286
+ testedDate: MEASURED_DATE_2026_09_05,
287
+ evidenceSource: OTHER_AGENTS_EVIDENCE_SOURCE,
288
+ // Whether a Skill added mid-session is picked up was not measured.
289
+ reloadKey: exports.AGENT_RELOAD_MESSAGE_KEYS.UNKNOWN,
290
+ skipReasonKey: null,
291
+ },
228
292
  // CommandMate's own slash palette serves `.agents/skills` entries to
229
293
  // antigravity sessions (#1504). That is CommandMate injecting a command, not
230
294
  // the Agent discovering a Skill, so it is not evidence for this table.
231
295
  unmeasuredEntry('antigravity'),
296
+ {
297
+ agent: 'command-code',
298
+ // Issue #2250 left this row unmeasured; Issue #2302 measured it on 1.49.0.
299
+ //
300
+ // Of CommandMate's two install roots, Command Code reads `.agents/skills`
301
+ // and does not read `.claude/skills`. `cmd skills list -d` names the roots
302
+ // it looks in — project `.commandcode/skills` and `.agents/skills`, the same
303
+ // pair under `$HOME` — and `.claude/skills` is not among them. A probe Skill
304
+ // was planted in each root at the same moment, so the split is the Agent's
305
+ // and not the install's: `.commandcode/skills` is the positive control and
306
+ // came back listed, `.claude/skills` is the negative control and did not.
307
+ //
308
+ // The dual-root install (#1460) is therefore half-read and still correct:
309
+ // one byte-identical payload in both roots is listed exactly once, from
310
+ // `.agents/skills`. Naming the unread root here would render as "installed
311
+ // and invisible" for anyone reading the table to decide where to look.
312
+ discoveryRoots: [constants_1.SKILL_INSTALL_ROOT_PREFIX],
313
+ discovery: {
314
+ outcome: 'verified',
315
+ evidenceKind: 'mechanical',
316
+ labelKey: exports.AGENT_AXIS_OUTCOME_LABEL_KEYS.verified,
317
+ evidenceKindKey: exports.AGENT_EVIDENCE_KIND_LABEL_KEYS.mechanical,
318
+ limitationKey: null,
319
+ },
320
+ invocation: {
321
+ // The axis codex and opencode both fail, and Command Code passes: typing
322
+ // `/probe` in its own composer offers the installed Skills as `[skill]`
323
+ // rows, and `/skills` lists them under "Project skills" with an
324
+ // `[.agents]` badge. So no limitation is attached here — CommandMate's
325
+ // palette is a convenience for this Agent, not the only route in.
326
+ //
327
+ // Headless is where it was machine-checked: `cmd -p "/<name>"` emits
328
+ // `{"type":"skill_loaded","name":"<name>"}` before the run starts and the
329
+ // model then answers the Skill's token. `--no-skills` is the control that
330
+ // makes that event mean discovery rather than prompt text — same prompt,
331
+ // no event.
332
+ outcome: 'verified',
333
+ evidenceKind: 'mechanical',
334
+ labelKey: exports.AGENT_AXIS_OUTCOME_LABEL_KEYS.verified,
335
+ evidenceKindKey: exports.AGENT_EVIDENCE_KIND_LABEL_KEYS.mechanical,
336
+ limitationKey: null,
337
+ },
338
+ testedVersion: '1.49.0',
339
+ testedDate: MEASURED_DATE_2026_09_05,
340
+ evidenceSource: COMMAND_CODE_EVIDENCE_SOURCE,
341
+ // Also measured: a Skill planted into a *running* session shows up in the
342
+ // `/skills` picker, which rescans when opened, but not in the composer's
343
+ // slash completion, which is built once at session start. A restart is what
344
+ // makes both agree, so that is the instruction.
345
+ reloadKey: exports.AGENT_RELOAD_MESSAGE_KEYS.SESSION_RESTART,
346
+ skipReasonKey: null,
347
+ },
232
348
  ];
233
349
  /** The measured matrix, in CLI-tool declaration order. */
234
350
  function getSkillAgentMatrix() {