commandmate 0.27.1 → 0.28.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 (918) hide show
  1. package/.env.example +28 -0
  2. package/.next/BUILD_ID +1 -1
  3. package/.next/app-build-manifest.json +278 -248
  4. package/.next/app-path-routes-manifest.json +30 -26
  5. package/.next/build-manifest.json +2 -2
  6. package/.next/prerender-manifest.json +15 -15
  7. package/.next/required-server-files.json +1 -1
  8. package/.next/routes-manifest.json +32 -0
  9. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/update/route.js +1 -1
  11. package/.next/server/app/api/app/update/route.js.nft.json +1 -1
  12. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/app/update-check/route.js +1 -1
  14. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/assistant/conversation/route.js +1 -1
  16. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  17. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/assistant/current-output/route.js +1 -1
  19. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  20. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/assistant/messages/route.js +1 -1
  22. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  23. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/assistant/session/route.js +1 -1
  25. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  26. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/assistant/start/route.js +32 -1
  28. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  29. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/assistant/terminal/route.js +34 -3
  31. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  32. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/assistant/tools/route.js +1 -1
  34. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  35. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/capabilities/route.js +1 -1
  40. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/daily-summary/route.js +1 -1
  42. package/.next/server/app/api/daily-summary/route.js.nft.json +1 -1
  43. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/daily-summary/status/route.js +1 -1
  45. package/.next/server/app/api/daily-summary/status/route.js.nft.json +1 -1
  46. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/external-apps/[id]/health/route.js +1 -1
  48. package/.next/server/app/api/external-apps/[id]/health/route.js.nft.json +1 -1
  49. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/external-apps/[id]/route.js +1 -1
  51. package/.next/server/app/api/external-apps/[id]/route.js.nft.json +1 -1
  52. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/external-apps/route.js +1 -1
  54. package/.next/server/app/api/external-apps/route.js.nft.json +1 -1
  55. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/fs/browse/route.js +1 -1
  57. package/.next/server/app/api/fs/browse/route.js.nft.json +1 -1
  58. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/fs/recent-paths/route.js +1 -1
  60. package/.next/server/app/api/fs/recent-paths/route.js.nft.json +1 -1
  61. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  63. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  64. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/hooks/claude-done/route.js +2 -2
  66. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  67. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  69. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  70. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/metrics/vibe/route.js +1 -1
  72. package/.next/server/app/api/metrics/vibe/route.js.nft.json +1 -1
  73. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/push/escalation/route.js +1 -1
  76. package/.next/server/app/api/push/escalation/route.js.nft.json +1 -1
  77. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/push/subscriptions/route.js +7 -1
  79. package/.next/server/app/api/push/subscriptions/route.js.nft.json +1 -1
  80. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/push/vapid/route.js +1 -1
  82. package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
  83. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/repositories/[id]/route.js +1 -1
  85. package/.next/server/app/api/repositories/[id]/route.js.nft.json +1 -1
  86. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js +1 -1
  88. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js.nft.json +1 -1
  89. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
  91. package/.next/server/app/api/repositories/[id]/todos/route.js.nft.json +1 -1
  92. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  94. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  95. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/repositories/clone/route.js +1 -1
  97. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  98. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/repositories/excluded/route.js +1 -1
  100. package/.next/server/app/api/repositories/excluded/route.js.nft.json +1 -1
  101. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/repositories/restore/route.js +1 -1
  103. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  104. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/repositories/route.js +1 -1
  106. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  107. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/repositories/scan/route.js +1 -1
  109. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  110. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/repositories/sync/route.js +1 -1
  112. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  113. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/repositories/validate-path/route.js +1 -1
  115. package/.next/server/app/api/repositories/validate-path/route.js.nft.json +1 -1
  116. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/sidebar/group-order/route.js +1 -1
  118. package/.next/server/app/api/sidebar/group-order/route.js.nft.json +1 -1
  119. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/skills/[id]/route.js.nft.json +1 -1
  121. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/skills/installations/route.js +1 -1
  123. package/.next/server/app/api/skills/installations/route.js.nft.json +1 -1
  124. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/skills/operations/route.js +1 -1
  126. package/.next/server/app/api/skills/operations/route.js.nft.json +1 -1
  127. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/skills/reindex/route.js +1 -1
  129. package/.next/server/app/api/skills/reindex/route.js.nft.json +1 -1
  130. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  132. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/slash-commands/route.js.nft.json +1 -1
  134. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/tasks/[taskId]/cancel/route.js +1 -1
  136. package/.next/server/app/api/tasks/[taskId]/cancel/route.js.nft.json +1 -1
  137. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/tasks/[taskId]/route.js +1 -1
  139. package/.next/server/app/api/tasks/[taskId]/route.js.nft.json +1 -1
  140. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/templates/[id]/route.js +2 -2
  142. package/.next/server/app/api/templates/[id]/route.js.nft.json +1 -1
  143. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/templates/route.js +2 -2
  145. package/.next/server/app/api/templates/route.js.nft.json +1 -1
  146. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/todos/route.js +1 -1
  148. package/.next/server/app/api/todos/route.js.nft.json +1 -1
  149. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/verification/runs/[runId]/route.js +1 -1
  151. package/.next/server/app/api/verification/runs/[runId]/route.js.nft.json +1 -1
  152. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  153. package/.next/server/app/api/verification/runs/route.js +1 -1
  154. package/.next/server/app/api/verification/runs/route.js.nft.json +1 -1
  155. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  158. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  161. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  164. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +1 -1
  167. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +2 -2
  169. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
  170. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/current-output/route.js +2 -2
  172. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  173. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/env/route.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/env/route.js.nft.json +1 -1
  176. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js.nft.json +1 -1
  179. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +2 -2
  181. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js.nft.json +1 -1
  182. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +1 -1
  185. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js.nft.json +1 -1
  188. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js.nft.json +1 -1
  191. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/git/branches/route.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/git/branches/route.js.nft.json +1 -1
  194. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js.nft.json +1 -1
  197. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/git/commit/route.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/git/commit/route.js.nft.json +1 -1
  200. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/git/diff/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/git/diff/route.js.nft.json +1 -1
  203. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/git/fetch/route.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/git/fetch/route.js.nft.json +1 -1
  206. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/api/worktrees/[id]/git/log/route.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/git/log/route.js.nft.json +1 -1
  209. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/api/worktrees/[id]/git/pull/route.js +1 -1
  211. package/.next/server/app/api/worktrees/[id]/git/pull/route.js.nft.json +1 -1
  212. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/git/push/route.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/git/push/route.js.nft.json +1 -1
  215. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/git/reset/route.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/git/reset/route.js.nft.json +1 -1
  218. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  219. package/.next/server/app/api/worktrees/[id]/git/revert/route.js +1 -1
  220. package/.next/server/app/api/worktrees/[id]/git/revert/route.js.nft.json +1 -1
  221. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  222. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js +1 -1
  223. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js.nft.json +1 -1
  224. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  225. package/.next/server/app/api/worktrees/[id]/git/stage/route.js +1 -1
  226. package/.next/server/app/api/worktrees/[id]/git/stage/route.js.nft.json +1 -1
  227. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/api/worktrees/[id]/git/staged/route.js +1 -1
  229. package/.next/server/app/api/worktrees/[id]/git/staged/route.js.nft.json +1 -1
  230. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  231. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js +1 -1
  232. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js.nft.json +1 -1
  233. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  234. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js +1 -1
  235. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js.nft.json +1 -1
  236. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  237. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js +1 -1
  238. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js.nft.json +1 -1
  239. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  240. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js +1 -1
  241. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js.nft.json +1 -1
  242. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  243. package/.next/server/app/api/worktrees/[id]/git/stash/route.js +1 -1
  244. package/.next/server/app/api/worktrees/[id]/git/stash/route.js.nft.json +1 -1
  245. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  246. package/.next/server/app/api/worktrees/[id]/git/status/route.js +1 -1
  247. package/.next/server/app/api/worktrees/[id]/git/status/route.js.nft.json +1 -1
  248. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  249. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js +1 -1
  250. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js.nft.json +1 -1
  251. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  252. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js +1 -1
  253. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js.nft.json +1 -1
  254. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  255. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -0
  256. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -0
  257. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -0
  258. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  259. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  260. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  261. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  262. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  263. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  264. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
  265. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -1
  266. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  267. package/.next/server/app/api/worktrees/[id]/logs/route.js +2 -2
  268. package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -1
  269. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  270. package/.next/server/app/api/worktrees/[id]/marp-render/route.js +4 -4
  271. package/.next/server/app/api/worktrees/[id]/marp-render/route.js.nft.json +1 -1
  272. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  273. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
  274. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +1 -1
  275. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  276. package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
  277. package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +1 -1
  278. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  279. package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -1
  280. package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +1 -1
  281. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  282. package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js +1 -0
  283. package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js.nft.json +1 -0
  284. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -0
  285. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -0
  286. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -0
  287. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -0
  288. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -0
  289. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -0
  290. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -0
  291. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  292. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  293. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  294. package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -1
  295. package/.next/server/app/api/worktrees/[id]/resolve-target/route.js.nft.json +1 -1
  296. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  297. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  298. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  299. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  300. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  301. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  302. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  303. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +5 -1
  304. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +1 -1
  305. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  306. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
  307. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
  308. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  309. package/.next/server/app/api/worktrees/[id]/schedules/route.js +6 -2
  310. package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +1 -1
  311. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  312. package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
  313. package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -1
  314. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  315. package/.next/server/app/api/worktrees/[id]/send/route.js +7 -3
  316. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  317. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  318. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +1 -1
  319. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  320. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  321. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js +1 -1
  322. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js.nft.json +1 -1
  323. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  324. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js +1 -1
  325. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +1 -1
  326. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  327. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js +1 -1
  328. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js.nft.json +1 -1
  329. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  330. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js +1 -1
  331. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js.nft.json +1 -1
  332. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  333. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js +1 -1
  334. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js.nft.json +1 -1
  335. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  336. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js +1 -1
  337. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js.nft.json +1 -1
  338. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  339. package/.next/server/app/api/worktrees/[id]/skills/route.js +1 -1
  340. package/.next/server/app/api/worktrees/[id]/skills/route.js.nft.json +1 -1
  341. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  342. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  343. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -1
  344. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  345. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  346. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  347. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  348. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -1
  349. package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
  350. package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
  351. package/.next/server/app/api/worktrees/[id]/tasks/route.js +1 -1
  352. package/.next/server/app/api/worktrees/[id]/tasks/route.js.nft.json +1 -1
  353. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  354. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  355. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  356. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  357. package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
  358. package/.next/server/app/api/worktrees/[id]/timers/history/route.js.nft.json +1 -1
  359. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  360. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -3
  361. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  362. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  363. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
  364. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js.nft.json +1 -1
  365. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  366. package/.next/server/app/api/worktrees/[id]/todos/route.js +1 -1
  367. package/.next/server/app/api/worktrees/[id]/todos/route.js.nft.json +1 -1
  368. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  369. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js +1 -1
  370. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -1
  371. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  372. package/.next/server/app/api/worktrees/[id]/tree/route.js +1 -1
  373. package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +1 -1
  374. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  375. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js +1 -1
  376. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -1
  377. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  378. package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
  379. package/.next/server/app/api/worktrees/[id]/verify/route.js.nft.json +1 -1
  380. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  381. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.js +1 -1
  382. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.js.nft.json +1 -1
  383. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  384. package/.next/server/app/api/worktrees/[id]/verify/runs/route.js +1 -1
  385. package/.next/server/app/api/worktrees/[id]/verify/runs/route.js.nft.json +1 -1
  386. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  387. package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -1
  388. package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -1
  389. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  390. package/.next/server/app/api/worktrees/route.js +1 -1
  391. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  392. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  393. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  394. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  395. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  396. package/.next/server/app/more/page.js +1 -1
  397. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  398. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  399. package/.next/server/app/page_client-reference-manifest.js +1 -1
  400. package/.next/server/app/proxy/[...path]/route.js +1 -1
  401. package/.next/server/app/proxy/[...path]/route.js.nft.json +1 -1
  402. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  403. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  404. package/.next/server/app/review/page.js +1 -1
  405. package/.next/server/app/review/page.js.nft.json +1 -1
  406. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  407. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  408. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  409. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  410. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  411. package/.next/server/app/worktrees/[id]/files/[...path]/page.js +1 -1
  412. package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
  413. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  414. package/.next/server/app/worktrees/[id]/page.js +15 -10
  415. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  416. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  417. package/.next/server/app/worktrees/[id]/terminal/page.js +2 -2
  418. package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -1
  419. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  420. package/.next/server/app-paths-manifest.json +30 -26
  421. package/.next/server/chunks/1058.js +1 -0
  422. package/.next/server/chunks/1068.js +1 -3
  423. package/.next/server/chunks/1191.js +13 -0
  424. package/.next/server/chunks/1296.js +1 -1
  425. package/.next/server/chunks/1601.js +2 -2
  426. package/.next/server/chunks/1714.js +7 -0
  427. package/.next/server/chunks/1886.js +5 -0
  428. package/.next/server/chunks/1944.js +1 -0
  429. package/.next/server/chunks/2119.js +1 -1
  430. package/.next/server/chunks/221.js +19 -0
  431. package/.next/server/chunks/222.js +1 -0
  432. package/.next/server/chunks/2328.js +1 -1
  433. package/.next/server/chunks/2366.js +1 -0
  434. package/.next/server/chunks/2404.js +1 -1
  435. package/.next/server/chunks/243.js +1 -0
  436. package/.next/server/chunks/2445.js +1 -1
  437. package/.next/server/chunks/2759.js +1 -1
  438. package/.next/server/chunks/3346.js +1 -1
  439. package/.next/server/chunks/3480.js +17 -1
  440. package/.next/server/chunks/3558.js +1 -0
  441. package/.next/server/chunks/4299.js +1 -0
  442. package/.next/server/chunks/4393.js +1 -1
  443. package/.next/server/chunks/5017.js +1 -1
  444. package/.next/server/chunks/5089.js +1 -1
  445. package/.next/server/chunks/5354.js +1 -1
  446. package/.next/server/chunks/5571.js +1 -1
  447. package/.next/server/chunks/6130.js +1 -1
  448. package/.next/server/chunks/6274.js +11 -10
  449. package/.next/server/chunks/6285.js +1 -1
  450. package/.next/server/chunks/6337.js +1 -0
  451. package/.next/server/chunks/6401.js +1 -1
  452. package/.next/server/chunks/663.js +78 -0
  453. package/.next/server/chunks/7472.js +1 -1
  454. package/.next/server/chunks/7824.js +1 -0
  455. package/.next/server/chunks/7905.js +1 -0
  456. package/.next/server/chunks/880.js +1 -1
  457. package/.next/server/chunks/8807.js +84 -18
  458. package/.next/server/chunks/9130.js +5 -0
  459. package/.next/server/chunks/9328.js +1 -1
  460. package/.next/server/chunks/9358.js +1 -1
  461. package/.next/server/chunks/9508.js +1 -1
  462. package/.next/server/chunks/9584.js +1 -0
  463. package/.next/server/chunks/9627.js +274 -0
  464. package/.next/server/chunks/9798.js +2 -0
  465. package/.next/server/chunks/9938.js +1 -1
  466. package/.next/server/middleware-manifest.json +5 -5
  467. package/.next/server/pages/500.html +1 -1
  468. package/.next/server/server-reference-manifest.json +1 -1
  469. package/.next/static/chunks/1188-8567ee5ecfef02ee.js +1 -0
  470. package/.next/static/chunks/3361-aa1b6e7c1d7eeeb4.js +1 -0
  471. package/.next/static/chunks/3968-8d8ca15657748bfb.js +1 -0
  472. package/.next/static/chunks/6381-d921ab728eda1191.js +1 -0
  473. package/.next/static/chunks/app/api/app/update/route-9247d6b9d647f750.js +1 -0
  474. package/.next/static/chunks/app/api/app/update-check/route-9247d6b9d647f750.js +1 -0
  475. package/.next/static/chunks/app/api/assistant/conversation/route-9247d6b9d647f750.js +1 -0
  476. package/.next/static/chunks/app/api/assistant/current-output/route-9247d6b9d647f750.js +1 -0
  477. package/.next/static/chunks/app/api/assistant/messages/route-9247d6b9d647f750.js +1 -0
  478. package/.next/static/chunks/app/api/assistant/session/route-9247d6b9d647f750.js +1 -0
  479. package/.next/static/chunks/app/api/assistant/start/route-9247d6b9d647f750.js +1 -0
  480. package/.next/static/chunks/app/api/assistant/terminal/route-9247d6b9d647f750.js +1 -0
  481. package/.next/static/chunks/app/api/assistant/tools/route-9247d6b9d647f750.js +1 -0
  482. package/.next/static/chunks/app/api/auth/login/route-9247d6b9d647f750.js +1 -0
  483. package/.next/static/chunks/app/api/auth/logout/route-9247d6b9d647f750.js +1 -0
  484. package/.next/static/chunks/app/api/auth/status/route-9247d6b9d647f750.js +1 -0
  485. package/.next/static/chunks/app/api/capabilities/route-9247d6b9d647f750.js +1 -0
  486. package/.next/static/chunks/app/api/daily-summary/route-9247d6b9d647f750.js +1 -0
  487. package/.next/static/chunks/app/api/daily-summary/status/route-9247d6b9d647f750.js +1 -0
  488. package/.next/static/chunks/app/api/external-apps/[id]/health/route-9247d6b9d647f750.js +1 -0
  489. package/.next/static/chunks/app/api/external-apps/[id]/route-9247d6b9d647f750.js +1 -0
  490. package/.next/static/chunks/app/api/external-apps/route-9247d6b9d647f750.js +1 -0
  491. package/.next/static/chunks/app/api/fs/browse/route-9247d6b9d647f750.js +1 -0
  492. package/.next/static/chunks/app/api/fs/recent-paths/route-9247d6b9d647f750.js +1 -0
  493. package/.next/static/chunks/app/api/hooks/agent-event/route-9247d6b9d647f750.js +1 -0
  494. package/.next/static/chunks/app/api/hooks/claude-done/route-9247d6b9d647f750.js +1 -0
  495. package/.next/static/chunks/app/api/hooks/permission-request/route-9247d6b9d647f750.js +1 -0
  496. package/.next/static/chunks/app/api/metrics/vibe/route-9247d6b9d647f750.js +1 -0
  497. package/.next/static/chunks/app/api/ollama/models/route-9247d6b9d647f750.js +1 -0
  498. package/.next/static/chunks/app/api/push/escalation/route-9247d6b9d647f750.js +1 -0
  499. package/.next/static/chunks/app/api/push/subscriptions/route-9247d6b9d647f750.js +1 -0
  500. package/.next/static/chunks/app/api/push/vapid/route-9247d6b9d647f750.js +1 -0
  501. package/.next/static/chunks/app/api/repositories/[id]/route-9247d6b9d647f750.js +1 -0
  502. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-9247d6b9d647f750.js +1 -0
  503. package/.next/static/chunks/app/api/repositories/[id]/todos/route-9247d6b9d647f750.js +1 -0
  504. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-9247d6b9d647f750.js +1 -0
  505. package/.next/static/chunks/app/api/repositories/clone/route-9247d6b9d647f750.js +1 -0
  506. package/.next/static/chunks/app/api/repositories/excluded/route-9247d6b9d647f750.js +1 -0
  507. package/.next/static/chunks/app/api/repositories/restore/route-9247d6b9d647f750.js +1 -0
  508. package/.next/static/chunks/app/api/repositories/route-9247d6b9d647f750.js +1 -0
  509. package/.next/static/chunks/app/api/repositories/scan/route-9247d6b9d647f750.js +1 -0
  510. package/.next/static/chunks/app/api/repositories/sync/route-9247d6b9d647f750.js +1 -0
  511. package/.next/static/chunks/app/api/repositories/validate-path/route-9247d6b9d647f750.js +1 -0
  512. package/.next/static/chunks/app/api/sidebar/group-order/route-9247d6b9d647f750.js +1 -0
  513. package/.next/static/chunks/app/api/skills/[id]/route-9247d6b9d647f750.js +1 -0
  514. package/.next/static/chunks/app/api/skills/installations/route-9247d6b9d647f750.js +1 -0
  515. package/.next/static/chunks/app/api/skills/operations/route-9247d6b9d647f750.js +1 -0
  516. package/.next/static/chunks/app/api/skills/reindex/route-9247d6b9d647f750.js +1 -0
  517. package/.next/static/chunks/app/api/skills/route-9247d6b9d647f750.js +1 -0
  518. package/.next/static/chunks/app/api/slash-commands/route-9247d6b9d647f750.js +1 -0
  519. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-9247d6b9d647f750.js +1 -0
  520. package/.next/static/chunks/app/api/tasks/[taskId]/route-9247d6b9d647f750.js +1 -0
  521. package/.next/static/chunks/app/api/templates/[id]/route-9247d6b9d647f750.js +1 -0
  522. package/.next/static/chunks/app/api/templates/route-9247d6b9d647f750.js +1 -0
  523. package/.next/static/chunks/app/api/todos/route-9247d6b9d647f750.js +1 -0
  524. package/.next/static/chunks/app/api/verification/runs/[runId]/route-9247d6b9d647f750.js +1 -0
  525. package/.next/static/chunks/app/api/verification/runs/route-9247d6b9d647f750.js +1 -0
  526. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-9247d6b9d647f750.js +1 -0
  527. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-9247d6b9d647f750.js +1 -0
  528. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-9247d6b9d647f750.js +1 -0
  529. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-9247d6b9d647f750.js +1 -0
  530. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-9247d6b9d647f750.js +1 -0
  531. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-9247d6b9d647f750.js +1 -0
  532. package/.next/static/chunks/app/api/worktrees/[id]/env/route-9247d6b9d647f750.js +1 -0
  533. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-9247d6b9d647f750.js +1 -0
  534. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-9247d6b9d647f750.js +1 -0
  535. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-9247d6b9d647f750.js +1 -0
  536. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-9247d6b9d647f750.js +1 -0
  537. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-9247d6b9d647f750.js +1 -0
  538. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-9247d6b9d647f750.js +1 -0
  539. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-9247d6b9d647f750.js +1 -0
  540. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-9247d6b9d647f750.js +1 -0
  541. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-9247d6b9d647f750.js +1 -0
  542. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-9247d6b9d647f750.js +1 -0
  543. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-9247d6b9d647f750.js +1 -0
  544. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-9247d6b9d647f750.js +1 -0
  545. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-9247d6b9d647f750.js +1 -0
  546. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-9247d6b9d647f750.js +1 -0
  547. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-9247d6b9d647f750.js +1 -0
  548. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-9247d6b9d647f750.js +1 -0
  549. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-9247d6b9d647f750.js +1 -0
  550. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-9247d6b9d647f750.js +1 -0
  551. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-9247d6b9d647f750.js +1 -0
  552. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-9247d6b9d647f750.js +1 -0
  553. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-9247d6b9d647f750.js +1 -0
  554. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-9247d6b9d647f750.js +1 -0
  555. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-9247d6b9d647f750.js +1 -0
  556. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-9247d6b9d647f750.js +1 -0
  557. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-9247d6b9d647f750.js +1 -0
  558. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-9247d6b9d647f750.js +1 -0
  559. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-9247d6b9d647f750.js +1 -0
  560. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-9247d6b9d647f750.js +1 -0
  561. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-9247d6b9d647f750.js +1 -0
  562. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-9247d6b9d647f750.js +1 -0
  563. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-9247d6b9d647f750.js +1 -0
  564. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-9247d6b9d647f750.js +1 -0
  565. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-9247d6b9d647f750.js +1 -0
  566. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-9247d6b9d647f750.js +1 -0
  567. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-9247d6b9d647f750.js +1 -0
  568. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-9247d6b9d647f750.js +1 -0
  569. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-9247d6b9d647f750.js +1 -0
  570. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-9247d6b9d647f750.js +1 -0
  571. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-9247d6b9d647f750.js +1 -0
  572. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-9247d6b9d647f750.js +1 -0
  573. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-9247d6b9d647f750.js +1 -0
  574. package/.next/static/chunks/app/api/worktrees/[id]/route-9247d6b9d647f750.js +1 -0
  575. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-9247d6b9d647f750.js +1 -0
  576. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-9247d6b9d647f750.js +1 -0
  577. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-9247d6b9d647f750.js +1 -0
  578. package/.next/static/chunks/app/api/worktrees/[id]/search/route-9247d6b9d647f750.js +1 -0
  579. package/.next/static/chunks/app/api/worktrees/[id]/send/route-9247d6b9d647f750.js +1 -0
  580. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-9247d6b9d647f750.js +1 -0
  581. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-9247d6b9d647f750.js +1 -0
  582. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-9247d6b9d647f750.js +1 -0
  583. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-9247d6b9d647f750.js +1 -0
  584. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-9247d6b9d647f750.js +1 -0
  585. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-9247d6b9d647f750.js +1 -0
  586. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-9247d6b9d647f750.js +1 -0
  587. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-9247d6b9d647f750.js +1 -0
  588. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-9247d6b9d647f750.js +1 -0
  589. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-9247d6b9d647f750.js +1 -0
  590. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-9247d6b9d647f750.js +1 -0
  591. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-9247d6b9d647f750.js +1 -0
  592. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-9247d6b9d647f750.js +1 -0
  593. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-9247d6b9d647f750.js +1 -0
  594. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-9247d6b9d647f750.js +1 -0
  595. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-9247d6b9d647f750.js +1 -0
  596. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-9247d6b9d647f750.js +1 -0
  597. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-9247d6b9d647f750.js +1 -0
  598. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-9247d6b9d647f750.js +1 -0
  599. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-9247d6b9d647f750.js +1 -0
  600. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-9247d6b9d647f750.js +1 -0
  601. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-9247d6b9d647f750.js +1 -0
  602. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-9247d6b9d647f750.js +1 -0
  603. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-9247d6b9d647f750.js +1 -0
  604. package/.next/static/chunks/app/api/worktrees/route-9247d6b9d647f750.js +1 -0
  605. package/.next/static/chunks/app/manifest.webmanifest/route-9247d6b9d647f750.js +1 -0
  606. package/.next/static/chunks/app/more/page-03867ab635d197c7.js +1 -0
  607. package/.next/static/chunks/app/proxy/[...path]/route-9247d6b9d647f750.js +1 -0
  608. package/.next/static/chunks/app/review/page-9a6d18ddcccbb63c.js +1 -0
  609. package/.next/static/chunks/app/worktrees/[id]/layout-9247d6b9d647f750.js +1 -0
  610. package/.next/static/chunks/app/worktrees/[id]/page-27b7cb2e77099eec.js +1 -0
  611. package/.next/static/chunks/app/worktrees/[id]/terminal/page-00ad5d9a62a71cab.js +1 -0
  612. package/.next/static/css/98722bc4152cedcc.css +1 -0
  613. package/.next/trace +13 -13
  614. package/.next/types/app/api/worktrees/[id]/instances/opencode/route.ts +347 -0
  615. package/.next/types/app/api/worktrees/[id]/opencode/diff/route.ts +347 -0
  616. package/.next/types/app/api/worktrees/[id]/opencode/session/route.ts +347 -0
  617. package/.next/types/app/api/worktrees/[id]/opencode/share/route.ts +347 -0
  618. package/.next/types/routes.d.ts +5 -1
  619. package/.next/types/validator.ts +36 -0
  620. package/README.md +9 -1
  621. package/dist/cli/commands/init.d.ts.map +1 -1
  622. package/dist/cli/commands/init.js +66 -0
  623. package/dist/cli/commands/instances.d.ts.map +1 -1
  624. package/dist/cli/commands/instances.js +46 -1
  625. package/dist/cli/commands/interrupt.d.ts +25 -0
  626. package/dist/cli/commands/interrupt.d.ts.map +1 -0
  627. package/dist/cli/commands/interrupt.js +146 -0
  628. package/dist/cli/commands/report.d.ts.map +1 -1
  629. package/dist/cli/commands/report.js +11 -4
  630. package/dist/cli/commands/respond.d.ts.map +1 -1
  631. package/dist/cli/commands/respond.js +146 -1
  632. package/dist/cli/commands/status.d.ts.map +1 -1
  633. package/dist/cli/commands/status.js +104 -0
  634. package/dist/cli/commands/wait.d.ts.map +1 -1
  635. package/dist/cli/commands/wait.js +39 -1
  636. package/dist/cli/config/agent-target-options.d.ts +12 -0
  637. package/dist/cli/config/agent-target-options.d.ts.map +1 -1
  638. package/dist/cli/config/agent-target-options.js +15 -1
  639. package/dist/cli/docs/agent-operations.d.ts +1 -1
  640. package/dist/cli/docs/agent-operations.d.ts.map +1 -1
  641. package/dist/cli/docs/agent-operations.js +34 -0
  642. package/dist/cli/program.d.ts.map +1 -1
  643. package/dist/cli/program.js +6 -0
  644. package/dist/cli/types/api-responses.d.ts +375 -0
  645. package/dist/cli/types/api-responses.d.ts.map +1 -1
  646. package/dist/cli/types/index.d.ts +63 -0
  647. package/dist/cli/types/index.d.ts.map +1 -1
  648. package/dist/cli/types/index.js +31 -1
  649. package/dist/cli/utils/daemon.d.ts.map +1 -1
  650. package/dist/cli/utils/daemon.js +3 -0
  651. package/dist/cli/utils/env-setup.d.ts +24 -0
  652. package/dist/cli/utils/env-setup.d.ts.map +1 -1
  653. package/dist/cli/utils/env-setup.js +70 -0
  654. package/dist/cli/utils/vapid-keygen.d.ts +74 -0
  655. package/dist/cli/utils/vapid-keygen.d.ts.map +1 -0
  656. package/dist/cli/utils/vapid-keygen.js +111 -0
  657. package/dist/lib/cli-tools/types.d.ts +11 -1
  658. package/dist/lib/cli-tools/types.d.ts.map +1 -1
  659. package/dist/lib/detection/tools/verified-against.d.ts +14 -3
  660. package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
  661. package/dist/lib/detection/tools/verified-against.js +14 -3
  662. package/dist/lib/push/vapid.d.ts +178 -0
  663. package/dist/lib/push/vapid.d.ts.map +1 -0
  664. package/dist/lib/push/vapid.js +293 -0
  665. package/dist/lib/server/localhost-self-check.d.ts +203 -0
  666. package/dist/lib/server/localhost-self-check.d.ts.map +1 -0
  667. package/dist/lib/server/localhost-self-check.js +333 -0
  668. package/dist/server/locales/en/notifications.json +23 -1
  669. package/dist/server/locales/ja/notifications.json +23 -1
  670. package/dist/server/server.js +103 -0
  671. package/dist/server/src/config/image-extensions.js +244 -0
  672. package/dist/server/src/config/opencode-constants.js +69 -0
  673. package/dist/server/src/config/tmux-pane-config.js +100 -1
  674. package/dist/server/src/lib/cli-tools/base.js +33 -48
  675. package/dist/server/src/lib/cli-tools/opencode-config.js +12 -0
  676. package/dist/server/src/lib/cli-tools/opencode.js +435 -7
  677. package/dist/server/src/lib/cli-tools/start-availability.js +160 -0
  678. package/dist/server/src/lib/cmate-cli-tool-parser.js +328 -7
  679. package/dist/server/src/lib/cmate-parser.js +12 -0
  680. package/dist/server/src/lib/db/agent-instances-db.js +129 -0
  681. package/dist/server/src/lib/db/agent-session-cost-db.js +204 -0
  682. package/dist/server/src/lib/db/agent-session-cost-sampler.js +194 -0
  683. package/dist/server/src/lib/db/chat-db.js +33 -0
  684. package/dist/server/src/lib/db/db-instance.js +11 -0
  685. package/dist/server/src/lib/db/db.js +8 -3
  686. package/dist/server/src/lib/db/migrations/index.js +6 -0
  687. package/dist/server/src/lib/db/migrations/runner.js +1 -1
  688. package/dist/server/src/lib/db/migrations/v57-push-subscription-defaults-notice.js +54 -0
  689. package/dist/server/src/lib/db/migrations/v58-agent-session-costs.js +100 -0
  690. package/dist/server/src/lib/db/migrations/v59-opencode-instance-settings.js +71 -0
  691. package/dist/server/src/lib/db/push-subscriptions-db.js +56 -5
  692. package/dist/server/src/lib/detection/cli-patterns.js +17 -6
  693. package/dist/server/src/lib/detection/excerpt.js +48 -0
  694. package/dist/server/src/lib/detection/model-info-extractor.js +26 -3
  695. package/dist/server/src/lib/detection/opencode-modal-overlay.js +400 -0
  696. package/dist/server/src/lib/detection/opencode-pane-obstruction.js +181 -0
  697. package/dist/server/src/lib/detection/status-detector.js +7 -0
  698. package/dist/server/src/lib/detection/status-reason.js +20 -0
  699. package/dist/server/src/lib/detection/terminal-columns.js +94 -0
  700. package/dist/server/src/lib/detection/tools/opencode/detect.js +43 -0
  701. package/dist/server/src/lib/detection/tools/opencode/prompt.js +20 -0
  702. package/dist/server/src/lib/detection/tools/verified-against.js +14 -3
  703. package/dist/server/src/lib/detection/upstream-faults.js +7 -22
  704. package/dist/server/src/lib/hooks/agent-session-telemetry.js +324 -0
  705. package/dist/server/src/lib/hooks/pending-decision-kind.js +72 -0
  706. package/dist/server/src/lib/hooks/sources/define-source.js +88 -0
  707. package/dist/server/src/lib/hooks/sources/opencode/client.js +907 -2
  708. package/dist/server/src/lib/hooks/sources/opencode/diff.js +336 -0
  709. package/dist/server/src/lib/hooks/sources/opencode/history.js +480 -0
  710. package/dist/server/src/lib/hooks/sources/opencode/ingest.js +76 -7
  711. package/dist/server/src/lib/hooks/sources/opencode/launch-settings.js +222 -0
  712. package/dist/server/src/lib/hooks/sources/opencode/mappers.js +31 -0
  713. package/dist/server/src/lib/hooks/sources/opencode/payloads.js +45 -0
  714. package/dist/server/src/lib/hooks/sources/opencode/ports.js +16 -0
  715. package/dist/server/src/lib/hooks/sources/opencode/push.js +307 -0
  716. package/dist/server/src/lib/hooks/sources/opencode/reattach.js +284 -0
  717. package/dist/server/src/lib/hooks/sources/opencode/runtime.js +165 -2
  718. package/dist/server/src/lib/hooks/sources/opencode/source.js +46 -2
  719. package/dist/server/src/lib/hooks/sources/opencode/subscription.js +407 -4
  720. package/dist/server/src/lib/hooks/sources/opencode/transcript.js +383 -0
  721. package/dist/server/src/lib/hooks/structured-decision-response.js +460 -0
  722. package/dist/server/src/lib/job-executor.js +43 -20
  723. package/dist/server/src/lib/polling/response-checker.js +43 -16
  724. package/dist/server/src/lib/polling/structured-history-gate.js +75 -0
  725. package/dist/server/src/lib/prompt-answer-sender.js +153 -2
  726. package/dist/server/src/lib/push/delivery-health.js +237 -0
  727. package/dist/server/src/lib/push/failure-push-notifier.js +109 -7
  728. package/dist/server/src/lib/push/index.js +25 -1
  729. package/dist/server/src/lib/push/prompt-card-state.js +254 -14
  730. package/dist/server/src/lib/push/push-sender.js +63 -12
  731. package/dist/server/src/lib/push/resolution-push-notifier.js +15 -3
  732. package/dist/server/src/lib/push/vapid.js +264 -5
  733. package/dist/server/src/lib/push/waiting-push-notifier.js +7 -0
  734. package/dist/server/src/lib/server/localhost-self-check.js +333 -0
  735. package/dist/server/src/lib/session/agent-event-state.js +169 -4
  736. package/dist/server/src/lib/session/claude-executor.js +152 -15
  737. package/dist/server/src/lib/session/current-output-builder.js +182 -15
  738. package/dist/server/src/lib/session/opencode-session-api.js +214 -0
  739. package/dist/server/src/lib/session/opencode-session-recall.js +168 -0
  740. package/dist/server/src/lib/session/opencode-session-store.js +274 -0
  741. package/dist/server/src/lib/session/provisional-turn.js +54 -1
  742. package/dist/server/src/lib/session/send-user-message.js +6 -5
  743. package/dist/server/src/lib/session/structured-prompt.js +53 -2
  744. package/dist/server/src/lib/skills/compatibility-matrix.js +50 -1
  745. package/dist/server/src/lib/tmux/tmux.js +74 -4
  746. package/dist/server/src/lib/verification/gate-runner.js +71 -8
  747. package/dist/server/src/types/agent-session.js +63 -0
  748. package/dist/server/src/types/agent-transcript.js +80 -0
  749. package/dist/server/src/types/opencode-export.js +228 -0
  750. package/dist/server/src/types/opencode-instance-settings.js +140 -0
  751. package/dist/server/src/types/opencode-share.js +111 -0
  752. package/dist/server/src/types/terminal-keys.js +69 -1
  753. package/dist/types/cli-tool-contracts.d.ts +48 -0
  754. package/dist/types/cli-tool-contracts.d.ts.map +1 -1
  755. package/dist/types/terminal-keys.d.ts +89 -0
  756. package/dist/types/terminal-keys.d.ts.map +1 -0
  757. package/dist/types/terminal-keys.js +105 -0
  758. package/package.json +1 -1
  759. package/.next/server/chunks/1029.js +0 -1
  760. package/.next/server/chunks/1239.js +0 -1
  761. package/.next/server/chunks/1538.js +0 -7
  762. package/.next/server/chunks/2546.js +0 -1
  763. package/.next/server/chunks/2689.js +0 -13
  764. package/.next/server/chunks/3292.js +0 -1
  765. package/.next/server/chunks/3417.js +0 -1
  766. package/.next/server/chunks/3736.js +0 -1
  767. package/.next/server/chunks/4423.js +0 -1
  768. package/.next/server/chunks/4444.js +0 -32
  769. package/.next/server/chunks/4565.js +0 -3
  770. package/.next/server/chunks/467.js +0 -1
  771. package/.next/server/chunks/4905.js +0 -5
  772. package/.next/server/chunks/552.js +0 -19
  773. package/.next/server/chunks/5998.js +0 -74
  774. package/.next/server/chunks/6919.js +0 -1
  775. package/.next/server/chunks/7970.js +0 -229
  776. package/.next/server/chunks/8536.js +0 -1
  777. package/.next/server/chunks/9284.js +0 -1
  778. package/.next/static/chunks/3361-5d6e93fba8a92bc1.js +0 -1
  779. package/.next/static/chunks/6381-8cfe50a5ca5425b1.js +0 -1
  780. package/.next/static/chunks/8521-c43994fb58501d13.js +0 -1
  781. package/.next/static/chunks/app/api/app/update/route-6add0d88e2828c23.js +0 -1
  782. package/.next/static/chunks/app/api/app/update-check/route-6add0d88e2828c23.js +0 -1
  783. package/.next/static/chunks/app/api/assistant/conversation/route-6add0d88e2828c23.js +0 -1
  784. package/.next/static/chunks/app/api/assistant/current-output/route-6add0d88e2828c23.js +0 -1
  785. package/.next/static/chunks/app/api/assistant/messages/route-6add0d88e2828c23.js +0 -1
  786. package/.next/static/chunks/app/api/assistant/session/route-6add0d88e2828c23.js +0 -1
  787. package/.next/static/chunks/app/api/assistant/start/route-6add0d88e2828c23.js +0 -1
  788. package/.next/static/chunks/app/api/assistant/terminal/route-6add0d88e2828c23.js +0 -1
  789. package/.next/static/chunks/app/api/assistant/tools/route-6add0d88e2828c23.js +0 -1
  790. package/.next/static/chunks/app/api/auth/login/route-6add0d88e2828c23.js +0 -1
  791. package/.next/static/chunks/app/api/auth/logout/route-6add0d88e2828c23.js +0 -1
  792. package/.next/static/chunks/app/api/auth/status/route-6add0d88e2828c23.js +0 -1
  793. package/.next/static/chunks/app/api/capabilities/route-6add0d88e2828c23.js +0 -1
  794. package/.next/static/chunks/app/api/daily-summary/route-6add0d88e2828c23.js +0 -1
  795. package/.next/static/chunks/app/api/daily-summary/status/route-6add0d88e2828c23.js +0 -1
  796. package/.next/static/chunks/app/api/external-apps/[id]/health/route-6add0d88e2828c23.js +0 -1
  797. package/.next/static/chunks/app/api/external-apps/[id]/route-6add0d88e2828c23.js +0 -1
  798. package/.next/static/chunks/app/api/external-apps/route-6add0d88e2828c23.js +0 -1
  799. package/.next/static/chunks/app/api/fs/browse/route-6add0d88e2828c23.js +0 -1
  800. package/.next/static/chunks/app/api/fs/recent-paths/route-6add0d88e2828c23.js +0 -1
  801. package/.next/static/chunks/app/api/hooks/agent-event/route-6add0d88e2828c23.js +0 -1
  802. package/.next/static/chunks/app/api/hooks/claude-done/route-6add0d88e2828c23.js +0 -1
  803. package/.next/static/chunks/app/api/hooks/permission-request/route-6add0d88e2828c23.js +0 -1
  804. package/.next/static/chunks/app/api/metrics/vibe/route-6add0d88e2828c23.js +0 -1
  805. package/.next/static/chunks/app/api/ollama/models/route-6add0d88e2828c23.js +0 -1
  806. package/.next/static/chunks/app/api/push/escalation/route-6add0d88e2828c23.js +0 -1
  807. package/.next/static/chunks/app/api/push/subscriptions/route-6add0d88e2828c23.js +0 -1
  808. package/.next/static/chunks/app/api/push/vapid/route-6add0d88e2828c23.js +0 -1
  809. package/.next/static/chunks/app/api/repositories/[id]/route-6add0d88e2828c23.js +0 -1
  810. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-6add0d88e2828c23.js +0 -1
  811. package/.next/static/chunks/app/api/repositories/[id]/todos/route-6add0d88e2828c23.js +0 -1
  812. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-6add0d88e2828c23.js +0 -1
  813. package/.next/static/chunks/app/api/repositories/clone/route-6add0d88e2828c23.js +0 -1
  814. package/.next/static/chunks/app/api/repositories/excluded/route-6add0d88e2828c23.js +0 -1
  815. package/.next/static/chunks/app/api/repositories/restore/route-6add0d88e2828c23.js +0 -1
  816. package/.next/static/chunks/app/api/repositories/route-6add0d88e2828c23.js +0 -1
  817. package/.next/static/chunks/app/api/repositories/scan/route-6add0d88e2828c23.js +0 -1
  818. package/.next/static/chunks/app/api/repositories/sync/route-6add0d88e2828c23.js +0 -1
  819. package/.next/static/chunks/app/api/repositories/validate-path/route-6add0d88e2828c23.js +0 -1
  820. package/.next/static/chunks/app/api/sidebar/group-order/route-6add0d88e2828c23.js +0 -1
  821. package/.next/static/chunks/app/api/skills/[id]/route-6add0d88e2828c23.js +0 -1
  822. package/.next/static/chunks/app/api/skills/installations/route-6add0d88e2828c23.js +0 -1
  823. package/.next/static/chunks/app/api/skills/operations/route-6add0d88e2828c23.js +0 -1
  824. package/.next/static/chunks/app/api/skills/reindex/route-6add0d88e2828c23.js +0 -1
  825. package/.next/static/chunks/app/api/skills/route-6add0d88e2828c23.js +0 -1
  826. package/.next/static/chunks/app/api/slash-commands/route-6add0d88e2828c23.js +0 -1
  827. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-6add0d88e2828c23.js +0 -1
  828. package/.next/static/chunks/app/api/tasks/[taskId]/route-6add0d88e2828c23.js +0 -1
  829. package/.next/static/chunks/app/api/templates/[id]/route-6add0d88e2828c23.js +0 -1
  830. package/.next/static/chunks/app/api/templates/route-6add0d88e2828c23.js +0 -1
  831. package/.next/static/chunks/app/api/todos/route-6add0d88e2828c23.js +0 -1
  832. package/.next/static/chunks/app/api/verification/runs/[runId]/route-6add0d88e2828c23.js +0 -1
  833. package/.next/static/chunks/app/api/verification/runs/route-6add0d88e2828c23.js +0 -1
  834. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-6add0d88e2828c23.js +0 -1
  835. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-6add0d88e2828c23.js +0 -1
  836. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-6add0d88e2828c23.js +0 -1
  837. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-6add0d88e2828c23.js +0 -1
  838. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-6add0d88e2828c23.js +0 -1
  839. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-6add0d88e2828c23.js +0 -1
  840. package/.next/static/chunks/app/api/worktrees/[id]/env/route-6add0d88e2828c23.js +0 -1
  841. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-6add0d88e2828c23.js +0 -1
  842. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-6add0d88e2828c23.js +0 -1
  843. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-6add0d88e2828c23.js +0 -1
  844. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-6add0d88e2828c23.js +0 -1
  845. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-6add0d88e2828c23.js +0 -1
  846. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-6add0d88e2828c23.js +0 -1
  847. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-6add0d88e2828c23.js +0 -1
  848. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-6add0d88e2828c23.js +0 -1
  849. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-6add0d88e2828c23.js +0 -1
  850. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-6add0d88e2828c23.js +0 -1
  851. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-6add0d88e2828c23.js +0 -1
  852. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-6add0d88e2828c23.js +0 -1
  853. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-6add0d88e2828c23.js +0 -1
  854. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-6add0d88e2828c23.js +0 -1
  855. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-6add0d88e2828c23.js +0 -1
  856. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-6add0d88e2828c23.js +0 -1
  857. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-6add0d88e2828c23.js +0 -1
  858. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-6add0d88e2828c23.js +0 -1
  859. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-6add0d88e2828c23.js +0 -1
  860. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-6add0d88e2828c23.js +0 -1
  861. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-6add0d88e2828c23.js +0 -1
  862. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-6add0d88e2828c23.js +0 -1
  863. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-6add0d88e2828c23.js +0 -1
  864. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-6add0d88e2828c23.js +0 -1
  865. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-6add0d88e2828c23.js +0 -1
  866. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-6add0d88e2828c23.js +0 -1
  867. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-6add0d88e2828c23.js +0 -1
  868. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-6add0d88e2828c23.js +0 -1
  869. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-6add0d88e2828c23.js +0 -1
  870. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-6add0d88e2828c23.js +0 -1
  871. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-6add0d88e2828c23.js +0 -1
  872. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-6add0d88e2828c23.js +0 -1
  873. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-6add0d88e2828c23.js +0 -1
  874. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-6add0d88e2828c23.js +0 -1
  875. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-6add0d88e2828c23.js +0 -1
  876. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-6add0d88e2828c23.js +0 -1
  877. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-6add0d88e2828c23.js +0 -1
  878. package/.next/static/chunks/app/api/worktrees/[id]/route-6add0d88e2828c23.js +0 -1
  879. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-6add0d88e2828c23.js +0 -1
  880. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-6add0d88e2828c23.js +0 -1
  881. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-6add0d88e2828c23.js +0 -1
  882. package/.next/static/chunks/app/api/worktrees/[id]/search/route-6add0d88e2828c23.js +0 -1
  883. package/.next/static/chunks/app/api/worktrees/[id]/send/route-6add0d88e2828c23.js +0 -1
  884. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-6add0d88e2828c23.js +0 -1
  885. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-6add0d88e2828c23.js +0 -1
  886. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-6add0d88e2828c23.js +0 -1
  887. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-6add0d88e2828c23.js +0 -1
  888. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-6add0d88e2828c23.js +0 -1
  889. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-6add0d88e2828c23.js +0 -1
  890. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-6add0d88e2828c23.js +0 -1
  891. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-6add0d88e2828c23.js +0 -1
  892. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-6add0d88e2828c23.js +0 -1
  893. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-6add0d88e2828c23.js +0 -1
  894. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-6add0d88e2828c23.js +0 -1
  895. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-6add0d88e2828c23.js +0 -1
  896. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-6add0d88e2828c23.js +0 -1
  897. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-6add0d88e2828c23.js +0 -1
  898. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-6add0d88e2828c23.js +0 -1
  899. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-6add0d88e2828c23.js +0 -1
  900. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-6add0d88e2828c23.js +0 -1
  901. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-6add0d88e2828c23.js +0 -1
  902. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-6add0d88e2828c23.js +0 -1
  903. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-6add0d88e2828c23.js +0 -1
  904. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-6add0d88e2828c23.js +0 -1
  905. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-6add0d88e2828c23.js +0 -1
  906. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-6add0d88e2828c23.js +0 -1
  907. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-6add0d88e2828c23.js +0 -1
  908. package/.next/static/chunks/app/api/worktrees/route-6add0d88e2828c23.js +0 -1
  909. package/.next/static/chunks/app/manifest.webmanifest/route-6add0d88e2828c23.js +0 -1
  910. package/.next/static/chunks/app/more/page-3266dfa945972649.js +0 -1
  911. package/.next/static/chunks/app/proxy/[...path]/route-6add0d88e2828c23.js +0 -1
  912. package/.next/static/chunks/app/review/page-8f63aff862fee421.js +0 -1
  913. package/.next/static/chunks/app/worktrees/[id]/layout-6add0d88e2828c23.js +0 -1
  914. package/.next/static/chunks/app/worktrees/[id]/page-f7b3dfbe757dc6b8.js +0 -1
  915. package/.next/static/chunks/app/worktrees/[id]/terminal/page-a75fe180a7233b2b.js +0 -1
  916. package/.next/static/css/928e5a8830fbf997.css +0 -1
  917. /package/.next/static/{9IXgWfBUtnEnRqnbmErTp → 0GHE2JGlFzqvSBZAcBFSt}/_buildManifest.js +0 -0
  918. /package/.next/static/{9IXgWfBUtnEnRqnbmErTp → 0GHE2JGlFzqvSBZAcBFSt}/_ssgManifest.js +0 -0
