commandmate 0.28.0 → 0.29.1

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 (520) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +404 -397
  3. package/.next/app-path-routes-manifest.json +26 -25
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/prerender-manifest.json +12 -12
  6. package/.next/react-loadable-manifest.json +0 -6
  7. package/.next/required-server-files.json +1 -1
  8. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/update-check/route.js +1 -1
  11. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/auth/login/route.js +1 -1
  20. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/auth/logout/route.js +1 -1
  22. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/auth/status/route.js +1 -1
  24. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/capabilities/route.js +1 -1
  26. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/remote/pair/route.js +2 -0
  43. package/.next/server/app/api/remote/pair/route.js.nft.json +1 -0
  44. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -0
  45. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  55. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  72. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/route.js +1 -1
  149. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  151. package/.next/server/app/login/page.js +2 -2
  152. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  153. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  155. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  156. package/.next/server/app/page_client-reference-manifest.js +1 -1
  157. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  159. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  160. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  161. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  162. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  163. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  164. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  165. package/.next/server/app/worktrees/[id]/page.js +9 -9
  166. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  167. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  168. package/.next/server/app-paths-manifest.json +26 -25
  169. package/.next/server/chunks/1162.js +1 -1
  170. package/.next/server/chunks/2119.js +1 -1
  171. package/.next/server/chunks/2404.js +1 -1
  172. package/.next/server/chunks/2445.js +1 -1
  173. package/.next/server/chunks/2759.js +1 -1
  174. package/.next/server/chunks/3440.js +1 -1
  175. package/.next/server/chunks/3543.js +1 -1
  176. package/.next/server/chunks/3945.js +1 -1
  177. package/.next/server/chunks/4393.js +1 -1
  178. package/.next/server/chunks/6130.js +1 -1
  179. package/.next/server/chunks/880.js +6 -6
  180. package/.next/server/chunks/9123.js +2 -2
  181. package/.next/server/chunks/9938.js +1 -1
  182. package/.next/server/functions-config-manifest.json +3 -1
  183. package/.next/server/middleware-build-manifest.js +1 -1
  184. package/.next/server/middleware-manifest.json +5 -5
  185. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  186. package/.next/server/pages/500.html +1 -1
  187. package/.next/server/server-reference-manifest.json +1 -1
  188. package/.next/server/src/middleware.js +1 -1
  189. package/.next/server/src/middleware.js.map +1 -1
  190. package/.next/static/Dvfs4ZThl5vBhJGP-ZQuJ/_buildManifest.js +1 -0
  191. package/.next/static/chunks/5229-580b581fce5aeb52.js +1 -0
  192. package/.next/static/chunks/6381-9a929249196a0e77.js +1 -0
  193. package/.next/static/chunks/app/api/app/update/route-e3626364434d521b.js +1 -0
  194. package/.next/static/chunks/app/api/app/update-check/route-e3626364434d521b.js +1 -0
  195. package/.next/static/chunks/app/api/assistant/conversation/route-e3626364434d521b.js +1 -0
  196. package/.next/static/chunks/app/api/assistant/current-output/route-e3626364434d521b.js +1 -0
  197. package/.next/static/chunks/app/api/assistant/messages/route-e3626364434d521b.js +1 -0
  198. package/.next/static/chunks/app/api/assistant/session/route-e3626364434d521b.js +1 -0
  199. package/.next/static/chunks/app/api/assistant/start/route-e3626364434d521b.js +1 -0
  200. package/.next/static/chunks/app/api/assistant/terminal/route-e3626364434d521b.js +1 -0
  201. package/.next/static/chunks/app/api/assistant/tools/route-e3626364434d521b.js +1 -0
  202. package/.next/static/chunks/app/api/auth/login/route-e3626364434d521b.js +1 -0
  203. package/.next/static/chunks/app/api/auth/logout/route-e3626364434d521b.js +1 -0
  204. package/.next/static/chunks/app/api/auth/status/route-e3626364434d521b.js +1 -0
  205. package/.next/static/chunks/app/api/capabilities/route-e3626364434d521b.js +1 -0
  206. package/.next/static/chunks/app/api/daily-summary/route-e3626364434d521b.js +1 -0
  207. package/.next/static/chunks/app/api/daily-summary/status/route-e3626364434d521b.js +1 -0
  208. package/.next/static/chunks/app/api/external-apps/[id]/health/route-e3626364434d521b.js +1 -0
  209. package/.next/static/chunks/app/api/external-apps/[id]/route-e3626364434d521b.js +1 -0
  210. package/.next/static/chunks/app/api/external-apps/route-e3626364434d521b.js +1 -0
  211. package/.next/static/chunks/app/api/fs/browse/route-e3626364434d521b.js +1 -0
  212. package/.next/static/chunks/app/api/fs/recent-paths/route-e3626364434d521b.js +1 -0
  213. package/.next/static/chunks/app/api/hooks/agent-event/route-e3626364434d521b.js +1 -0
  214. package/.next/static/chunks/app/api/hooks/claude-done/route-e3626364434d521b.js +1 -0
  215. package/.next/static/chunks/app/api/hooks/permission-request/route-e3626364434d521b.js +1 -0
  216. package/.next/static/chunks/app/api/metrics/vibe/route-e3626364434d521b.js +1 -0
  217. package/.next/static/chunks/app/api/ollama/models/route-e3626364434d521b.js +1 -0
  218. package/.next/static/chunks/app/api/push/escalation/route-e3626364434d521b.js +1 -0
  219. package/.next/static/chunks/app/api/push/subscriptions/route-e3626364434d521b.js +1 -0
  220. package/.next/static/chunks/app/api/push/vapid/route-e3626364434d521b.js +1 -0
  221. package/.next/static/chunks/app/api/remote/pair/route-e3626364434d521b.js +1 -0
  222. package/.next/static/chunks/app/api/repositories/[id]/route-e3626364434d521b.js +1 -0
  223. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-e3626364434d521b.js +1 -0
  224. package/.next/static/chunks/app/api/repositories/[id]/todos/route-e3626364434d521b.js +1 -0
  225. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-e3626364434d521b.js +1 -0
  226. package/.next/static/chunks/app/api/repositories/clone/route-e3626364434d521b.js +1 -0
  227. package/.next/static/chunks/app/api/repositories/excluded/route-e3626364434d521b.js +1 -0
  228. package/.next/static/chunks/app/api/repositories/restore/route-e3626364434d521b.js +1 -0
  229. package/.next/static/chunks/app/api/repositories/route-e3626364434d521b.js +1 -0
  230. package/.next/static/chunks/app/api/repositories/scan/route-e3626364434d521b.js +1 -0
  231. package/.next/static/chunks/app/api/repositories/sync/route-e3626364434d521b.js +1 -0
  232. package/.next/static/chunks/app/api/repositories/validate-path/route-e3626364434d521b.js +1 -0
  233. package/.next/static/chunks/app/api/sidebar/group-order/route-e3626364434d521b.js +1 -0
  234. package/.next/static/chunks/app/api/skills/[id]/route-e3626364434d521b.js +1 -0
  235. package/.next/static/chunks/app/api/skills/installations/route-e3626364434d521b.js +1 -0
  236. package/.next/static/chunks/app/api/skills/operations/route-e3626364434d521b.js +1 -0
  237. package/.next/static/chunks/app/api/skills/reindex/route-e3626364434d521b.js +1 -0
  238. package/.next/static/chunks/app/api/skills/route-e3626364434d521b.js +1 -0
  239. package/.next/static/chunks/app/api/slash-commands/route-e3626364434d521b.js +1 -0
  240. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-e3626364434d521b.js +1 -0
  241. package/.next/static/chunks/app/api/tasks/[taskId]/route-e3626364434d521b.js +1 -0
  242. package/.next/static/chunks/app/api/templates/[id]/route-e3626364434d521b.js +1 -0
  243. package/.next/static/chunks/app/api/templates/route-e3626364434d521b.js +1 -0
  244. package/.next/static/chunks/app/api/todos/route-e3626364434d521b.js +1 -0
  245. package/.next/static/chunks/app/api/verification/runs/[runId]/route-e3626364434d521b.js +1 -0
  246. package/.next/static/chunks/app/api/verification/runs/route-e3626364434d521b.js +1 -0
  247. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-e3626364434d521b.js +1 -0
  248. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-e3626364434d521b.js +1 -0
  249. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-e3626364434d521b.js +1 -0
  250. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-e3626364434d521b.js +1 -0
  251. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-e3626364434d521b.js +1 -0
  252. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-e3626364434d521b.js +1 -0
  253. package/.next/static/chunks/app/api/worktrees/[id]/env/route-e3626364434d521b.js +1 -0
  254. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-e3626364434d521b.js +1 -0
  255. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-e3626364434d521b.js +1 -0
  256. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-e3626364434d521b.js +1 -0
  257. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-e3626364434d521b.js +1 -0
  258. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-e3626364434d521b.js +1 -0
  259. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-e3626364434d521b.js +1 -0
  260. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-e3626364434d521b.js +1 -0
  261. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-e3626364434d521b.js +1 -0
  262. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-e3626364434d521b.js +1 -0
  263. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-e3626364434d521b.js +1 -0
  264. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-e3626364434d521b.js +1 -0
  265. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-e3626364434d521b.js +1 -0
  266. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-e3626364434d521b.js +1 -0
  267. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-e3626364434d521b.js +1 -0
  268. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-e3626364434d521b.js +1 -0
  269. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-e3626364434d521b.js +1 -0
  270. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-e3626364434d521b.js +1 -0
  271. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-e3626364434d521b.js +1 -0
  272. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-e3626364434d521b.js +1 -0
  273. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-e3626364434d521b.js +1 -0
  274. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-e3626364434d521b.js +1 -0
  275. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-e3626364434d521b.js +1 -0
  276. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-e3626364434d521b.js +1 -0
  277. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-e3626364434d521b.js +1 -0
  278. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-e3626364434d521b.js +1 -0
  279. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-e3626364434d521b.js +1 -0
  280. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-e3626364434d521b.js +1 -0
  281. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-e3626364434d521b.js +1 -0
  282. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-e3626364434d521b.js +1 -0
  283. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-e3626364434d521b.js +1 -0
  284. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-e3626364434d521b.js +1 -0
  285. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-e3626364434d521b.js +1 -0
  286. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-e3626364434d521b.js +1 -0
  287. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-e3626364434d521b.js +1 -0
  288. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-e3626364434d521b.js +1 -0
  289. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-e3626364434d521b.js +1 -0
  290. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-e3626364434d521b.js +1 -0
  291. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-e3626364434d521b.js +1 -0
  292. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-e3626364434d521b.js +1 -0
  293. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-e3626364434d521b.js +1 -0
  294. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-e3626364434d521b.js +1 -0
  295. package/.next/static/chunks/app/api/worktrees/[id]/route-e3626364434d521b.js +1 -0
  296. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-e3626364434d521b.js +1 -0
  297. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-e3626364434d521b.js +1 -0
  298. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-e3626364434d521b.js +1 -0
  299. package/.next/static/chunks/app/api/worktrees/[id]/search/route-e3626364434d521b.js +1 -0
  300. package/.next/static/chunks/app/api/worktrees/[id]/send/route-e3626364434d521b.js +1 -0
  301. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-e3626364434d521b.js +1 -0
  302. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-e3626364434d521b.js +1 -0
  303. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-e3626364434d521b.js +1 -0
  304. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-e3626364434d521b.js +1 -0
  305. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-e3626364434d521b.js +1 -0
  306. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-e3626364434d521b.js +1 -0
  307. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-e3626364434d521b.js +1 -0
  308. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-e3626364434d521b.js +1 -0
  309. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-e3626364434d521b.js +1 -0
  310. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-e3626364434d521b.js +1 -0
  311. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-e3626364434d521b.js +1 -0
  312. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-e3626364434d521b.js +1 -0
  313. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-e3626364434d521b.js +1 -0
  314. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-e3626364434d521b.js +1 -0
  315. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-e3626364434d521b.js +1 -0
  316. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-e3626364434d521b.js +1 -0
  317. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-e3626364434d521b.js +1 -0
  318. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-e3626364434d521b.js +1 -0
  319. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-e3626364434d521b.js +1 -0
  320. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-e3626364434d521b.js +1 -0
  321. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-e3626364434d521b.js +1 -0
  322. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-e3626364434d521b.js +1 -0
  323. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-e3626364434d521b.js +1 -0
  324. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-e3626364434d521b.js +1 -0
  325. package/.next/static/chunks/app/api/worktrees/route-e3626364434d521b.js +1 -0
  326. package/.next/static/chunks/app/login/page-03659dded846ef1d.js +1 -0
  327. package/.next/static/chunks/app/manifest.webmanifest/route-e3626364434d521b.js +1 -0
  328. package/.next/static/chunks/app/proxy/[...path]/route-e3626364434d521b.js +1 -0
  329. package/.next/static/chunks/app/worktrees/[id]/layout-e3626364434d521b.js +1 -0
  330. package/.next/static/chunks/app/worktrees/[id]/page-817378dd7c580774.js +1 -0
  331. package/.next/static/chunks/webpack-7e79064bfce988d7.js +1 -0
  332. package/.next/static/css/6266bde3bce465a2.css +1 -0
  333. package/.next/trace +13 -13
  334. package/.next/types/app/api/remote/pair/route.ts +347 -0
  335. package/.next/types/routes.d.ts +2 -1
  336. package/.next/types/validator.ts +9 -0
  337. package/README.md +15 -3
  338. package/dist/cli/commands/remote.d.ts +248 -0
  339. package/dist/cli/commands/remote.d.ts.map +1 -0
  340. package/dist/cli/commands/remote.js +849 -0
  341. package/dist/cli/config/security-messages.d.ts +25 -0
  342. package/dist/cli/config/security-messages.d.ts.map +1 -1
  343. package/dist/cli/config/security-messages.js +43 -1
  344. package/dist/cli/program.d.ts.map +1 -1
  345. package/dist/cli/program.js +6 -0
  346. package/dist/cli/types/index.d.ts +20 -0
  347. package/dist/cli/types/index.d.ts.map +1 -1
  348. package/dist/cli/utils/qr-terminal.d.ts +54 -0
  349. package/dist/cli/utils/qr-terminal.d.ts.map +1 -0
  350. package/dist/cli/utils/qr-terminal.js +181 -0
  351. package/dist/cli/utils/remote-state.d.ts +123 -0
  352. package/dist/cli/utils/remote-state.d.ts.map +1 -0
  353. package/dist/cli/utils/remote-state.js +193 -0
  354. package/dist/config/auth-config.d.ts +1 -1
  355. package/dist/config/auth-config.d.ts.map +1 -1
  356. package/dist/config/auth-config.js +5 -0
  357. package/dist/lib/remote/cloudflare.d.ts +285 -0
  358. package/dist/lib/remote/cloudflare.d.ts.map +1 -0
  359. package/dist/lib/remote/cloudflare.js +619 -0
  360. package/dist/lib/remote/index.d.ts +17 -0
  361. package/dist/lib/remote/index.d.ts.map +1 -0
  362. package/dist/lib/remote/index.js +64 -0
  363. package/dist/lib/remote/provider-registry.d.ts +29 -0
  364. package/dist/lib/remote/provider-registry.d.ts.map +1 -0
  365. package/dist/lib/remote/provider-registry.js +73 -0
  366. package/dist/lib/remote/tailscale.d.ts +268 -0
  367. package/dist/lib/remote/tailscale.d.ts.map +1 -0
  368. package/dist/lib/remote/tailscale.js +546 -0
  369. package/dist/lib/remote/types.d.ts +127 -0
  370. package/dist/lib/remote/types.d.ts.map +1 -0
  371. package/dist/lib/remote/types.js +53 -0
  372. package/dist/lib/security/pairing-code.d.ts +182 -0
  373. package/dist/lib/security/pairing-code.d.ts.map +1 -0
  374. package/dist/lib/security/pairing-code.js +265 -0
  375. package/dist/server/src/config/auth-config.js +5 -0
  376. package/package.json +2 -1
  377. package/.next/static/0GHE2JGlFzqvSBZAcBFSt/_buildManifest.js +0 -1
  378. package/.next/static/chunks/5229-1f5f19740a8d6c11.js +0 -1
  379. package/.next/static/chunks/6271.295ced91b6335f18.js +0 -1
  380. package/.next/static/chunks/6381-d921ab728eda1191.js +0 -1
  381. package/.next/static/chunks/app/api/app/update/route-9247d6b9d647f750.js +0 -1
  382. package/.next/static/chunks/app/api/app/update-check/route-9247d6b9d647f750.js +0 -1
  383. package/.next/static/chunks/app/api/assistant/conversation/route-9247d6b9d647f750.js +0 -1
  384. package/.next/static/chunks/app/api/assistant/current-output/route-9247d6b9d647f750.js +0 -1
  385. package/.next/static/chunks/app/api/assistant/messages/route-9247d6b9d647f750.js +0 -1
  386. package/.next/static/chunks/app/api/assistant/session/route-9247d6b9d647f750.js +0 -1
  387. package/.next/static/chunks/app/api/assistant/start/route-9247d6b9d647f750.js +0 -1
  388. package/.next/static/chunks/app/api/assistant/terminal/route-9247d6b9d647f750.js +0 -1
  389. package/.next/static/chunks/app/api/assistant/tools/route-9247d6b9d647f750.js +0 -1
  390. package/.next/static/chunks/app/api/auth/login/route-9247d6b9d647f750.js +0 -1
  391. package/.next/static/chunks/app/api/auth/logout/route-9247d6b9d647f750.js +0 -1
  392. package/.next/static/chunks/app/api/auth/status/route-9247d6b9d647f750.js +0 -1
  393. package/.next/static/chunks/app/api/capabilities/route-9247d6b9d647f750.js +0 -1
  394. package/.next/static/chunks/app/api/daily-summary/route-9247d6b9d647f750.js +0 -1
  395. package/.next/static/chunks/app/api/daily-summary/status/route-9247d6b9d647f750.js +0 -1
  396. package/.next/static/chunks/app/api/external-apps/[id]/health/route-9247d6b9d647f750.js +0 -1
  397. package/.next/static/chunks/app/api/external-apps/[id]/route-9247d6b9d647f750.js +0 -1
  398. package/.next/static/chunks/app/api/external-apps/route-9247d6b9d647f750.js +0 -1
  399. package/.next/static/chunks/app/api/fs/browse/route-9247d6b9d647f750.js +0 -1
  400. package/.next/static/chunks/app/api/fs/recent-paths/route-9247d6b9d647f750.js +0 -1
  401. package/.next/static/chunks/app/api/hooks/agent-event/route-9247d6b9d647f750.js +0 -1
  402. package/.next/static/chunks/app/api/hooks/claude-done/route-9247d6b9d647f750.js +0 -1
  403. package/.next/static/chunks/app/api/hooks/permission-request/route-9247d6b9d647f750.js +0 -1
  404. package/.next/static/chunks/app/api/metrics/vibe/route-9247d6b9d647f750.js +0 -1
  405. package/.next/static/chunks/app/api/ollama/models/route-9247d6b9d647f750.js +0 -1
  406. package/.next/static/chunks/app/api/push/escalation/route-9247d6b9d647f750.js +0 -1
  407. package/.next/static/chunks/app/api/push/subscriptions/route-9247d6b9d647f750.js +0 -1
  408. package/.next/static/chunks/app/api/push/vapid/route-9247d6b9d647f750.js +0 -1
  409. package/.next/static/chunks/app/api/repositories/[id]/route-9247d6b9d647f750.js +0 -1
  410. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-9247d6b9d647f750.js +0 -1
  411. package/.next/static/chunks/app/api/repositories/[id]/todos/route-9247d6b9d647f750.js +0 -1
  412. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-9247d6b9d647f750.js +0 -1
  413. package/.next/static/chunks/app/api/repositories/clone/route-9247d6b9d647f750.js +0 -1
  414. package/.next/static/chunks/app/api/repositories/excluded/route-9247d6b9d647f750.js +0 -1
  415. package/.next/static/chunks/app/api/repositories/restore/route-9247d6b9d647f750.js +0 -1
  416. package/.next/static/chunks/app/api/repositories/route-9247d6b9d647f750.js +0 -1
  417. package/.next/static/chunks/app/api/repositories/scan/route-9247d6b9d647f750.js +0 -1
  418. package/.next/static/chunks/app/api/repositories/sync/route-9247d6b9d647f750.js +0 -1
  419. package/.next/static/chunks/app/api/repositories/validate-path/route-9247d6b9d647f750.js +0 -1
  420. package/.next/static/chunks/app/api/sidebar/group-order/route-9247d6b9d647f750.js +0 -1
  421. package/.next/static/chunks/app/api/skills/[id]/route-9247d6b9d647f750.js +0 -1
  422. package/.next/static/chunks/app/api/skills/installations/route-9247d6b9d647f750.js +0 -1
  423. package/.next/static/chunks/app/api/skills/operations/route-9247d6b9d647f750.js +0 -1
  424. package/.next/static/chunks/app/api/skills/reindex/route-9247d6b9d647f750.js +0 -1
  425. package/.next/static/chunks/app/api/skills/route-9247d6b9d647f750.js +0 -1
  426. package/.next/static/chunks/app/api/slash-commands/route-9247d6b9d647f750.js +0 -1
  427. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-9247d6b9d647f750.js +0 -1
  428. package/.next/static/chunks/app/api/tasks/[taskId]/route-9247d6b9d647f750.js +0 -1
  429. package/.next/static/chunks/app/api/templates/[id]/route-9247d6b9d647f750.js +0 -1
  430. package/.next/static/chunks/app/api/templates/route-9247d6b9d647f750.js +0 -1
  431. package/.next/static/chunks/app/api/todos/route-9247d6b9d647f750.js +0 -1
  432. package/.next/static/chunks/app/api/verification/runs/[runId]/route-9247d6b9d647f750.js +0 -1
  433. package/.next/static/chunks/app/api/verification/runs/route-9247d6b9d647f750.js +0 -1
  434. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-9247d6b9d647f750.js +0 -1
  435. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-9247d6b9d647f750.js +0 -1
  436. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-9247d6b9d647f750.js +0 -1
  437. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-9247d6b9d647f750.js +0 -1
  438. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-9247d6b9d647f750.js +0 -1
  439. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-9247d6b9d647f750.js +0 -1
  440. package/.next/static/chunks/app/api/worktrees/[id]/env/route-9247d6b9d647f750.js +0 -1
  441. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-9247d6b9d647f750.js +0 -1
  442. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-9247d6b9d647f750.js +0 -1
  443. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-9247d6b9d647f750.js +0 -1
  444. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-9247d6b9d647f750.js +0 -1
  445. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-9247d6b9d647f750.js +0 -1
  446. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-9247d6b9d647f750.js +0 -1
  447. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-9247d6b9d647f750.js +0 -1
  448. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-9247d6b9d647f750.js +0 -1
  449. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-9247d6b9d647f750.js +0 -1
  450. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-9247d6b9d647f750.js +0 -1
  451. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-9247d6b9d647f750.js +0 -1
  452. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-9247d6b9d647f750.js +0 -1
  453. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-9247d6b9d647f750.js +0 -1
  454. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-9247d6b9d647f750.js +0 -1
  455. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-9247d6b9d647f750.js +0 -1
  456. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-9247d6b9d647f750.js +0 -1
  457. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-9247d6b9d647f750.js +0 -1
  458. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-9247d6b9d647f750.js +0 -1
  459. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-9247d6b9d647f750.js +0 -1
  460. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-9247d6b9d647f750.js +0 -1
  461. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-9247d6b9d647f750.js +0 -1
  462. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-9247d6b9d647f750.js +0 -1
  463. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-9247d6b9d647f750.js +0 -1
  464. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-9247d6b9d647f750.js +0 -1
  465. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-9247d6b9d647f750.js +0 -1
  466. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-9247d6b9d647f750.js +0 -1
  467. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-9247d6b9d647f750.js +0 -1
  468. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-9247d6b9d647f750.js +0 -1
  469. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-9247d6b9d647f750.js +0 -1
  470. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-9247d6b9d647f750.js +0 -1
  471. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-9247d6b9d647f750.js +0 -1
  472. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-9247d6b9d647f750.js +0 -1
  473. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-9247d6b9d647f750.js +0 -1
  474. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-9247d6b9d647f750.js +0 -1
  475. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-9247d6b9d647f750.js +0 -1
  476. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-9247d6b9d647f750.js +0 -1
  477. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-9247d6b9d647f750.js +0 -1
  478. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-9247d6b9d647f750.js +0 -1
  479. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-9247d6b9d647f750.js +0 -1
  480. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-9247d6b9d647f750.js +0 -1
  481. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-9247d6b9d647f750.js +0 -1
  482. package/.next/static/chunks/app/api/worktrees/[id]/route-9247d6b9d647f750.js +0 -1
  483. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-9247d6b9d647f750.js +0 -1
  484. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-9247d6b9d647f750.js +0 -1
  485. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-9247d6b9d647f750.js +0 -1
  486. package/.next/static/chunks/app/api/worktrees/[id]/search/route-9247d6b9d647f750.js +0 -1
  487. package/.next/static/chunks/app/api/worktrees/[id]/send/route-9247d6b9d647f750.js +0 -1
  488. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-9247d6b9d647f750.js +0 -1
  489. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-9247d6b9d647f750.js +0 -1
  490. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-9247d6b9d647f750.js +0 -1
  491. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-9247d6b9d647f750.js +0 -1
  492. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-9247d6b9d647f750.js +0 -1
  493. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-9247d6b9d647f750.js +0 -1
  494. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-9247d6b9d647f750.js +0 -1
  495. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-9247d6b9d647f750.js +0 -1
  496. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-9247d6b9d647f750.js +0 -1
  497. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-9247d6b9d647f750.js +0 -1
  498. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-9247d6b9d647f750.js +0 -1
  499. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-9247d6b9d647f750.js +0 -1
  500. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-9247d6b9d647f750.js +0 -1
  501. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-9247d6b9d647f750.js +0 -1
  502. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-9247d6b9d647f750.js +0 -1
  503. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-9247d6b9d647f750.js +0 -1
  504. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-9247d6b9d647f750.js +0 -1
  505. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-9247d6b9d647f750.js +0 -1
  506. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-9247d6b9d647f750.js +0 -1
  507. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-9247d6b9d647f750.js +0 -1
  508. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-9247d6b9d647f750.js +0 -1
  509. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-9247d6b9d647f750.js +0 -1
  510. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-9247d6b9d647f750.js +0 -1
  511. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-9247d6b9d647f750.js +0 -1
  512. package/.next/static/chunks/app/api/worktrees/route-9247d6b9d647f750.js +0 -1
  513. package/.next/static/chunks/app/login/page-adc51f0f7cbb7ac6.js +0 -1
  514. package/.next/static/chunks/app/manifest.webmanifest/route-9247d6b9d647f750.js +0 -1
  515. package/.next/static/chunks/app/proxy/[...path]/route-9247d6b9d647f750.js +0 -1
  516. package/.next/static/chunks/app/worktrees/[id]/layout-9247d6b9d647f750.js +0 -1
  517. package/.next/static/chunks/app/worktrees/[id]/page-27b7cb2e77099eec.js +0 -1
  518. package/.next/static/chunks/webpack-6a9668cf54a26eba.js +0 -1
  519. package/.next/static/css/98722bc4152cedcc.css +0 -1
  520. /package/.next/static/{0GHE2JGlFzqvSBZAcBFSt → Dvfs4ZThl5vBhJGP-ZQuJ}/_ssgManifest.js +0 -0
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ /**
3
+ * Provider abstraction for `commandmate remote` (Issue #1937, R1).
4
+ *
5
+ * The shapes here are §6.1 of `docs/design/remote-qr-pairing-1937.md` verbatim.
6
+ * Two of them carry a structural guarantee rather than a convention, and both
7
+ * exist because a Provider can destroy configuration the user created and that
8
+ * CommandMate has no way to restore (§6.3):
9
+ *
10
+ * 1. `RemoteProvider` has no `reset()` / `cleanupAll()`. `stop()` takes a
11
+ * `RemoteHandle` and nothing else, so "read the Provider's whole config and
12
+ * tear it down" is not expressible in this type. A pinning test asserts the
13
+ * member list stays exactly `id` / `detect` / `start` / `stop`.
14
+ * 2. `start()` must return `preexisting`. `stop()` reverts only what is in
15
+ * `owned` and NOT in `preexisting`; anything in both is skipped and reported
16
+ * in `StopOutcome.skipped` so a human can see what was left alone.
17
+ *
18
+ * Choosing between Providers is deliberately NOT here. "Tailscale first, and do
19
+ * not silently fall back to a public tunnel" is a rule about selection, not a
20
+ * property of either Provider, so it lives in the orchestrator that will own
21
+ * `src/cli/commands/remote.ts` (R9). See `provider-registry.ts`.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.isPreexistingSnapshot = isPreexistingSnapshot;
25
+ exports.planStop = planStop;
26
+ /** Narrows `RemoteHandle.preexisting` to the shape the shared skip rule reads. */
27
+ function isPreexistingSnapshot(value) {
28
+ if (typeof value !== 'object' || value === null)
29
+ return false;
30
+ const keys = value.keys;
31
+ return Array.isArray(keys) && keys.every((key) => typeof key === 'string');
32
+ }
33
+ /**
34
+ * Splits a handle's owned revert entries into "safe to undo" and "leave alone".
35
+ *
36
+ * This is the single implementation of §6.3-2. Every Provider's `stop()` routes
37
+ * through it so the rule cannot drift between Providers, and so the rule can be
38
+ * tested once instead of once per Provider.
39
+ */
40
+ function planStop(handle) {
41
+ const owned = handle.owned.revert ?? {};
42
+ const protectedKeys = new Set(isPreexistingSnapshot(handle.preexisting) ? handle.preexisting.keys : []);
43
+ const revert = {};
44
+ const skipped = [];
45
+ for (const key of Object.keys(owned)) {
46
+ if (protectedKeys.has(key)) {
47
+ skipped.push(key);
48
+ continue;
49
+ }
50
+ revert[key] = owned[key];
51
+ }
52
+ return { revert, skipped: skipped.sort() };
53
+ }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Pairing code lifecycle for `commandmate remote` (Issue #1937, R5)
3
+ *
4
+ * Design: docs/design/remote-qr-pairing-1937.md §7
5
+ *
6
+ * CONSTRAINTS:
7
+ * - NODE RUNTIME ONLY. This module touches `fs` and `crypto`; the Edge Runtime
8
+ * (`src/middleware.ts`) must never import it. Pairing is an excluded path, so
9
+ * middleware never needs to.
10
+ * - No Next.js imports, so `src/cli/**` can pull it in for `commandmate remote`
11
+ * under `tsconfig.cli.json` (which declares `"paths": {}` — relative imports
12
+ * only, never `@/...`).
13
+ *
14
+ * WHY A FILE AND NOT AN ENVIRONMENT VARIABLE (§7.2)
15
+ * -------------------------------------------------
16
+ * The cookie has to carry the *plaintext* long-lived token, so the server must
17
+ * know it. The obvious route — put it in the server's startup env — is rejected:
18
+ * `src/lib/tmux/**` passes no `env:` to the panes it spawns, so a pane inherits
19
+ * the server's environment wholesale, and `sanitizeEnvForChildProcess()` is
20
+ * called in only two places that an agent pane does not go through. An env var
21
+ * would therefore be readable by the very Claude / Codex / OpenCode processes
22
+ * CommandMate is driving.
23
+ *
24
+ * So the secret lands in one 0600 handoff file and only its *path* travels in
25
+ * `CM_REMOTE_PAIRING_FILE` (a path is not a secret). Two further consequences:
26
+ *
27
+ * - The consumed flag is THE ABSENCE OF THE FILE. A module-level variable
28
+ * cannot work here: `server.ts` and the Next route handler bundle are
29
+ * separate module instances, so state written by one is invisible to the
30
+ * other.
31
+ * - Deleting the file destroys the plaintext token at the moment of pairing,
32
+ * shrinking its window on disk to "remote start → first pairing".
33
+ */
34
+ /** Env var carrying the handoff file PATH (never the secret itself). */
35
+ export declare const PAIRING_FILE_ENV_KEY = "CM_REMOTE_PAIRING_FILE";
36
+ /** File name inside the config directory (`~/.commandmate` for global installs). */
37
+ export declare const PAIRING_FILE_NAME = "remote-pairing.json";
38
+ /** Owner read/write only. Asserted by tests, not merely intended. */
39
+ export declare const PAIRING_FILE_MODE = 384;
40
+ /**
41
+ * Crockford Base32 (https://www.crockford.com/base32.html).
42
+ * `I`, `L`, `O` and `U` are absent so a transcribed code cannot be ambiguous.
43
+ */
44
+ export declare const CROCKFORD_BASE32_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
45
+ /** Bits of entropy carried by a pairing code. */
46
+ export declare const PAIRING_CODE_BITS = 128;
47
+ /** ceil(128 / 5) — the encoded length of PAIRING_CODE_BITS. */
48
+ export declare const PAIRING_CODE_LENGTH = 26;
49
+ /** Default time-to-live for one pairing code (§7.4). */
50
+ export declare const DEFAULT_PAIRING_TTL_MS: number;
51
+ /**
52
+ * Input length cap for `POST /api/remote/pair`, copied from `/api/auth/login`'s
53
+ * 256-char cap so an oversized body cannot be used to burn CPU on hashing.
54
+ */
55
+ export declare const MAX_PAIRING_CODE_LENGTH = 256;
56
+ /** On-disk shape of the handoff file. */
57
+ export interface PairingHandoff {
58
+ /** SHA-256 hex of the canonical pairing code. The code itself is never stored. */
59
+ pairingHash: string;
60
+ /** Epoch ms after which the code is dead. */
61
+ expiresAt: number;
62
+ /** Plaintext long-lived token that becomes the auth cookie value. */
63
+ sessionToken: string;
64
+ }
65
+ /** What `createPairingHandoff()` hands back to the caller (the `remote` command). */
66
+ export interface CreatedPairing {
67
+ /**
68
+ * Plaintext pairing code. NEVER persisted — the caller renders it as a QR
69
+ * code and drops it. Re-displaying it means running `remote` again.
70
+ */
71
+ code: string;
72
+ /** Plaintext long-lived token (also written to the handoff file). */
73
+ sessionToken: string;
74
+ expiresAt: number;
75
+ filePath: string;
76
+ }
77
+ export interface CreatePairingHandoffOptions {
78
+ /** Defaults to `<configDir>/remote-pairing.json`. */
79
+ filePath?: string;
80
+ /** Defaults to {@link DEFAULT_PAIRING_TTL_MS}. */
81
+ ttlMs?: number;
82
+ /** Defaults to a fresh `generateToken()`. */
83
+ sessionToken?: string;
84
+ /** Injectable clock for tests. */
85
+ now?: number;
86
+ }
87
+ /**
88
+ * Encode bytes as Crockford Base32, MSB first, no padding character.
89
+ *
90
+ * 16 bytes (128 bits) produce 26 characters: 25 characters consume 125 bits and
91
+ * the remaining 3 bits are left-shifted into the 26th.
92
+ *
93
+ * @param bytes - Raw bytes to encode
94
+ * @returns Crockford Base32 string
95
+ */
96
+ export declare function encodeCrockfordBase32(bytes: Buffer): string;
97
+ /**
98
+ * Canonicalize a transcribed pairing code.
99
+ *
100
+ * This is the whole reason Crockford Base32 was picked over RFC 4648 Base32:
101
+ * `i`/`l` are accepted as `1`, `o` as `0`, case is irrelevant, and grouping
102
+ * spaces or hyphens a human inserted are dropped. `generatePairingCode()`
103
+ * already emits the canonical form, so `normalize(generate()) === generate()`
104
+ * and the QR path is unaffected.
105
+ *
106
+ * @param code - Raw user/QR supplied code
107
+ * @returns Canonical uppercase form used for hashing
108
+ */
109
+ export declare function normalizePairingCode(code: string): string;
110
+ /**
111
+ * Generate a pairing code carrying {@link PAIRING_CODE_BITS} bits of entropy.
112
+ *
113
+ * Reuses `generateToken()` (32 random bytes as hex) rather than calling
114
+ * `randomBytes` again, and keeps the leading 128 bits: at a 10-minute TTL,
115
+ * single use and a rate limit, 128 bits is already extravagant, and a 26-char
116
+ * code keeps the QR small enough to scan from a laptop screen.
117
+ *
118
+ * @returns 26-character Crockford Base32 code
119
+ */
120
+ export declare function generatePairingCode(): string;
121
+ /**
122
+ * Absolute path of the default handoff file.
123
+ *
124
+ * @returns `<configDir>/remote-pairing.json`
125
+ */
126
+ export declare function getDefaultPairingFilePath(): string;
127
+ /**
128
+ * Read the handoff file path out of the environment.
129
+ *
130
+ * @returns The path, or null when `remote` is not running (route answers 404)
131
+ */
132
+ export declare function getPairingFilePathFromEnv(): string | null;
133
+ /**
134
+ * Write the handoff file with mode 0600.
135
+ *
136
+ * An existing file is unlinked first: `writeFileSync`'s `mode` is only honoured
137
+ * when the file is created, so writing over a stale world-readable file would
138
+ * silently keep the old permissions. `chmodSync` afterwards closes the umask
139
+ * gap for good measure.
140
+ *
141
+ * @param filePath - Absolute path of the handoff file
142
+ * @param handoff - Hash, expiry and plaintext session token
143
+ */
144
+ export declare function writePairingHandoff(filePath: string, handoff: PairingHandoff): void;
145
+ /**
146
+ * Mint a pairing code plus its handoff file in one step.
147
+ *
148
+ * @param options - Overrides for path, TTL, session token and clock
149
+ * @returns The plaintext code and token, which the caller must not persist
150
+ */
151
+ export declare function createPairingHandoff(options?: CreatePairingHandoffOptions): CreatedPairing;
152
+ /**
153
+ * Read and validate the handoff file.
154
+ *
155
+ * Missing and malformed are deliberately the same answer: the caller turns both
156
+ * into 410 Gone, and "already consumed" arrives here as ENOENT.
157
+ *
158
+ * @param filePath - Absolute path of the handoff file
159
+ * @returns The handoff, or null when it is absent or unusable
160
+ */
161
+ export declare function readPairingHandoff(filePath: string): PairingHandoff | null;
162
+ /**
163
+ * Delete the handoff file. Idempotent — a missing file is success.
164
+ *
165
+ * @param filePath - Absolute path of the handoff file
166
+ */
167
+ export declare function consumePairingHandoff(filePath: string): void;
168
+ /**
169
+ * @param handoff - Handoff read from disk
170
+ * @param now - Epoch ms, injectable for tests
171
+ * @returns true when the pairing window has closed
172
+ */
173
+ export declare function isPairingExpired(handoff: PairingHandoff, now?: number): boolean;
174
+ /**
175
+ * Timing-safe comparison of a supplied code against the stored hash (S001).
176
+ *
177
+ * @param code - Code as supplied by the client
178
+ * @param pairingHash - SHA-256 hex from the handoff file
179
+ * @returns true when the code matches
180
+ */
181
+ export declare function verifyPairingCode(code: string, pairingHash: string): boolean;
182
+ //# sourceMappingURL=pairing-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing-code.d.ts","sourceRoot":"","sources":["../../../src/lib/security/pairing-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAUH,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAE7D,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,MAAQ,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,qCAAqC,CAAC;AAE5E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,wDAAwD;AACxD,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,2BAA2B;IAC1C,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmB3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAGzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CASnF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,2BAAgC,GAAG,cAAc,CAU9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CA0B1E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAM5D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAE3F;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAgB5E"}
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ /**
3
+ * Pairing code lifecycle for `commandmate remote` (Issue #1937, R5)
4
+ *
5
+ * Design: docs/design/remote-qr-pairing-1937.md §7
6
+ *
7
+ * CONSTRAINTS:
8
+ * - NODE RUNTIME ONLY. This module touches `fs` and `crypto`; the Edge Runtime
9
+ * (`src/middleware.ts`) must never import it. Pairing is an excluded path, so
10
+ * middleware never needs to.
11
+ * - No Next.js imports, so `src/cli/**` can pull it in for `commandmate remote`
12
+ * under `tsconfig.cli.json` (which declares `"paths": {}` — relative imports
13
+ * only, never `@/...`).
14
+ *
15
+ * WHY A FILE AND NOT AN ENVIRONMENT VARIABLE (§7.2)
16
+ * -------------------------------------------------
17
+ * The cookie has to carry the *plaintext* long-lived token, so the server must
18
+ * know it. The obvious route — put it in the server's startup env — is rejected:
19
+ * `src/lib/tmux/**` passes no `env:` to the panes it spawns, so a pane inherits
20
+ * the server's environment wholesale, and `sanitizeEnvForChildProcess()` is
21
+ * called in only two places that an agent pane does not go through. An env var
22
+ * would therefore be readable by the very Claude / Codex / OpenCode processes
23
+ * CommandMate is driving.
24
+ *
25
+ * So the secret lands in one 0600 handoff file and only its *path* travels in
26
+ * `CM_REMOTE_PAIRING_FILE` (a path is not a secret). Two further consequences:
27
+ *
28
+ * - The consumed flag is THE ABSENCE OF THE FILE. A module-level variable
29
+ * cannot work here: `server.ts` and the Next route handler bundle are
30
+ * separate module instances, so state written by one is invisible to the
31
+ * other.
32
+ * - Deleting the file destroys the plaintext token at the moment of pairing,
33
+ * shrinking its window on disk to "remote start → first pairing".
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MAX_PAIRING_CODE_LENGTH = exports.DEFAULT_PAIRING_TTL_MS = exports.PAIRING_CODE_LENGTH = exports.PAIRING_CODE_BITS = exports.CROCKFORD_BASE32_ALPHABET = exports.PAIRING_FILE_MODE = exports.PAIRING_FILE_NAME = exports.PAIRING_FILE_ENV_KEY = void 0;
37
+ exports.encodeCrockfordBase32 = encodeCrockfordBase32;
38
+ exports.normalizePairingCode = normalizePairingCode;
39
+ exports.generatePairingCode = generatePairingCode;
40
+ exports.getDefaultPairingFilePath = getDefaultPairingFilePath;
41
+ exports.getPairingFilePathFromEnv = getPairingFilePathFromEnv;
42
+ exports.writePairingHandoff = writePairingHandoff;
43
+ exports.createPairingHandoff = createPairingHandoff;
44
+ exports.readPairingHandoff = readPairingHandoff;
45
+ exports.consumePairingHandoff = consumePairingHandoff;
46
+ exports.isPairingExpired = isPairingExpired;
47
+ exports.verifyPairingCode = verifyPairingCode;
48
+ const crypto_1 = require("crypto");
49
+ const fs_1 = require("fs");
50
+ const path_1 = require("path");
51
+ const auth_config_1 = require("../../config/auth-config");
52
+ const install_context_1 = require("../../cli/utils/install-context");
53
+ const auth_1 = require("./auth");
54
+ /** Env var carrying the handoff file PATH (never the secret itself). */
55
+ exports.PAIRING_FILE_ENV_KEY = 'CM_REMOTE_PAIRING_FILE';
56
+ /** File name inside the config directory (`~/.commandmate` for global installs). */
57
+ exports.PAIRING_FILE_NAME = 'remote-pairing.json';
58
+ /** Owner read/write only. Asserted by tests, not merely intended. */
59
+ exports.PAIRING_FILE_MODE = 0o600;
60
+ /**
61
+ * Crockford Base32 (https://www.crockford.com/base32.html).
62
+ * `I`, `L`, `O` and `U` are absent so a transcribed code cannot be ambiguous.
63
+ */
64
+ exports.CROCKFORD_BASE32_ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
65
+ /** Bits of entropy carried by a pairing code. */
66
+ exports.PAIRING_CODE_BITS = 128;
67
+ /** ceil(128 / 5) — the encoded length of PAIRING_CODE_BITS. */
68
+ exports.PAIRING_CODE_LENGTH = 26;
69
+ /** Default time-to-live for one pairing code (§7.4). */
70
+ exports.DEFAULT_PAIRING_TTL_MS = 10 * 60 * 1000;
71
+ /**
72
+ * Input length cap for `POST /api/remote/pair`, copied from `/api/auth/login`'s
73
+ * 256-char cap so an oversized body cannot be used to burn CPU on hashing.
74
+ */
75
+ exports.MAX_PAIRING_CODE_LENGTH = 256;
76
+ /**
77
+ * Encode bytes as Crockford Base32, MSB first, no padding character.
78
+ *
79
+ * 16 bytes (128 bits) produce 26 characters: 25 characters consume 125 bits and
80
+ * the remaining 3 bits are left-shifted into the 26th.
81
+ *
82
+ * @param bytes - Raw bytes to encode
83
+ * @returns Crockford Base32 string
84
+ */
85
+ function encodeCrockfordBase32(bytes) {
86
+ let out = '';
87
+ let buffer = 0;
88
+ let bits = 0;
89
+ for (const byte of bytes) {
90
+ buffer = (buffer << 8) | byte;
91
+ bits += 8;
92
+ while (bits >= 5) {
93
+ out += exports.CROCKFORD_BASE32_ALPHABET[(buffer >>> (bits - 5)) & 0b11111];
94
+ bits -= 5;
95
+ }
96
+ }
97
+ if (bits > 0) {
98
+ out += exports.CROCKFORD_BASE32_ALPHABET[(buffer << (5 - bits)) & 0b11111];
99
+ }
100
+ return out;
101
+ }
102
+ /**
103
+ * Canonicalize a transcribed pairing code.
104
+ *
105
+ * This is the whole reason Crockford Base32 was picked over RFC 4648 Base32:
106
+ * `i`/`l` are accepted as `1`, `o` as `0`, case is irrelevant, and grouping
107
+ * spaces or hyphens a human inserted are dropped. `generatePairingCode()`
108
+ * already emits the canonical form, so `normalize(generate()) === generate()`
109
+ * and the QR path is unaffected.
110
+ *
111
+ * @param code - Raw user/QR supplied code
112
+ * @returns Canonical uppercase form used for hashing
113
+ */
114
+ function normalizePairingCode(code) {
115
+ return code
116
+ .replace(/[\s-]/g, '')
117
+ .toUpperCase()
118
+ .replace(/[ILO]/g, (character) => (character === 'O' ? '0' : '1'));
119
+ }
120
+ /**
121
+ * Generate a pairing code carrying {@link PAIRING_CODE_BITS} bits of entropy.
122
+ *
123
+ * Reuses `generateToken()` (32 random bytes as hex) rather than calling
124
+ * `randomBytes` again, and keeps the leading 128 bits: at a 10-minute TTL,
125
+ * single use and a rate limit, 128 bits is already extravagant, and a 26-char
126
+ * code keeps the QR small enough to scan from a laptop screen.
127
+ *
128
+ * @returns 26-character Crockford Base32 code
129
+ */
130
+ function generatePairingCode() {
131
+ const hexDigits = exports.PAIRING_CODE_BITS / 4;
132
+ return encodeCrockfordBase32(Buffer.from((0, auth_1.generateToken)().slice(0, hexDigits), 'hex'));
133
+ }
134
+ /**
135
+ * Absolute path of the default handoff file.
136
+ *
137
+ * @returns `<configDir>/remote-pairing.json`
138
+ */
139
+ function getDefaultPairingFilePath() {
140
+ return (0, path_1.join)((0, install_context_1.getConfigDir)(), exports.PAIRING_FILE_NAME);
141
+ }
142
+ /**
143
+ * Read the handoff file path out of the environment.
144
+ *
145
+ * @returns The path, or null when `remote` is not running (route answers 404)
146
+ */
147
+ function getPairingFilePathFromEnv() {
148
+ const value = process.env[exports.PAIRING_FILE_ENV_KEY];
149
+ return value && value.trim().length > 0 ? value : null;
150
+ }
151
+ /**
152
+ * Write the handoff file with mode 0600.
153
+ *
154
+ * An existing file is unlinked first: `writeFileSync`'s `mode` is only honoured
155
+ * when the file is created, so writing over a stale world-readable file would
156
+ * silently keep the old permissions. `chmodSync` afterwards closes the umask
157
+ * gap for good measure.
158
+ *
159
+ * @param filePath - Absolute path of the handoff file
160
+ * @param handoff - Hash, expiry and plaintext session token
161
+ */
162
+ function writePairingHandoff(filePath, handoff) {
163
+ (0, fs_1.mkdirSync)((0, path_1.dirname)(filePath), { recursive: true, mode: 0o700 });
164
+ try {
165
+ (0, fs_1.unlinkSync)(filePath);
166
+ }
167
+ catch {
168
+ // Not there yet - the normal case.
169
+ }
170
+ (0, fs_1.writeFileSync)(filePath, JSON.stringify(handoff), { encoding: 'utf8', mode: exports.PAIRING_FILE_MODE });
171
+ (0, fs_1.chmodSync)(filePath, exports.PAIRING_FILE_MODE);
172
+ }
173
+ /**
174
+ * Mint a pairing code plus its handoff file in one step.
175
+ *
176
+ * @param options - Overrides for path, TTL, session token and clock
177
+ * @returns The plaintext code and token, which the caller must not persist
178
+ */
179
+ function createPairingHandoff(options = {}) {
180
+ const filePath = options.filePath ?? (0, path_1.join)((0, install_context_1.ensureConfigDir)(), exports.PAIRING_FILE_NAME);
181
+ const now = options.now ?? Date.now();
182
+ const code = generatePairingCode();
183
+ const sessionToken = options.sessionToken ?? (0, auth_1.generateToken)();
184
+ const expiresAt = now + (options.ttlMs ?? exports.DEFAULT_PAIRING_TTL_MS);
185
+ writePairingHandoff(filePath, { pairingHash: (0, auth_1.hashToken)(code), expiresAt, sessionToken });
186
+ return { code, sessionToken, expiresAt, filePath };
187
+ }
188
+ /**
189
+ * Read and validate the handoff file.
190
+ *
191
+ * Missing and malformed are deliberately the same answer: the caller turns both
192
+ * into 410 Gone, and "already consumed" arrives here as ENOENT.
193
+ *
194
+ * @param filePath - Absolute path of the handoff file
195
+ * @returns The handoff, or null when it is absent or unusable
196
+ */
197
+ function readPairingHandoff(filePath) {
198
+ let raw;
199
+ try {
200
+ raw = (0, fs_1.readFileSync)(filePath, 'utf8');
201
+ }
202
+ catch {
203
+ return null;
204
+ }
205
+ let parsed;
206
+ try {
207
+ parsed = JSON.parse(raw);
208
+ }
209
+ catch {
210
+ return null;
211
+ }
212
+ if (!parsed || typeof parsed !== 'object') {
213
+ return null;
214
+ }
215
+ const { pairingHash, expiresAt, sessionToken } = parsed;
216
+ if (typeof pairingHash !== 'string' || !(0, auth_config_1.isValidTokenHash)(pairingHash))
217
+ return null;
218
+ if (typeof expiresAt !== 'number' || !Number.isFinite(expiresAt))
219
+ return null;
220
+ if (typeof sessionToken !== 'string' || sessionToken.length === 0)
221
+ return null;
222
+ return { pairingHash, expiresAt, sessionToken };
223
+ }
224
+ /**
225
+ * Delete the handoff file. Idempotent — a missing file is success.
226
+ *
227
+ * @param filePath - Absolute path of the handoff file
228
+ */
229
+ function consumePairingHandoff(filePath) {
230
+ try {
231
+ (0, fs_1.unlinkSync)(filePath);
232
+ }
233
+ catch {
234
+ // Already gone: the state we wanted.
235
+ }
236
+ }
237
+ /**
238
+ * @param handoff - Handoff read from disk
239
+ * @param now - Epoch ms, injectable for tests
240
+ * @returns true when the pairing window has closed
241
+ */
242
+ function isPairingExpired(handoff, now = Date.now()) {
243
+ return now > handoff.expiresAt;
244
+ }
245
+ /**
246
+ * Timing-safe comparison of a supplied code against the stored hash (S001).
247
+ *
248
+ * @param code - Code as supplied by the client
249
+ * @param pairingHash - SHA-256 hex from the handoff file
250
+ * @returns true when the code matches
251
+ */
252
+ function verifyPairingCode(code, pairingHash) {
253
+ if (typeof code !== 'string' || code.length === 0 || code.length > exports.MAX_PAIRING_CODE_LENGTH) {
254
+ return false;
255
+ }
256
+ if (!(0, auth_config_1.isValidTokenHash)(pairingHash)) {
257
+ return false;
258
+ }
259
+ const candidate = Buffer.from((0, auth_1.hashToken)(normalizePairingCode(code)), 'hex');
260
+ const expected = Buffer.from(pairingHash, 'hex');
261
+ if (candidate.length !== expected.length) {
262
+ return false;
263
+ }
264
+ return (0, crypto_1.timingSafeEqual)(candidate, expected);
265
+ }
@@ -35,6 +35,11 @@ exports.AUTH_EXCLUDED_PATHS = [
35
35
  '/api/auth/login',
36
36
  '/api/auth/logout',
37
37
  '/api/auth/status',
38
+ // Issue #1937 (R5): one-shot pairing-code exchange for `commandmate remote`.
39
+ // The pairing SCREEN is '/login' above, driven by a '#code=' fragment, so
40
+ // this is the only entry the remote feature adds. Handler:
41
+ // src/app/api/remote/pair/route.ts (it authenticates the code itself).
42
+ '/api/remote/pair',
38
43
  // Issue #1124 (PWA): non-sensitive resources that must stay reachable before
39
44
  // auth so the app is installable and the offline fallback can be precached.
40
45
  // All carry no user data (app metadata / public SW code / static fallback).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commandmate",
3
- "version": "0.28.0",
3
+ "version": "0.29.1",
4
4
  "description": "A local control plane for agent CLIs — orchestration and visibility for Claude Code, Codex, Gemini CLI, and more across Git worktrees",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -92,6 +92,7 @@
92
92
  "next-intl": "^4.8.2",
93
93
  "next-themes": "^0.4.6",
94
94
  "postcss": "^8.5.6",
95
+ "qr.js": "0.0.0",
95
96
  "react": "^19.2.7",
96
97
  "react-dom": "^19.2.7",
97
98
  "react-markdown": "^10.1.0",
@@ -1 +0,0 @@
1
- self.__BUILD_MANIFEST=function(e,r,t,_){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:59,errorRate:1e-4,numBits:1132,numHashes:14,bitArray:[1,0,0,1,e,r,e,e,e,r,r,e,r,e,r,r,r,e,e,e,r,e,e,e,r,e,r,r,r,e,r,r,r,e,e,r,e,r,e,r,r,e,r,e,e,e,e,e,e,r,e,r,e,r,r,r,e,e,r,r,e,e,e,r,e,e,r,r,r,r,r,e,e,r,r,r,e,r,r,e,e,e,r,r,r,e,e,e,r,r,r,r,r,e,e,e,r,r,e,r,r,r,e,e,r,e,r,e,r,r,r,r,r,r,e,e,r,r,e,r,e,r,e,e,e,e,r,r,r,r,e,e,e,r,r,r,e,e,e,e,e,e,r,e,e,e,r,e,e,r,e,e,e,r,e,e,e,e,r,e,e,e,e,r,r,e,e,r,r,e,r,r,e,r,e,r,e,e,r,r,r,r,e,e,r,e,r,e,e,e,e,e,r,e,e,r,r,r,e,e,r,e,e,r,e,r,e,e,e,r,r,e,r,e,r,e,e,r,e,e,e,r,e,r,r,r,r,e,e,e,r,e,r,e,r,r,e,e,r,r,e,e,e,r,e,e,r,e,e,r,e,e,e,e,e,r,e,e,e,e,r,e,e,e,r,r,e,e,r,e,r,e,r,e,e,r,e,e,r,e,r,r,r,e,e,r,r,r,e,e,e,e,e,e,r,r,r,e,r,e,e,r,r,r,r,e,r,e,e,r,e,e,e,r,r,e,e,r,e,r,r,e,r,e,e,e,r,r,e,e,e,r,e,e,r,e,e,r,r,e,e,r,e,e,r,r,e,e,e,r,r,e,r,e,e,r,r,r,e,e,e,r,e,r,r,e,r,e,e,e,r,r,r,e,r,e,e,e,r,e,r,e,r,r,e,r,e,e,r,r,e,r,r,r,r,r,r,e,r,e,e,r,r,r,e,r,e,e,e,r,e,e,r,r,r,r,e,e,r,e,e,r,r,e,r,e,e,r,e,e,r,r,r,e,r,e,e,e,e,e,e,e,r,e,r,e,e,e,e,e,r,e,e,r,e,e,r,r,r,e,e,r,r,e,e,r,e,e,r,r,r,r,r,e,e,e,r,e,e,e,e,r,r,r,r,e,r,r,e,r,e,r,e,e,r,r,r,r,e,r,r,e,e,e,e,r,r,e,e,r,e,e,r,e,e,r,r,e,r,e,r,e,e,e,r,r,e,e,e,r,e,e,r,r,r,r,e,r,r,e,r,e,e,e,r,r,e,e,e,e,e,r,e,e,r,e,r,e,r,r,r,r,e,e,r,e,r,r,r,r,r,r,r,r,e,e,e,e,r,e,r,r,e,r,r,r,e,r,e,r,e,e,e,e,r,r,r,e,r,e,r,e,e,r,r,e,e,e,e,e,e,r,r,e,e,r,r,e,e,r,e,e,e,r,e,r,e,e,e,e,e,e,r,r,e,e,e,e,e,r,r,e,r,r,r,r,e,r,e,r,e,e,r,e,e,r,e,r,r,e,r,e,e,e,e,e,r,e,e,r,r,e,e,e,e,e,e,e,e,r,r,r,r,r,e,r,r,e,e,e,r,e,e,r,r,e,r,e,e,r,e,r,e,r,e,e,r,r,r,e,e,e,r,e,r,r,r,r,r,e,e,e,r,e,e,r,r,e,r,e,e,e,r,e,r,e,r,e,e,e,e,r,e,r,e,r,e,r,e,r,e,r,e,r,e,e,e,e,e,e,r,e,r,r,r,r,r,e,e,r,r,e,r,e,r,r,r,e,e,e,e,r,r,e,e,r,r,e,r,r,e,r,e,e,r,r,r,e,r,e,r,r,r,e,r,e,r,e,r,e,e,e,e,r,r,e,e,e,e,r,r,r,r,e,e,e,e,r,r,e,r,e,e,r,e,r,e,e,e,e,e,e,r,r,e,e,r,r,e,e,r,e,e,r,r,r,e,r,r,r,r,e,r,r,e,r,e,e,e,r,r,r,e,r,e,e,r,e,r,r,r,r,e,r,e,e,r,r,e,r,e,r,r,r,e,r,e,r,e,r,e,r,r,r,r,r,r,r,r,e,r,r,r,e,r,r,e,r,r,r,r,e,e,r,r,r,e,e,r,e,e,e,e,r,r,r,e,e,e,r,r,e,r,r,r,r,r,r,r,r,e,e,r,e,e,r,r,e,r,e,e,r,r,e,r,e,r,r,e,e,e,e,r,e,r,r,r,r,r,e,e,r,r,e,r,r,r,r,r,e,r,e,r,e,r,r,r,e,r,e,r,r,e,e,e,r,e,r,e,r,e,e,r,e,r,r,r,e,e,r,r,r,e,r,e,r,e,r,e,e,r,r,r,r,e,r,r,r,e,r,e,r,r,e,e,r,e,e,e,e,r,r,e,r,e,e,r,r,e,e,e,e,r,r,e,e,r,e,e,e,e,e,r,r,r,r,e,e,e,r,e,e,r,e,e,r,e,e,r,r,r,r,r,r,r,r,r,e,e,e,r,r,e,e,e,e,r,e,e,e,r,r,r,e,e,e,r,e,e,r,e,r,r,r,r,e,e,r,r,e,e,r]},__routerFilterDynamic:{numItems:11,errorRate:1e-4,numBits:211,numHashes:14,bitArray:[r,e,e,e,r,e,r,r,r,r,e,r,r,e,r,e,r,e,e,e,r,r,e,e,e,r,e,e,e,r,r,e,r,e,e,r,r,r,e,r,e,e,e,r,r,e,r,e,e,r,r,e,e,e,r,e,r,e,r,r,e,r,e,e,r,e,e,r,e,e,e,e,r,e,e,r,r,r,e,e,e,e,e,r,r,r,e,r,e,e,e,r,e,r,e,r,e,e,r,r,e,e,r,e,r,e,r,e,e,e,e,r,r,e,e,r,e,e,e,e,r,e,e,r,r,e,e,r,e,r,e,e,r,e,e,e,e,r,r,e,r,r,r,e,r,r,r,r,r,e,e,e,r,e,r,e,r,e,e,e,e,e,r,r,r,e,e,r,r,e,e,r,r,e,r,r,e,e,r,r,r,e,e,r,e,r,r,r,e,r,e,r,e,e,e,r,e,r,r,r,e,r,e,e,e,r,e,e,r,r,e]},"/_error":["static/chunks/pages/_error-c970d8b55ace1b48.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4,14),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();