@@ -42,7 +42,7 @@
42
42
  * @module lib/hooks/sources/opencode/client
43
43
  */
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.MAX_OPENCODE_SSE_FRAME_CHARS = exports.MAX_OPENCODE_SESSION_STATUSES = exports.OPENCODE_EVENT_CONTENT_TYPE = exports.OPENCODE_JSON_CONTENT_TYPE = exports.OPENCODE_FETCH_REDIRECT = exports.OPENCODE_REQUEST_TIMEOUT_MS = exports.OPENCODE_SERVER_HOST = void 0;
45
+ exports.OPENCODE_SHARE_REQUEST_TIMEOUT_MS = exports.MAX_OPENCODE_DIFF_PATCH_CHARS = exports.MAX_OPENCODE_DIFF_FILES = exports.OPENCODE_CONTEXT_MESSAGE_WINDOW = exports.MAX_OPENCODE_SESSION_MESSAGES = exports.MAX_OPENCODE_SSE_FRAME_CHARS = exports.MAX_OPENCODE_SESSION_STATUSES = exports.OPENCODE_EVENT_CONTENT_TYPE = exports.OPENCODE_JSON_CONTENT_TYPE = exports.OPENCODE_FETCH_REDIRECT = exports.OPENCODE_REQUEST_TIMEOUT_MS = exports.OPENCODE_SERVER_HOST = void 0;
46
46
  exports.opencodeBaseUrl = opencodeBaseUrl;
47
47
  exports.probeOpencodeHealth = probeOpencodeHealth;
48
48
  exports.fetchOpencodeHealth = fetchOpencodeHealth;
@@ -50,11 +50,37 @@ exports.fetchOpencodePendingPermissions = fetchOpencodePendingPermissions;
50
50
  exports.fetchOpencodePendingQuestions = fetchOpencodePendingQuestions;
51
51
  exports.fetchOpencodeSessionStatuses = fetchOpencodeSessionStatuses;
52
52
  exports.fetchOpencodeActivity = fetchOpencodeActivity;
53
+ exports.abortOpencodeSession = abortOpencodeSession;
54
+ exports.opencodeFileUrl = opencodeFileUrl;
55
+ exports.newOpencodeMessageId = newOpencodeMessageId;
56
+ exports.promptSelectionBody = promptSelectionBody;
57
+ exports.sendOpencodePrompt = sendOpencodePrompt;
58
+ exports.readOpencodeUserMessage = readOpencodeUserMessage;
53
59
  exports.replyOpencodePermission = replyOpencodePermission;
54
60
  exports.replyOpencodeQuestion = replyOpencodeQuestion;
55
61
  exports.createSseParser = createSseParser;
56
62
  exports.openOpencodeEventStream = openOpencodeEventStream;
63
+ exports.fetchOpencodeSessionMessages = fetchOpencodeSessionMessages;
64
+ exports.fetchOpencodeModelContextLimit = fetchOpencodeModelContextLimit;
65
+ exports.readOpencodeModelContextLimit = readOpencodeModelContextLimit;
66
+ exports.fetchOpencodeProviderCatalog = fetchOpencodeProviderCatalog;
67
+ exports.readOpencodeProviderCatalog = readOpencodeProviderCatalog;
68
+ exports.fetchOpencodeAgents = fetchOpencodeAgents;
69
+ exports.readOpencodeAgents = readOpencodeAgents;
70
+ exports.isOpencodeLaunchableAgent = isOpencodeLaunchableAgent;
71
+ exports.fetchOpencodeContextTokens = fetchOpencodeContextTokens;
72
+ exports.readOpencodeFileDiffs = readOpencodeFileDiffs;
73
+ exports.fetchOpencodeMessageDiff = fetchOpencodeMessageDiff;
74
+ exports.revertOpencodeMessage = revertOpencodeMessage;
75
+ exports.unrevertOpencodeSession = unrevertOpencodeSession;
76
+ exports.fetchOpencodeShareMode = fetchOpencodeShareMode;
77
+ exports.shareOpencodeSession = shareOpencodeSession;
78
+ exports.unshareOpencodeSession = unshareOpencodeSession;
79
+ exports.fetchOpencodeSessionShareUrl = fetchOpencodeSessionShareUrl;
80
+ const crypto_1 = require("crypto");
81
+ const url_1 = require("url");
57
82
  const logger_1 = require("../../../../lib/logger");
83
+ const opencode_share_1 = require("../../../../types/opencode-share");
58
84
  const logger = (0, logger_1.createLogger)('lib/hooks/sources/opencode/client');
59
85
  /**
60
86
  * The only host an opencode server is ever addressed on.
@@ -308,6 +334,238 @@ async function fetchOpencodeActivity(port) {
308
334
  return null;
309
335
  return Object.values(statuses).includes('busy') ? 'busy' : 'idle';
310
336
  }
337
+ /**
338
+ * Stop the turn one session is running (Issue #2034).
339
+ *
340
+ * `POST /session/:id/abort`. Measured live on **1.18.22** — isolated HOME, an
341
+ * `opencode serve` on 127.0.0.1:4298, LM Studio as the provider, a generation
342
+ * aborted 6 s in:
343
+ *
344
+ * ```
345
+ * HTTP/1.1 200 OK
346
+ * Content-Type: application/json
347
+ * Content-Length: 4
348
+ *
349
+ * true
350
+ * ```
351
+ *
352
+ * and on the event stream, in the same millisecond as the reply:
353
+ *
354
+ * ```
355
+ * 10:17:25.946 session.error MessageAbortedError
356
+ * 10:17:25.946 session.status idle
357
+ * 10:17:25.946 session.idle <- 1st
358
+ * 10:17:25.969 session.idle <- 2nd, 23 ms later
359
+ * ```
360
+ *
361
+ * Two consequences for the caller, and neither is visible from the status code:
362
+ *
363
+ * - **`true` is "accepted", not "a turn was stopped".** Aborting the SAME
364
+ * session again once it was already idle answered `200 true` as well, and
365
+ * emitted one more `session.idle`. So the reply cannot confirm the turn
366
+ * ended; only the event can — see `./subscription`'s idle watch.
367
+ * - **The idle can arrive before this promise resolves.** It did here: the
368
+ * frame is emitted while the request is still in flight. A caller that
369
+ * starts watching *after* awaiting this call can miss its own completion.
370
+ *
371
+ * `true` is required rather than "not null" because the route's own schema
372
+ * (`GET /doc`, `operationId: session.abort`) declares a bare boolean body: a
373
+ * `false` is the server saying it did not take the request, and `requestJson`
374
+ * would hand that back as a perfectly good parsed body.
375
+ *
376
+ * @param port - The instance's server
377
+ * @param sessionId - `ses_…`, the session whose turn should stop
378
+ * @returns Whether the server accepted the abort
379
+ */
380
+ async function abortOpencodeSession(port, sessionId) {
381
+ const result = await requestJson(`${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/abort`, { method: 'POST' });
382
+ return result === true;
383
+ }
384
+ /**
385
+ * The `file://` URL for a local file, which is the only form the route takes.
386
+ *
387
+ * Measured on 1.18.22 (Issue #2035). A bare absolute path in `FilePartInput.url`
388
+ * is **accepted with `204` and then silently discarded** — the server answers
389
+ * before it resolves the part, and the resolution failure arrives on the event
390
+ * stream instead:
391
+ *
392
+ * ```
393
+ * session.error UnknownError
394
+ * TypeError: "/…/probe.png" cannot be parsed as a URL.
395
+ * at SessionPrompt.resolveUserPart …
396
+ * ```
397
+ *
398
+ * and the **whole message is dropped, its text part included** — a read-back of
399
+ * the message id answers `404`. So this is not a nicety: a path handed over
400
+ * unencoded loses the operator's message with a success status code on the wire.
401
+ *
402
+ * `pathToFileURL` rather than `'file://' + path` because the difference is
403
+ * exactly the paths people have: a space or a `#` in a worktree name makes the
404
+ * concatenated string a different URL, and non-ASCII makes it an invalid one.
405
+ *
406
+ * @param absolutePath - Absolute path to a local file
407
+ * @returns `file:///…`, percent-encoded
408
+ */
409
+ function opencodeFileUrl(absolutePath) {
410
+ return (0, url_1.pathToFileURL)(absolutePath).href;
411
+ }
412
+ /**
413
+ * A message id for a prompt CommandMate is about to post.
414
+ *
415
+ * The route accepts a caller-chosen `messageID` (schema: `pattern: "^msg"`), and
416
+ * that is what makes the send verifiable: the id is known *before* the request,
417
+ * so {@link readOpencodeUserMessage} can ask for that exact message afterwards
418
+ * rather than guessing which of the session's messages was this one. Measured on
419
+ * 1.18.22 — `msg_cmate2035probe0001` was accepted and read back verbatim.
420
+ *
421
+ * The `cmate` infix is deliberate: opencode's own ids are
422
+ * `msg_037794348001Ajss6k50nWrocp`, so a CommandMate-originated message stays
423
+ * identifiable in `opencode.db` afterwards, and the two generators cannot
424
+ * collide.
425
+ */
426
+ function newOpencodeMessageId() {
427
+ return `msg_cmate${(0, crypto_1.randomBytes)(12).toString('hex')}`;
428
+ }
429
+ /**
430
+ * The `prompt_async` body keys a selection contributes, or nothing.
431
+ *
432
+ * Keys are omitted rather than nulled so a request from an instance with no
433
+ * settings is byte-identical to the pre-#2048 one.
434
+ */
435
+ function promptSelectionBody(selection) {
436
+ if (!selection)
437
+ return {};
438
+ const body = {};
439
+ if (selection.agent)
440
+ body.agent = selection.agent;
441
+ if (selection.model?.providerID && selection.model.modelID) {
442
+ body.model = {
443
+ providerID: selection.model.providerID,
444
+ modelID: selection.model.modelID,
445
+ };
446
+ }
447
+ if (selection.variant)
448
+ body.variant = selection.variant;
449
+ return body;
450
+ }
451
+ /**
452
+ * Post one prompt to a session without waiting for the reply (Issue #2035).
453
+ *
454
+ * `POST /session/:id/prompt_async`. This is the route the send path takes when
455
+ * the instance has a server, and it was chosen over `/tui/append-prompt` +
456
+ * `/tui/submit-prompt` on a measurement, not a preference — see
457
+ * `docs/design/opencode-server-live-verification.md` §11.4. The short version:
458
+ * the `/tui/*` pair drives the TUI's **composer**, so it inherits the composer's
459
+ * state, and a body whose first token matches a slash command opens the command
460
+ * palette and the palette then eats the submit. `/exit` as a message body
461
+ * answered `200 true` on all three calls and produced no message at all. This
462
+ * route does not go through the composer, and the same body arrived verbatim.
463
+ *
464
+ * **`204` means accepted, not delivered.** Three measured ways that gap opens:
465
+ *
466
+ * - a file part whose `url` is not a URL is dropped along with its whole
467
+ * message ({@link opencodeFileUrl});
468
+ * - a server that shares `HOME` + project with this one answers `204` for a
469
+ * session it can reach through `opencode.db` — and the message then appears
470
+ * on **neither** this server's event stream nor this pane's screen;
471
+ * - an unknown route on a real opencode answers `200 text/html` (#1931), which
472
+ * is why the status is compared exactly rather than through `response.ok`.
473
+ *
474
+ * {@link readOpencodeUserMessage} is the other half, and callers are expected to
475
+ * use it. Nothing here throws.
476
+ *
477
+ * @param port - The instance's server
478
+ * @param sessionId - `ses_…`, the session the message belongs to
479
+ * @param messageId - `msg_…`, from {@link newOpencodeMessageId}
480
+ * @param parts - The message body; at least one part
481
+ * @returns Whether the server answered `204`
482
+ */
483
+ async function sendOpencodePrompt(port, sessionId, messageId, parts, selection) {
484
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/prompt_async`;
485
+ try {
486
+ const response = await loopbackFetch(url, {
487
+ method: 'POST',
488
+ headers: { 'Content-Type': exports.OPENCODE_JSON_CONTENT_TYPE },
489
+ body: JSON.stringify({
490
+ messageID: messageId,
491
+ ...promptSelectionBody(selection),
492
+ parts,
493
+ }),
494
+ signal: AbortSignal.timeout(exports.OPENCODE_REQUEST_TIMEOUT_MS),
495
+ });
496
+ if (response.status !== 204) {
497
+ logger.warn('opencode-prompt-rejected', { port, sessionId, status: response.status });
498
+ return false;
499
+ }
500
+ return true;
501
+ }
502
+ catch (error) {
503
+ logger.debug('opencode-request-failed', {
504
+ url,
505
+ error: error instanceof Error ? error.message : String(error),
506
+ });
507
+ return false;
508
+ }
509
+ }
510
+ /**
511
+ * Read back one message by the id it was posted under (Issue #2035).
512
+ *
513
+ * `GET /session/:id/message/:messageID`. The positive evidence for a send, in
514
+ * the same sense `session.idle` is the positive evidence for an abort (#2034):
515
+ * the status code on the way in says the request was taken, and only this says
516
+ * the message exists.
517
+ *
518
+ * Measured on 1.18.22 across five runs: the message was readable on the **first**
519
+ * attempt, 8-23 ms after the POST began — `prompt_async` answers `204` after the
520
+ * message is created, not before. The falsification ran too: a message posted
521
+ * with a malformed file part answered `204` and then `404` here, which is the
522
+ * case the whole ladder is for.
523
+ *
524
+ * `info.role` is checked because the id space is shared with the assistant's
525
+ * messages: a `messageID` that collided with one would otherwise read back as a
526
+ * perfectly good delivery of somebody else's text.
527
+ *
528
+ * @param port - The instance's server
529
+ * @param sessionId - `ses_…`
530
+ * @param messageId - `msg_…`, the id the prompt was posted under
531
+ */
532
+ async function readOpencodeUserMessage(port, sessionId, messageId) {
533
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}` +
534
+ `/message/${encodeURIComponent(messageId)}`;
535
+ let response;
536
+ try {
537
+ response = await loopbackFetch(url, {
538
+ signal: AbortSignal.timeout(exports.OPENCODE_REQUEST_TIMEOUT_MS),
539
+ });
540
+ }
541
+ catch (error) {
542
+ return { kind: 'unknown', reason: error instanceof Error ? error.message : String(error) };
543
+ }
544
+ if (response.status === 404)
545
+ return { kind: 'missing' };
546
+ if (!response.ok)
547
+ return { kind: 'unknown', reason: `status ${response.status}` };
548
+ if (!hasContentType(response, exports.OPENCODE_JSON_CONTENT_TYPE)) {
549
+ return { kind: 'unknown', reason: 'content-type' };
550
+ }
551
+ let body;
552
+ try {
553
+ body = (await response.json());
554
+ }
555
+ catch {
556
+ return { kind: 'unknown', reason: 'body' };
557
+ }
558
+ if (!isPlainObject(body))
559
+ return { kind: 'unknown', reason: 'body' };
560
+ const info = isPlainObject(body.info) ? body.info : null;
561
+ if (info === null || info.role !== 'user')
562
+ return { kind: 'unknown', reason: 'role' };
563
+ const texts = (Array.isArray(body.parts) ? body.parts : [])
564
+ .filter(isPlainObject)
565
+ .filter((part) => part.type === 'text' && typeof part.text === 'string')
566
+ .map((part) => part.text);
567
+ return { kind: 'found', texts };
568
+ }
311
569
  /**
312
570
  * Answer one approval.
313
571
  *
@@ -333,8 +591,17 @@ async function replyOpencodePermission(port, requestId, reply, message) {
333
591
  /**
334
592
  * Answer one question.
335
593
  *
594
+ * Reachable from production since Issue #2039. It was written with #1763's
595
+ * source and then had no caller for a year of Issues: `decideOpencode` routes
596
+ * `{ kind: 'answer' }` here, and nothing in `src/` built that verdict, so a
597
+ * `question.asked` could be displayed and never answered except with arrow
598
+ * keys. What #2039 added is the two mappings above it —
599
+ * `resolveStructuredQuestionAnswer` and the `kind === 'question'` branch of
600
+ * `respondByDecisionId` — not a line of this function.
601
+ *
336
602
  * @param answers - One array of selected labels per question, in the order the
337
- * `question.asked` frame listed them
603
+ * `question.asked` frame listed them. Measured shape: `{"answers":[["Blue"]]}`
604
+ * for the one-question call (#1758 §5.2.4)
338
605
  */
339
606
  async function replyOpencodeQuestion(port, questionId, answers) {
340
607
  const result = await requestJson(`${opencodeBaseUrl(port)}/question/${encodeURIComponent(questionId)}/reply`, {
@@ -560,3 +827,641 @@ function safeParseFrame(raw) {
560
827
  return null;
561
828
  }
562
829
  }
830
+ /**
831
+ * Cap on messages read back from one `GET /session/:id/message` (Issue #2041).
832
+ *
833
+ * Same argument as {@link MAX_OPENCODE_SESSION_STATUSES}: the document comes off
834
+ * a process CommandMate did not start, one server's `opencode.db` is shared by
835
+ * every TUI with the same HOME and project (#1758 §5.6.3), and a session that
836
+ * has been going for a week is not bounded by this instance's behaviour. Two
837
+ * messages per turn measured on 1.18.22 (one user, one or two assistant), so
838
+ * this is roughly 250 turns.
839
+ */
840
+ exports.MAX_OPENCODE_SESSION_MESSAGES = 500;
841
+ /**
842
+ * Every message in one session, with its parts (Issue #2041).
843
+ *
844
+ * `GET /session/:id/message`. The only route to a reply CommandMate did not see
845
+ * arrive: a fresh subscription to `/event` replays **nothing** — measured on
846
+ * 1.18.22, a second SSE connection opened after three completed turns received
847
+ * one `server.connected` frame and then silence — so a turn that ran while this
848
+ * server was down exists only here.
849
+ *
850
+ * The body is an array of `{ info, parts }`. Returned raw rather than parsed
851
+ * because the parsing lives in `./transcript`, which has to read the *same*
852
+ * shape off the event stream and must not have two readers of it.
853
+ *
854
+ * Answers null for every failure, including the ordinary "nothing is listening
855
+ * because the pane exited" — a caller cannot act on the difference and the
856
+ * distinction {@link OpencodeMessageReadback} draws is not available here (a
857
+ * missing session is a 404 that means the same as an unreachable one for a
858
+ * backfill: there is nothing to recover).
859
+ *
860
+ * @param port - The instance's server
861
+ * @param sessionId - `ses_…`
862
+ * @returns The array, bounded to the newest {@link MAX_OPENCODE_SESSION_MESSAGES}, or null
863
+ */
864
+ async function fetchOpencodeSessionMessages(port, sessionId) {
865
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/message`;
866
+ const body = await requestJson(url);
867
+ if (!Array.isArray(body))
868
+ return null;
869
+ const entries = body.filter(isPlainObject);
870
+ // Newest kept, and the array stays in the server's own order so `parentID`
871
+ // grouping still sees a turn's messages together.
872
+ return entries.length > exports.MAX_OPENCODE_SESSION_MESSAGES
873
+ ? entries.slice(entries.length - exports.MAX_OPENCODE_SESSION_MESSAGES)
874
+ : entries;
875
+ }
876
+ // ============================================================================
877
+ // Context occupancy (Issue #2042). Appended at the end of the file on purpose:
878
+ // #2041 is rewriting this module's neighbours in parallel, and everything below
879
+ // is additive — no export above it is touched.
880
+ // ============================================================================
881
+ /**
882
+ * How many trailing messages are read back to find the last assistant turn.
883
+ *
884
+ * `GET /session/:id/message?limit=N` answers the **last** N messages in
885
+ * chronological order — measured on 1.18.22, see
886
+ * `docs/design/opencode-server-live-verification.md` §14.3. Four is two
887
+ * user/assistant pairs: enough that a turn still streaming (its assistant
888
+ * message exists but has `output === 0`) falls back to the previous completed
889
+ * one, and small enough that the read stays a few KB rather than the whole
890
+ * conversation. A session whose last four messages contain no finished
891
+ * assistant turn answers null, which is the honest answer — it has not spent a
892
+ * turn yet.
893
+ */
894
+ exports.OPENCODE_CONTEXT_MESSAGE_WINDOW = 4;
895
+ /**
896
+ * What one model declares it can hold, as `GET /config/providers` states it.
897
+ *
898
+ * Only `context` is read. `limit.input` is also published and is **not** the
899
+ * denominator: on `github-copilot/claude-sonnet-4.6` it is 936,000 against a
900
+ * `context` of 1,000,000, and opencode's own readout divides by `context`
901
+ * (§14.2 quotes the 1.18.22 bundle).
902
+ */
903
+ async function fetchOpencodeModelContextLimit(port, providerId, modelId) {
904
+ const body = await fetchOpencodeProvidersDocument(port);
905
+ return readOpencodeModelContextLimit(body, providerId, modelId);
906
+ }
907
+ /**
908
+ * `GET /config/providers`, unparsed — the one reader of that route (#2048).
909
+ *
910
+ * Issue #2042 read this route for `limit.context` and Issue #2048 needs the
911
+ * same document for the *model and variant catalogue* the settings pane offers.
912
+ * Two independent readers of one endpoint is how the two come to disagree about
913
+ * its shape, so both go through here and each takes what it needs from the
914
+ * body. Nothing is cached: the call is a loopback round trip on a route that
915
+ * answers from memory, and the alternative is a cache that has to be invalidated
916
+ * when the operator adds a provider.
917
+ */
918
+ async function fetchOpencodeProvidersDocument(port) {
919
+ return requestJson(`${opencodeBaseUrl(port)}/config/providers`);
920
+ }
921
+ /**
922
+ * `limit.context` for one model, out of a `GET /config/providers` body.
923
+ *
924
+ * Split from the fetch so the arithmetic is testable against a recorded body
925
+ * rather than a live server. Behaviour is #2042's, unchanged: `context` only,
926
+ * and a non-positive value is "no percentage" rather than a divisor.
927
+ */
928
+ function readOpencodeModelContextLimit(body, providerId, modelId) {
929
+ if (!isPlainObject(body))
930
+ return null;
931
+ const providers = Array.isArray(body.providers) ? body.providers : [];
932
+ for (const provider of providers) {
933
+ if (!isPlainObject(provider) || provider.id !== providerId)
934
+ continue;
935
+ const models = isPlainObject(provider.models) ? provider.models : null;
936
+ if (!models)
937
+ return null;
938
+ const model = models[modelId];
939
+ if (!isPlainObject(model))
940
+ return null;
941
+ const limit = isPlainObject(model.limit) ? model.limit : null;
942
+ if (!limit)
943
+ return null;
944
+ const context = limit.context;
945
+ // A zero or a negative would divide into a percentage nobody can read, and
946
+ // opencode itself treats a falsy `limit.context` as "no percentage".
947
+ if (typeof context !== 'number' || !Number.isFinite(context) || context <= 0)
948
+ return null;
949
+ return context;
950
+ }
951
+ return null;
952
+ }
953
+ /**
954
+ * The provider / model / variant catalogue the settings pane offers (#2048).
955
+ *
956
+ * Three shapes measured on 1.18.22 (§20.1), each of which is easy to guess
957
+ * wrong:
958
+ *
959
+ * - **`providers` is an array, `models` is an object.** The models are keyed by
960
+ * model id, not listed — `providers[].models["claude-sonnet-4.6"]` — so an
961
+ * `Array.isArray` guard on it drops every model there is.
962
+ * - **`variants` is an object too**, keyed by variant name (`low` / `medium` /
963
+ * `high` / `max` / `minimal` / `none` / `xhigh` across the measured
964
+ * catalogue), whose values carry `effort` or `reasoningEffort`. Only the keys
965
+ * are kept: the name is what `prompt_async` takes, and the effort inside it
966
+ * is opencode's own restatement of the same word.
967
+ * - **`variants: {}` is a real answer**, not a missing field — `kimi-k2.7-code`
968
+ * publishes it — and it is how the pane knows to offer no variant at all.
969
+ *
970
+ * Entries that do not parse are dropped rather than represented: this feeds a
971
+ * `<select>`, and an option with no id is an option that cannot be chosen.
972
+ *
973
+ * @param port - The instance's server
974
+ * @returns The catalogue, or an empty array when the server could not be asked
975
+ */
976
+ async function fetchOpencodeProviderCatalog(port) {
977
+ return readOpencodeProviderCatalog(await fetchOpencodeProvidersDocument(port));
978
+ }
979
+ /** {@link fetchOpencodeProviderCatalog}'s parser, over an already-read body. */
980
+ function readOpencodeProviderCatalog(body) {
981
+ if (!isPlainObject(body))
982
+ return [];
983
+ const providers = Array.isArray(body.providers) ? body.providers : [];
984
+ const catalog = [];
985
+ for (const provider of providers) {
986
+ if (!isPlainObject(provider))
987
+ continue;
988
+ const id = typeof provider.id === 'string' ? provider.id : null;
989
+ if (!id)
990
+ continue;
991
+ const models = [];
992
+ const rawModels = isPlainObject(provider.models) ? provider.models : {};
993
+ for (const [modelId, rawModel] of Object.entries(rawModels)) {
994
+ if (!isPlainObject(rawModel))
995
+ continue;
996
+ const variants = isPlainObject(rawModel.variants) ? Object.keys(rawModel.variants) : [];
997
+ models.push({
998
+ id: modelId,
999
+ name: typeof rawModel.name === 'string' && rawModel.name.length > 0
1000
+ ? rawModel.name
1001
+ : modelId,
1002
+ variants: variants.sort(),
1003
+ });
1004
+ }
1005
+ models.sort((a, b) => a.id.localeCompare(b.id));
1006
+ catalog.push({
1007
+ id,
1008
+ name: typeof provider.name === 'string' && provider.name.length > 0 ? provider.name : id,
1009
+ models,
1010
+ });
1011
+ }
1012
+ catalog.sort((a, b) => a.id.localeCompare(b.id));
1013
+ return catalog;
1014
+ }
1015
+ /**
1016
+ * The personas this server will start a session as — `GET /agent` (#2048).
1017
+ *
1018
+ * An **array**, unlike `/config/providers`'s object-of-models, and its entries
1019
+ * carry two fields that decide what the pane may offer (§20.1): `mode` is
1020
+ * `primary` or `subagent`, and `hidden` is `true` on the three internal
1021
+ * personas (`compaction`, `summary`, `title`). A stock 1.18.22 install answered
1022
+ * seven agents of which exactly two — `build` and `plan` — are primary and
1023
+ * visible, which is the pair Issue #2048's acceptance condition names.
1024
+ *
1025
+ * Both fields are kept rather than filtered here: this is the reader, and which
1026
+ * agents a *launch* may name is a policy the caller states —
1027
+ * {@link isOpencodeLaunchableAgent}.
1028
+ *
1029
+ * @param port - The instance's server
1030
+ * @returns Every agent the server declared, or an empty array when it could not
1031
+ * be asked
1032
+ */
1033
+ async function fetchOpencodeAgents(port) {
1034
+ return readOpencodeAgents(await requestJson(`${opencodeBaseUrl(port)}/agent`));
1035
+ }
1036
+ /** {@link fetchOpencodeAgents}'s parser, over an already-read body. */
1037
+ function readOpencodeAgents(body) {
1038
+ if (!Array.isArray(body))
1039
+ return [];
1040
+ const agents = [];
1041
+ for (const entry of body) {
1042
+ if (!isPlainObject(entry))
1043
+ continue;
1044
+ const name = typeof entry.name === 'string' ? entry.name : null;
1045
+ if (!name)
1046
+ continue;
1047
+ // `hidden` is absent on the visible ones rather than `false`, so the test is
1048
+ // truthiness of the key and not a comparison against `false`.
1049
+ if (entry.hidden === true)
1050
+ continue;
1051
+ agents.push({
1052
+ name,
1053
+ mode: typeof entry.mode === 'string' ? entry.mode : '',
1054
+ description: typeof entry.description === 'string' ? entry.description : null,
1055
+ });
1056
+ }
1057
+ return agents;
1058
+ }
1059
+ /**
1060
+ * Whether an agent may be named on a launch line or a prompt.
1061
+ *
1062
+ * `primary` only. A `subagent` (`explore`, `general`) is something a running
1063
+ * session spawns for a `task` tool call; naming one as the session's own persona
1064
+ * is not a thing opencode's UI offers and not something measured to work.
1065
+ */
1066
+ function isOpencodeLaunchableAgent(agent) {
1067
+ return agent.mode === 'primary';
1068
+ }
1069
+ /** A finite, non-negative token count, or 0 — the shape `tokens.*` arrives in. */
1070
+ function readTokenCount(source, key) {
1071
+ const value = source[key];
1072
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0;
1073
+ }
1074
+ /**
1075
+ * How full this session's context is, in tokens (Issue #2042).
1076
+ *
1077
+ * **This is not `Session.tokens` and the difference is the whole point.**
1078
+ * `session.updated` reports a *cumulative* count — after two turns the measured
1079
+ * session read `input 6 / output 11 / cache.read 8482 / cache.write 8500`, which
1080
+ * is what `opencode stats` prints and what `AgentSessionRecord` carries.
1081
+ * What opencode's own TUI shows as `8.5K (1%)` is a different quantity: the
1082
+ * token footprint of the **last assistant message**, which is what the next
1083
+ * request actually has to fit into a context window. Summing the session's
1084
+ * counts would have said 16,999 where opencode says 8,508, and the gap widens
1085
+ * with every turn (§14.2).
1086
+ *
1087
+ * The rule is opencode's own, transcribed from the 1.18.22 bundle rather than
1088
+ * inferred: take the last message with `role === 'assistant'` **and**
1089
+ * `tokens.output > 0`, and add `input + output + reasoning + cache.read +
1090
+ * cache.write`. The `output > 0` clause is what skips the assistant message a
1091
+ * turn opens with, whose counts are all zero until the turn finishes.
1092
+ *
1093
+ * `tokens.total` on that message is opencode's own sum of exactly those five
1094
+ * and was measured equal to it (8491, then 8508) — it is not read here because
1095
+ * it is absent until the turn completes, and the five are the definition.
1096
+ *
1097
+ * @param port - The instance's server
1098
+ * @param sessionId - `ses_…`
1099
+ * @returns The occupancy in tokens, or null when no finished assistant turn is
1100
+ * in the window (a fresh session, or one whose last four messages are all
1101
+ * user prompts) and on every transport failure
1102
+ */
1103
+ async function fetchOpencodeContextTokens(port, sessionId) {
1104
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/message` +
1105
+ `?limit=${exports.OPENCODE_CONTEXT_MESSAGE_WINDOW}`;
1106
+ const body = await requestJson(url);
1107
+ if (!Array.isArray(body))
1108
+ return null;
1109
+ for (let index = body.length - 1; index >= 0; index -= 1) {
1110
+ const entry = body[index];
1111
+ if (!isPlainObject(entry))
1112
+ continue;
1113
+ // `{ info, parts }`; only `info` carries the counts.
1114
+ const info = isPlainObject(entry.info) ? entry.info : null;
1115
+ if (!info || info.role !== 'assistant')
1116
+ continue;
1117
+ const tokens = isPlainObject(info.tokens) ? info.tokens : null;
1118
+ if (!tokens)
1119
+ continue;
1120
+ const output = readTokenCount(tokens, 'output');
1121
+ if (output <= 0)
1122
+ continue;
1123
+ const cache = isPlainObject(tokens.cache) ? tokens.cache : {};
1124
+ return (readTokenCount(tokens, 'input') +
1125
+ output +
1126
+ readTokenCount(tokens, 'reasoning') +
1127
+ readTokenCount(cache, 'read') +
1128
+ readTokenCount(cache, 'write'));
1129
+ }
1130
+ return null;
1131
+ }
1132
+ const OPENCODE_FILE_DIFF_STATUSES = ['added', 'deleted', 'modified'];
1133
+ /**
1134
+ * Cap on files kept from one diff.
1135
+ *
1136
+ * A diff is carried on the status poll's payload, and `patch` is unbounded — a
1137
+ * generated lockfile is megabytes of it. The cap is on *files* rather than
1138
+ * bytes so the panel never shows half a file's name; {@link MAX_OPENCODE_DIFF_PATCH_CHARS}
1139
+ * is the byte-side companion.
1140
+ */
1141
+ exports.MAX_OPENCODE_DIFF_FILES = 200;
1142
+ /** Cap on one file's `patch`. Truncated patches still render; huge ones do not. */
1143
+ exports.MAX_OPENCODE_DIFF_PATCH_CHARS = 64 * 1024;
1144
+ /**
1145
+ * Read an array of `SnapshotFileDiff` off any opencode payload.
1146
+ *
1147
+ * Shared by the event reader and the REST reader on purpose: `session.diff`'s
1148
+ * `properties.diff` and `GET /session/:id/diff`'s body are the *same* schema,
1149
+ * and two readers of one shape is how they come apart.
1150
+ *
1151
+ * Entries that are not objects are dropped rather than represented, and a
1152
+ * non-array answers the empty array — "the server said nothing readable" and
1153
+ * "the server said no files" are the same instruction to a panel that hides
1154
+ * itself when empty.
1155
+ */
1156
+ function readOpencodeFileDiffs(value) {
1157
+ if (!Array.isArray(value))
1158
+ return [];
1159
+ const files = [];
1160
+ for (const entry of value) {
1161
+ if (!isPlainObject(entry))
1162
+ continue;
1163
+ const patch = typeof entry.patch === 'string' ? entry.patch : null;
1164
+ files.push({
1165
+ file: typeof entry.file === 'string' && entry.file.length > 0 ? entry.file : null,
1166
+ patch: patch === null ? null : patch.slice(0, exports.MAX_OPENCODE_DIFF_PATCH_CHARS),
1167
+ additions: typeof entry.additions === 'number' && Number.isFinite(entry.additions)
1168
+ ? entry.additions
1169
+ : 0,
1170
+ deletions: typeof entry.deletions === 'number' && Number.isFinite(entry.deletions)
1171
+ ? entry.deletions
1172
+ : 0,
1173
+ status: typeof entry.status === 'string' && OPENCODE_FILE_DIFF_STATUSES.includes(entry.status)
1174
+ ? entry.status
1175
+ : null,
1176
+ });
1177
+ if (files.length >= exports.MAX_OPENCODE_DIFF_FILES)
1178
+ break;
1179
+ }
1180
+ return files;
1181
+ }
1182
+ /**
1183
+ * The files one user message's turn changed (Issue #2043).
1184
+ *
1185
+ * `GET /session/:id/diff?messageID=<msg…>`. **The `messageID` is not optional in
1186
+ * practice**: measured on 1.18.22, the same route without it answered `[]` both
1187
+ * before and after a turn that changed two files, while the same call *with* it
1188
+ * answered both files and their patches.
1189
+ *
1190
+ * The answer is a historical record rather than live state — measured: it still
1191
+ * returned the turn's two files after that turn had been reverted — so a caller
1192
+ * showing "what this turn changed" is reading the right thing, and a caller
1193
+ * asking "is this still applied" is not.
1194
+ *
1195
+ * A malformed `messageID` (one not starting with `msg`) is a **400** from the
1196
+ * server, which collapses to null here like every other failure.
1197
+ *
1198
+ * @param port - The instance's server
1199
+ * @param sessionId - `ses_…`
1200
+ * @param messageId - `msg_…`, the *user* message that opened the turn
1201
+ * @returns The files, or null when the server could not be asked
1202
+ */
1203
+ async function fetchOpencodeMessageDiff(port, sessionId, messageId) {
1204
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/diff` +
1205
+ `?messageID=${encodeURIComponent(messageId)}`;
1206
+ const body = await requestJson(url);
1207
+ if (!Array.isArray(body))
1208
+ return null;
1209
+ return readOpencodeFileDiffs(body);
1210
+ }
1211
+ /**
1212
+ * `Session.revert.messageID`, or null when the session holds nothing back.
1213
+ *
1214
+ * The one field that distinguishes a revert that took from one that did not,
1215
+ * for both routes: `POST /revert` sets it, `POST /unrevert` clears it, and a
1216
+ * no-op leaves it as it was.
1217
+ */
1218
+ function readSessionRevertMessageId(body) {
1219
+ if (!isPlainObject(body))
1220
+ return null;
1221
+ const revert = isPlainObject(body.revert) ? body.revert : null;
1222
+ if (!revert)
1223
+ return null;
1224
+ return typeof revert.messageID === 'string' && revert.messageID.length > 0
1225
+ ? revert.messageID
1226
+ : null;
1227
+ }
1228
+ /** One POST to a revert route, with the three measured statuses kept apart. */
1229
+ async function postOpencodeRevertRoute(url, body) {
1230
+ let response;
1231
+ try {
1232
+ response = await loopbackFetch(url, {
1233
+ method: 'POST',
1234
+ headers: { 'Content-Type': exports.OPENCODE_JSON_CONTENT_TYPE },
1235
+ body: JSON.stringify(body),
1236
+ signal: AbortSignal.timeout(exports.OPENCODE_REQUEST_TIMEOUT_MS),
1237
+ });
1238
+ }
1239
+ catch (error) {
1240
+ logger.debug('opencode-request-failed', {
1241
+ url,
1242
+ error: error instanceof Error ? error.message : String(error),
1243
+ });
1244
+ return { outcome: { kind: 'unreachable' } };
1245
+ }
1246
+ if (response.status === 409)
1247
+ return { outcome: { kind: 'busy' } };
1248
+ if (!response.ok) {
1249
+ logger.warn('opencode-revert-rejected', { url, status: response.status });
1250
+ return { outcome: { kind: 'rejected', status: response.status } };
1251
+ }
1252
+ // #1931: an unknown route on a real opencode answers `200 text/html`, so a
1253
+ // 200 alone does not mean this route exists on the server that answered.
1254
+ if (!hasContentType(response, exports.OPENCODE_JSON_CONTENT_TYPE)) {
1255
+ return { outcome: { kind: 'unreachable' } };
1256
+ }
1257
+ try {
1258
+ return { revertedTo: readSessionRevertMessageId(await response.json()) };
1259
+ }
1260
+ catch {
1261
+ return { outcome: { kind: 'unreachable' } };
1262
+ }
1263
+ }
1264
+ /**
1265
+ * Undo one turn's file changes (Issue #2043).
1266
+ *
1267
+ * `POST /session/:id/revert` with `{ messageID }`. **Destructive and measured to
1268
+ * be so**: reverting to the first turn of a two-turn session restored
1269
+ * `sample.txt` to its pre-session contents *and deleted* the `added.txt` the
1270
+ * agent had created. It rewrites the working tree from opencode's own git
1271
+ * snapshot ledger, so it can also undo work that was already committed — the
1272
+ * measurement in §16.5 left a clean tree reading ` D added.txt` / ` M
1273
+ * sample.txt` afterwards.
1274
+ *
1275
+ * That is why the caller is expected to confirm first, and why a `no_op` is
1276
+ * reported rather than swallowed.
1277
+ *
1278
+ * @param port - The instance's server
1279
+ * @param sessionId - `ses_…`
1280
+ * @param messageId - `msg_…`, the user message whose turn is being undone
1281
+ */
1282
+ async function revertOpencodeMessage(port, sessionId, messageId) {
1283
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/revert`;
1284
+ const result = await postOpencodeRevertRoute(url, { messageID: messageId });
1285
+ if ('outcome' in result)
1286
+ return result.outcome;
1287
+ // Measured twice, and the second measurement is why this compares ids rather
1288
+ // than testing for null. From a session with nothing reverted, an unknown
1289
+ // `messageID` answers `200` with `revert: null`. From a session that is
1290
+ // **already** holding a revert, the same request answers `200` with the
1291
+ // *existing* `revert` untouched — so a null check alone reported success, and
1292
+ // reported it under the previous revert's message id. A revert that took
1293
+ // echoes the id that was asked for; anything else did nothing.
1294
+ return result.revertedTo === messageId
1295
+ ? { kind: 'reverted', messageId }
1296
+ : { kind: 'no_op' };
1297
+ }
1298
+ /**
1299
+ * Put back everything a revert is holding (Issue #2043).
1300
+ *
1301
+ * `POST /session/:id/unrevert`. Takes no arguments — it restores *all*
1302
+ * previously reverted messages, per the server's own summary — and answers
1303
+ * **200 on a session with nothing reverted**, which is why "restored" here means
1304
+ * "nothing is held back now" rather than "something moved".
1305
+ *
1306
+ * Measured asymmetry worth knowing: a successful unrevert emits **no
1307
+ * `session.diff` frame at all**, only `session.updated` with `revert: null`. A
1308
+ * reader that waited for `session.diff` to go empty would wait forever, which is
1309
+ * why {@link readOpencodeRevertState} reads the session frame too.
1310
+ */
1311
+ async function unrevertOpencodeSession(port, sessionId) {
1312
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/unrevert`;
1313
+ const result = await postOpencodeRevertRoute(url, {});
1314
+ if ('outcome' in result)
1315
+ return result.outcome;
1316
+ // Here the null check *is* the right test: unrevert takes no argument, so
1317
+ // "nothing is held back any more" is the whole success condition. A session
1318
+ // that still reports a revert refused to let go of it.
1319
+ return result.revertedTo === null
1320
+ ? { kind: 'restored' }
1321
+ : { kind: 'no_op' };
1322
+ }
1323
+ // =============================================================================
1324
+ // Session sharing (Issue #2051)
1325
+ // =============================================================================
1326
+ /**
1327
+ * Timeout for the two share routes.
1328
+ *
1329
+ * Longer than {@link OPENCODE_REQUEST_TIMEOUT_MS}, which bounds loopback calls
1330
+ * that opencode answers out of its own process. These two do not stay on the
1331
+ * loopback: opencode uploads the session to its hosting and waits for the reply,
1332
+ * so the round trip includes somebody else's network. 20s rather than 5s, and
1333
+ * still bounded, because the operator is watching a spinner.
1334
+ */
1335
+ exports.OPENCODE_SHARE_REQUEST_TIMEOUT_MS = 20_000;
1336
+ /**
1337
+ * The `share` setting this server is running with.
1338
+ *
1339
+ * A whole `GET /config` fetch for one key, because that is the only place the
1340
+ * setting is exposed: there is no `/config/share`, and the value is not on the
1341
+ * session. Cheap enough — the measured body is under 200 bytes.
1342
+ *
1343
+ * @param port - The instance's server
1344
+ * @returns The mode, or null when the key is unset, unknown to this build, or
1345
+ * the server could not be asked. `null` must not be read as `'disabled'`;
1346
+ * see `src/types/opencode-share.ts`
1347
+ */
1348
+ async function fetchOpencodeShareMode(port) {
1349
+ const body = await requestJson(`${opencodeBaseUrl(port)}/config`);
1350
+ return (0, opencode_share_1.readOpencodeShareMode)(body);
1351
+ }
1352
+ /**
1353
+ * Publish one session to opencode's hosting.
1354
+ *
1355
+ * **This makes the conversation readable by anyone with the link**, under the
1356
+ * operator's own credentials. Measured on 1.18.22: the published page carries
1357
+ * the session *unredacted* — the prompts, the replies and the absolute
1358
+ * `directory` path were all present in the HTML. It is the exact opposite of
1359
+ * `opencode export --sanitize`, and nothing between here and the operator
1360
+ * removes anything. Every caller must have taken an explicit confirmation
1361
+ * first.
1362
+ *
1363
+ * Written against `requestJson`'s siblings rather than through it because the
1364
+ * status code is load-bearing here: `requestJson` collapses every non-2xx to
1365
+ * null, and a 404 (no such session) needs telling apart from a 500 (refused).
1366
+ *
1367
+ * @param port - The instance's server
1368
+ * @param sessionId - `ses_…`
1369
+ * @returns The outcome; on success, the URL opencode minted
1370
+ */
1371
+ async function shareOpencodeSession(port, sessionId) {
1372
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/share`;
1373
+ try {
1374
+ // Measured: the route takes no request body at all (`requestBody: null` in
1375
+ // opencode's own OpenAPI), so none is sent.
1376
+ const response = await loopbackFetch(url, {
1377
+ method: 'POST',
1378
+ signal: AbortSignal.timeout(exports.OPENCODE_SHARE_REQUEST_TIMEOUT_MS),
1379
+ });
1380
+ if (response.status === 404)
1381
+ return { kind: 'not-found' };
1382
+ if (!response.ok) {
1383
+ logger.warn('opencode-share-refused', { port, sessionId, status: response.status });
1384
+ return { kind: 'refused', status: response.status };
1385
+ }
1386
+ if (!hasContentType(response, exports.OPENCODE_JSON_CONTENT_TYPE)) {
1387
+ return { kind: 'failed', reason: 'response was not JSON' };
1388
+ }
1389
+ const body = (await response.json());
1390
+ const shareUrl = (0, opencode_share_1.readOpencodeShareUrl)(body);
1391
+ if (shareUrl === null) {
1392
+ // A 200 with no usable URL is the one case that must not read as success:
1393
+ // the session may well be published, and the operator would be told it is
1394
+ // not. Reported as a failure so the UI keeps the revoke path visible.
1395
+ logger.warn('opencode-share-no-url', { port, sessionId });
1396
+ return { kind: 'failed', reason: 'server returned no share URL' };
1397
+ }
1398
+ logger.info('opencode-share-created', { port, sessionId });
1399
+ return { kind: 'shared', url: shareUrl };
1400
+ }
1401
+ catch (error) {
1402
+ return {
1403
+ kind: 'failed',
1404
+ reason: error instanceof Error ? error.message : String(error),
1405
+ };
1406
+ }
1407
+ }
1408
+ /**
1409
+ * Take one session's published page down.
1410
+ *
1411
+ * Measured on 1.18.22, and both halves matter:
1412
+ *
1413
+ * - It **works**: the public URL stops serving the conversation and renders
1414
+ * opencode's own "Not Found" view instead. Note that the HTTP status stays
1415
+ * **200** — the not-found view is client-rendered — so a caller must not
1416
+ * verify revocation by fetching the URL and testing for 404.
1417
+ * - The session **keeps its `share: { url }`** afterwards, in the response to
1418
+ * this very call and in `GET /session/:id`, and it survives a server restart.
1419
+ * So there is no server-side flag saying "currently shared", and this
1420
+ * function's boolean is the only signal a caller gets.
1421
+ *
1422
+ * @param port - The instance's server
1423
+ * @param sessionId - `ses_…`
1424
+ * @returns Whether opencode accepted the revocation
1425
+ */
1426
+ async function unshareOpencodeSession(port, sessionId) {
1427
+ const url = `${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}/share`;
1428
+ try {
1429
+ const response = await loopbackFetch(url, {
1430
+ method: 'DELETE',
1431
+ signal: AbortSignal.timeout(exports.OPENCODE_SHARE_REQUEST_TIMEOUT_MS),
1432
+ });
1433
+ if (!response.ok) {
1434
+ logger.warn('opencode-unshare-refused', { port, sessionId, status: response.status });
1435
+ return false;
1436
+ }
1437
+ logger.info('opencode-share-removed', { port, sessionId });
1438
+ return true;
1439
+ }
1440
+ catch (error) {
1441
+ logger.warn('opencode-unshare-failed', {
1442
+ port,
1443
+ sessionId,
1444
+ error: error instanceof Error ? error.message : String(error),
1445
+ });
1446
+ return false;
1447
+ }
1448
+ }
1449
+ /**
1450
+ * The share URL opencode currently records against one session.
1451
+ *
1452
+ * A raw `GET /session/:id` rather than `fetchOpencodeSession()`, which projects
1453
+ * the body down to `{ id, title, directory, parentId }` and drops `share`
1454
+ * along with it.
1455
+ *
1456
+ * Read what this returns as **"a page was published for this session at some
1457
+ * point"**, never as "a page is up now": the field survives
1458
+ * {@link unshareOpencodeSession} and a server restart. See that function.
1459
+ *
1460
+ * @param port - The instance's server
1461
+ * @param sessionId - `ses_…`
1462
+ * @returns The recorded `https:` URL, or null when there is none
1463
+ */
1464
+ async function fetchOpencodeSessionShareUrl(port, sessionId) {
1465
+ const body = await requestJson(`${opencodeBaseUrl(port)}/session/${encodeURIComponent(sessionId)}`);
1466
+ return (0, opencode_share_1.readOpencodeShareUrl)(body);
1467
+ }