@richhardry/codor 0.10.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 (388) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +293 -0
  3. package/bin/codor.mjs +7 -0
  4. package/node_modules/@codor/adapter-antigravity/dist/adapter.d.ts +41 -0
  5. package/node_modules/@codor/adapter-antigravity/dist/adapter.d.ts.map +1 -0
  6. package/node_modules/@codor/adapter-antigravity/dist/adapter.js +275 -0
  7. package/node_modules/@codor/adapter-antigravity/dist/adapter.js.map +1 -0
  8. package/node_modules/@codor/adapter-antigravity/dist/index.d.ts +2 -0
  9. package/node_modules/@codor/adapter-antigravity/dist/index.d.ts.map +1 -0
  10. package/node_modules/@codor/adapter-antigravity/dist/index.js +2 -0
  11. package/node_modules/@codor/adapter-antigravity/dist/index.js.map +1 -0
  12. package/node_modules/@codor/adapter-antigravity/package.json +18 -0
  13. package/node_modules/@codor/adapter-claude-code/dist/adapter.d.ts +94 -0
  14. package/node_modules/@codor/adapter-claude-code/dist/adapter.d.ts.map +1 -0
  15. package/node_modules/@codor/adapter-claude-code/dist/adapter.js +785 -0
  16. package/node_modules/@codor/adapter-claude-code/dist/adapter.js.map +1 -0
  17. package/node_modules/@codor/adapter-claude-code/dist/index.d.ts +8 -0
  18. package/node_modules/@codor/adapter-claude-code/dist/index.d.ts.map +1 -0
  19. package/node_modules/@codor/adapter-claude-code/dist/index.js +5 -0
  20. package/node_modules/@codor/adapter-claude-code/dist/index.js.map +1 -0
  21. package/node_modules/@codor/adapter-claude-code/dist/limits-probe.d.ts +18 -0
  22. package/node_modules/@codor/adapter-claude-code/dist/limits-probe.d.ts.map +1 -0
  23. package/node_modules/@codor/adapter-claude-code/dist/limits-probe.js +67 -0
  24. package/node_modules/@codor/adapter-claude-code/dist/limits-probe.js.map +1 -0
  25. package/node_modules/@codor/adapter-claude-code/dist/peek.d.ts +3 -0
  26. package/node_modules/@codor/adapter-claude-code/dist/peek.d.ts.map +1 -0
  27. package/node_modules/@codor/adapter-claude-code/dist/peek.js +128 -0
  28. package/node_modules/@codor/adapter-claude-code/dist/peek.js.map +1 -0
  29. package/node_modules/@codor/adapter-claude-code/dist/query.d.ts +9 -0
  30. package/node_modules/@codor/adapter-claude-code/dist/query.d.ts.map +1 -0
  31. package/node_modules/@codor/adapter-claude-code/dist/query.js +7 -0
  32. package/node_modules/@codor/adapter-claude-code/dist/query.js.map +1 -0
  33. package/node_modules/@codor/adapter-claude-code/dist/translate.d.ts +40 -0
  34. package/node_modules/@codor/adapter-claude-code/dist/translate.d.ts.map +1 -0
  35. package/node_modules/@codor/adapter-claude-code/dist/translate.js +505 -0
  36. package/node_modules/@codor/adapter-claude-code/dist/translate.js.map +1 -0
  37. package/node_modules/@codor/adapter-claude-code/package.json +18 -0
  38. package/node_modules/@codor/adapter-codex/dist/adapter.d.ts +105 -0
  39. package/node_modules/@codor/adapter-codex/dist/adapter.d.ts.map +1 -0
  40. package/node_modules/@codor/adapter-codex/dist/adapter.js +625 -0
  41. package/node_modules/@codor/adapter-codex/dist/adapter.js.map +1 -0
  42. package/node_modules/@codor/adapter-codex/dist/app-server-transport.d.ts +39 -0
  43. package/node_modules/@codor/adapter-codex/dist/app-server-transport.d.ts.map +1 -0
  44. package/node_modules/@codor/adapter-codex/dist/app-server-transport.js +186 -0
  45. package/node_modules/@codor/adapter-codex/dist/app-server-transport.js.map +1 -0
  46. package/node_modules/@codor/adapter-codex/dist/index.d.ts +8 -0
  47. package/node_modules/@codor/adapter-codex/dist/index.d.ts.map +1 -0
  48. package/node_modules/@codor/adapter-codex/dist/index.js +5 -0
  49. package/node_modules/@codor/adapter-codex/dist/index.js.map +1 -0
  50. package/node_modules/@codor/adapter-codex/dist/limits-probe.d.ts +18 -0
  51. package/node_modules/@codor/adapter-codex/dist/limits-probe.d.ts.map +1 -0
  52. package/node_modules/@codor/adapter-codex/dist/limits-probe.js +87 -0
  53. package/node_modules/@codor/adapter-codex/dist/limits-probe.js.map +1 -0
  54. package/node_modules/@codor/adapter-codex/dist/peek.d.ts +3 -0
  55. package/node_modules/@codor/adapter-codex/dist/peek.d.ts.map +1 -0
  56. package/node_modules/@codor/adapter-codex/dist/peek.js +98 -0
  57. package/node_modules/@codor/adapter-codex/dist/peek.js.map +1 -0
  58. package/node_modules/@codor/adapter-codex/dist/translate.d.ts +17 -0
  59. package/node_modules/@codor/adapter-codex/dist/translate.d.ts.map +1 -0
  60. package/node_modules/@codor/adapter-codex/dist/translate.js +286 -0
  61. package/node_modules/@codor/adapter-codex/dist/translate.js.map +1 -0
  62. package/node_modules/@codor/adapter-codex/package.json +17 -0
  63. package/node_modules/@codor/adapter-copilot/dist/adapter.d.ts +40 -0
  64. package/node_modules/@codor/adapter-copilot/dist/adapter.d.ts.map +1 -0
  65. package/node_modules/@codor/adapter-copilot/dist/adapter.js +190 -0
  66. package/node_modules/@codor/adapter-copilot/dist/adapter.js.map +1 -0
  67. package/node_modules/@codor/adapter-copilot/dist/index.d.ts +4 -0
  68. package/node_modules/@codor/adapter-copilot/dist/index.d.ts.map +1 -0
  69. package/node_modules/@codor/adapter-copilot/dist/index.js +3 -0
  70. package/node_modules/@codor/adapter-copilot/dist/index.js.map +1 -0
  71. package/node_modules/@codor/adapter-copilot/dist/translate.d.ts +11 -0
  72. package/node_modules/@codor/adapter-copilot/dist/translate.d.ts.map +1 -0
  73. package/node_modules/@codor/adapter-copilot/dist/translate.js +184 -0
  74. package/node_modules/@codor/adapter-copilot/dist/translate.js.map +1 -0
  75. package/node_modules/@codor/adapter-copilot/package.json +18 -0
  76. package/node_modules/@codor/adapter-cursor/dist/adapter.d.ts +32 -0
  77. package/node_modules/@codor/adapter-cursor/dist/adapter.d.ts.map +1 -0
  78. package/node_modules/@codor/adapter-cursor/dist/adapter.js +179 -0
  79. package/node_modules/@codor/adapter-cursor/dist/adapter.js.map +1 -0
  80. package/node_modules/@codor/adapter-cursor/dist/index.d.ts +9 -0
  81. package/node_modules/@codor/adapter-cursor/dist/index.d.ts.map +1 -0
  82. package/node_modules/@codor/adapter-cursor/dist/index.js +8 -0
  83. package/node_modules/@codor/adapter-cursor/dist/index.js.map +1 -0
  84. package/node_modules/@codor/adapter-cursor/dist/translate.d.ts +15 -0
  85. package/node_modules/@codor/adapter-cursor/dist/translate.d.ts.map +1 -0
  86. package/node_modules/@codor/adapter-cursor/dist/translate.js +164 -0
  87. package/node_modules/@codor/adapter-cursor/dist/translate.js.map +1 -0
  88. package/node_modules/@codor/adapter-cursor/package.json +17 -0
  89. package/node_modules/@codor/adapter-gemini/dist/adapter.d.ts +36 -0
  90. package/node_modules/@codor/adapter-gemini/dist/adapter.d.ts.map +1 -0
  91. package/node_modules/@codor/adapter-gemini/dist/adapter.js +245 -0
  92. package/node_modules/@codor/adapter-gemini/dist/adapter.js.map +1 -0
  93. package/node_modules/@codor/adapter-gemini/dist/index.d.ts +4 -0
  94. package/node_modules/@codor/adapter-gemini/dist/index.d.ts.map +1 -0
  95. package/node_modules/@codor/adapter-gemini/dist/index.js +3 -0
  96. package/node_modules/@codor/adapter-gemini/dist/index.js.map +1 -0
  97. package/node_modules/@codor/adapter-gemini/dist/translate.d.ts +12 -0
  98. package/node_modules/@codor/adapter-gemini/dist/translate.d.ts.map +1 -0
  99. package/node_modules/@codor/adapter-gemini/dist/translate.js +123 -0
  100. package/node_modules/@codor/adapter-gemini/dist/translate.js.map +1 -0
  101. package/node_modules/@codor/adapter-gemini/package.json +18 -0
  102. package/node_modules/@codor/adapter-opencode/dist/adapter.d.ts +42 -0
  103. package/node_modules/@codor/adapter-opencode/dist/adapter.d.ts.map +1 -0
  104. package/node_modules/@codor/adapter-opencode/dist/adapter.js +240 -0
  105. package/node_modules/@codor/adapter-opencode/dist/adapter.js.map +1 -0
  106. package/node_modules/@codor/adapter-opencode/dist/index.d.ts +4 -0
  107. package/node_modules/@codor/adapter-opencode/dist/index.d.ts.map +1 -0
  108. package/node_modules/@codor/adapter-opencode/dist/index.js +3 -0
  109. package/node_modules/@codor/adapter-opencode/dist/index.js.map +1 -0
  110. package/node_modules/@codor/adapter-opencode/dist/translate.d.ts +12 -0
  111. package/node_modules/@codor/adapter-opencode/dist/translate.d.ts.map +1 -0
  112. package/node_modules/@codor/adapter-opencode/dist/translate.js +144 -0
  113. package/node_modules/@codor/adapter-opencode/dist/translate.js.map +1 -0
  114. package/node_modules/@codor/adapter-opencode/package.json +18 -0
  115. package/node_modules/@codor/cli/dist/artifact.d.ts +33 -0
  116. package/node_modules/@codor/cli/dist/artifact.d.ts.map +1 -0
  117. package/node_modules/@codor/cli/dist/artifact.js +183 -0
  118. package/node_modules/@codor/cli/dist/artifact.js.map +1 -0
  119. package/node_modules/@codor/cli/dist/attach.d.ts +25 -0
  120. package/node_modules/@codor/cli/dist/attach.d.ts.map +1 -0
  121. package/node_modules/@codor/cli/dist/attach.js +133 -0
  122. package/node_modules/@codor/cli/dist/attach.js.map +1 -0
  123. package/node_modules/@codor/cli/dist/connection.d.ts +21 -0
  124. package/node_modules/@codor/cli/dist/connection.d.ts.map +1 -0
  125. package/node_modules/@codor/cli/dist/connection.js +130 -0
  126. package/node_modules/@codor/cli/dist/connection.js.map +1 -0
  127. package/node_modules/@codor/cli/dist/detect.d.ts +14 -0
  128. package/node_modules/@codor/cli/dist/detect.d.ts.map +1 -0
  129. package/node_modules/@codor/cli/dist/detect.js +99 -0
  130. package/node_modules/@codor/cli/dist/detect.js.map +1 -0
  131. package/node_modules/@codor/cli/dist/index.d.ts +17 -0
  132. package/node_modules/@codor/cli/dist/index.d.ts.map +1 -0
  133. package/node_modules/@codor/cli/dist/index.js +24 -0
  134. package/node_modules/@codor/cli/dist/index.js.map +1 -0
  135. package/node_modules/@codor/cli/dist/mirror.d.ts +4 -0
  136. package/node_modules/@codor/cli/dist/mirror.d.ts.map +1 -0
  137. package/node_modules/@codor/cli/dist/mirror.js +93 -0
  138. package/node_modules/@codor/cli/dist/mirror.js.map +1 -0
  139. package/node_modules/@codor/cli/dist/program.d.ts +17 -0
  140. package/node_modules/@codor/cli/dist/program.d.ts.map +1 -0
  141. package/node_modules/@codor/cli/dist/program.js +1068 -0
  142. package/node_modules/@codor/cli/dist/program.js.map +1 -0
  143. package/node_modules/@codor/cli/dist/runtime-install.d.ts +61 -0
  144. package/node_modules/@codor/cli/dist/runtime-install.d.ts.map +1 -0
  145. package/node_modules/@codor/cli/dist/runtime-install.js +122 -0
  146. package/node_modules/@codor/cli/dist/runtime-install.js.map +1 -0
  147. package/node_modules/@codor/cli/dist/runtime-paths.d.ts +24 -0
  148. package/node_modules/@codor/cli/dist/runtime-paths.d.ts.map +1 -0
  149. package/node_modules/@codor/cli/dist/runtime-paths.js +69 -0
  150. package/node_modules/@codor/cli/dist/runtime-paths.js.map +1 -0
  151. package/node_modules/@codor/cli/dist/setup-flow.d.ts +69 -0
  152. package/node_modules/@codor/cli/dist/setup-flow.d.ts.map +1 -0
  153. package/node_modules/@codor/cli/dist/setup-flow.js +110 -0
  154. package/node_modules/@codor/cli/dist/setup-flow.js.map +1 -0
  155. package/node_modules/@codor/cli/dist/setup-session.d.ts +105 -0
  156. package/node_modules/@codor/cli/dist/setup-session.d.ts.map +1 -0
  157. package/node_modules/@codor/cli/dist/setup-session.js +346 -0
  158. package/node_modules/@codor/cli/dist/setup-session.js.map +1 -0
  159. package/node_modules/@codor/cli/dist/setup-ui.d.ts +93 -0
  160. package/node_modules/@codor/cli/dist/setup-ui.d.ts.map +1 -0
  161. package/node_modules/@codor/cli/dist/setup-ui.js +249 -0
  162. package/node_modules/@codor/cli/dist/setup-ui.js.map +1 -0
  163. package/node_modules/@codor/cli/dist/setup.d.ts +108 -0
  164. package/node_modules/@codor/cli/dist/setup.d.ts.map +1 -0
  165. package/node_modules/@codor/cli/dist/setup.js +878 -0
  166. package/node_modules/@codor/cli/dist/setup.js.map +1 -0
  167. package/node_modules/@codor/cli/dist/terminal-keys.d.ts +26 -0
  168. package/node_modules/@codor/cli/dist/terminal-keys.d.ts.map +1 -0
  169. package/node_modules/@codor/cli/dist/terminal-keys.js +70 -0
  170. package/node_modules/@codor/cli/dist/terminal-keys.js.map +1 -0
  171. package/node_modules/@codor/cli/dist/terminal-qr.d.ts +2 -0
  172. package/node_modules/@codor/cli/dist/terminal-qr.d.ts.map +1 -0
  173. package/node_modules/@codor/cli/dist/terminal-qr.js +30 -0
  174. package/node_modules/@codor/cli/dist/terminal-qr.js.map +1 -0
  175. package/node_modules/@codor/cli/dist/up.d.ts +52 -0
  176. package/node_modules/@codor/cli/dist/up.d.ts.map +1 -0
  177. package/node_modules/@codor/cli/dist/up.js +178 -0
  178. package/node_modules/@codor/cli/dist/up.js.map +1 -0
  179. package/node_modules/@codor/cli/package.json +24 -0
  180. package/node_modules/@codor/cli/packaging/systemd/codor.service +21 -0
  181. package/node_modules/@codor/cli/runtime/web/assets/LandingPage-BOmG5kSw.js +31 -0
  182. package/node_modules/@codor/cli/runtime/web/assets/LedgerPage-CecuTS8-.js +1 -0
  183. package/node_modules/@codor/cli/runtime/web/assets/NoChannels-CYiBXGQd.js +11 -0
  184. package/node_modules/@codor/cli/runtime/web/assets/PairingCodeInput-Cr6XDWx-.js +1 -0
  185. package/node_modules/@codor/cli/runtime/web/assets/PairingPage-CQBWNA2L.js +6 -0
  186. package/node_modules/@codor/cli/runtime/web/assets/SettingsPage-DGLbSXE7.js +16 -0
  187. package/node_modules/@codor/cli/runtime/web/assets/StartupUnavailable-DdQBHip_.js +1 -0
  188. package/node_modules/@codor/cli/runtime/web/assets/arrow-left-BOpjMuRi.js +6 -0
  189. package/node_modules/@codor/cli/runtime/web/assets/browser-BWQYNOsD.js +6 -0
  190. package/node_modules/@codor/cli/runtime/web/assets/graph-toBZHlC0.js +1 -0
  191. package/node_modules/@codor/cli/runtime/web/assets/index-Cxi54Xim.js +408 -0
  192. package/node_modules/@codor/cli/runtime/web/assets/index-DjwJakJC.css +1 -0
  193. package/node_modules/@codor/cli/runtime/web/assets/qr-DpynCwP9.js +8 -0
  194. package/node_modules/@codor/cli/runtime/web/assets/react-C8w-UNLI.js +32 -0
  195. package/node_modules/@codor/cli/runtime/web/assets/sodium-DtsvMzX9.js +1 -0
  196. package/node_modules/@codor/cli/runtime/web/codor-192.png +0 -0
  197. package/node_modules/@codor/cli/runtime/web/codor-512.png +0 -0
  198. package/node_modules/@codor/cli/runtime/web/codor-apple-touch-180.png +0 -0
  199. package/node_modules/@codor/cli/runtime/web/codor-favicon.svg +86 -0
  200. package/node_modules/@codor/cli/runtime/web/codor-mark.svg +86 -0
  201. package/node_modules/@codor/cli/runtime/web/codor-maskable-512.png +0 -0
  202. package/node_modules/@codor/cli/runtime/web/codor-og.png +0 -0
  203. package/node_modules/@codor/cli/runtime/web/fonts/BitcountPropSingle-latin.woff2 +0 -0
  204. package/node_modules/@codor/cli/runtime/web/fonts/Geist-Variable.woff2 +0 -0
  205. package/node_modules/@codor/cli/runtime/web/fonts/GeistMono-Variable.woff2 +0 -0
  206. package/node_modules/@codor/cli/runtime/web/fonts/OFL.txt +93 -0
  207. package/node_modules/@codor/cli/runtime/web/index.html +53 -0
  208. package/node_modules/@codor/cli/runtime/web/manifest.webmanifest +1 -0
  209. package/node_modules/@codor/cli/runtime/web/sw.js +2 -0
  210. package/node_modules/@codor/protocol/dist/adapter.d.ts +118 -0
  211. package/node_modules/@codor/protocol/dist/adapter.d.ts.map +1 -0
  212. package/node_modules/@codor/protocol/dist/adapter.js +15 -0
  213. package/node_modules/@codor/protocol/dist/adapter.js.map +1 -0
  214. package/node_modules/@codor/protocol/dist/body.d.ts +14 -0
  215. package/node_modules/@codor/protocol/dist/body.d.ts.map +1 -0
  216. package/node_modules/@codor/protocol/dist/body.js +50 -0
  217. package/node_modules/@codor/protocol/dist/body.js.map +1 -0
  218. package/node_modules/@codor/protocol/dist/changelog.d.ts +30 -0
  219. package/node_modules/@codor/protocol/dist/changelog.d.ts.map +1 -0
  220. package/node_modules/@codor/protocol/dist/changelog.js +19 -0
  221. package/node_modules/@codor/protocol/dist/changelog.js.map +1 -0
  222. package/node_modules/@codor/protocol/dist/default-recipient.d.ts +8 -0
  223. package/node_modules/@codor/protocol/dist/default-recipient.d.ts.map +1 -0
  224. package/node_modules/@codor/protocol/dist/default-recipient.js +19 -0
  225. package/node_modules/@codor/protocol/dist/default-recipient.js.map +1 -0
  226. package/node_modules/@codor/protocol/dist/delivery.d.ts +42 -0
  227. package/node_modules/@codor/protocol/dist/delivery.d.ts.map +1 -0
  228. package/node_modules/@codor/protocol/dist/delivery.js +44 -0
  229. package/node_modules/@codor/protocol/dist/delivery.js.map +1 -0
  230. package/node_modules/@codor/protocol/dist/events.d.ts +284 -0
  231. package/node_modules/@codor/protocol/dist/events.d.ts.map +1 -0
  232. package/node_modules/@codor/protocol/dist/events.js +150 -0
  233. package/node_modules/@codor/protocol/dist/events.js.map +1 -0
  234. package/node_modules/@codor/protocol/dist/ids.d.ts +19 -0
  235. package/node_modules/@codor/protocol/dist/ids.d.ts.map +1 -0
  236. package/node_modules/@codor/protocol/dist/ids.js +27 -0
  237. package/node_modules/@codor/protocol/dist/ids.js.map +1 -0
  238. package/node_modules/@codor/protocol/dist/index.d.ts +14 -0
  239. package/node_modules/@codor/protocol/dist/index.d.ts.map +1 -0
  240. package/node_modules/@codor/protocol/dist/index.js +14 -0
  241. package/node_modules/@codor/protocol/dist/index.js.map +1 -0
  242. package/node_modules/@codor/protocol/dist/interaction.d.ts +45 -0
  243. package/node_modules/@codor/protocol/dist/interaction.d.ts.map +1 -0
  244. package/node_modules/@codor/protocol/dist/interaction.js +33 -0
  245. package/node_modules/@codor/protocol/dist/interaction.js.map +1 -0
  246. package/node_modules/@codor/protocol/dist/member.d.ts +146 -0
  247. package/node_modules/@codor/protocol/dist/member.d.ts.map +1 -0
  248. package/node_modules/@codor/protocol/dist/member.js +169 -0
  249. package/node_modules/@codor/protocol/dist/member.js.map +1 -0
  250. package/node_modules/@codor/protocol/dist/message.d.ts +166 -0
  251. package/node_modules/@codor/protocol/dist/message.d.ts.map +1 -0
  252. package/node_modules/@codor/protocol/dist/message.js +95 -0
  253. package/node_modules/@codor/protocol/dist/message.js.map +1 -0
  254. package/node_modules/@codor/protocol/dist/observability.d.ts +80 -0
  255. package/node_modules/@codor/protocol/dist/observability.d.ts.map +1 -0
  256. package/node_modules/@codor/protocol/dist/observability.js +41 -0
  257. package/node_modules/@codor/protocol/dist/observability.js.map +1 -0
  258. package/node_modules/@codor/protocol/dist/room.d.ts +430 -0
  259. package/node_modules/@codor/protocol/dist/room.d.ts.map +1 -0
  260. package/node_modules/@codor/protocol/dist/room.js +142 -0
  261. package/node_modules/@codor/protocol/dist/room.js.map +1 -0
  262. package/node_modules/@codor/protocol/dist/ws.d.ts +1348 -0
  263. package/node_modules/@codor/protocol/dist/ws.d.ts.map +1 -0
  264. package/node_modules/@codor/protocol/dist/ws.js +282 -0
  265. package/node_modules/@codor/protocol/dist/ws.js.map +1 -0
  266. package/node_modules/@codor/protocol/package.json +17 -0
  267. package/node_modules/@codor/switchboard/dist/adapter-registry.d.ts +14 -0
  268. package/node_modules/@codor/switchboard/dist/adapter-registry.d.ts.map +1 -0
  269. package/node_modules/@codor/switchboard/dist/adapter-registry.js +175 -0
  270. package/node_modules/@codor/switchboard/dist/adapter-registry.js.map +1 -0
  271. package/node_modules/@codor/switchboard/dist/authorization.d.ts +13 -0
  272. package/node_modules/@codor/switchboard/dist/authorization.d.ts.map +1 -0
  273. package/node_modules/@codor/switchboard/dist/authorization.js +96 -0
  274. package/node_modules/@codor/switchboard/dist/authorization.js.map +1 -0
  275. package/node_modules/@codor/switchboard/dist/blobs.d.ts +17 -0
  276. package/node_modules/@codor/switchboard/dist/blobs.d.ts.map +1 -0
  277. package/node_modules/@codor/switchboard/dist/blobs.js +54 -0
  278. package/node_modules/@codor/switchboard/dist/blobs.js.map +1 -0
  279. package/node_modules/@codor/switchboard/dist/collaboration.d.ts +115 -0
  280. package/node_modules/@codor/switchboard/dist/collaboration.d.ts.map +1 -0
  281. package/node_modules/@codor/switchboard/dist/collaboration.js +123 -0
  282. package/node_modules/@codor/switchboard/dist/collaboration.js.map +1 -0
  283. package/node_modules/@codor/switchboard/dist/continuation.d.ts +33 -0
  284. package/node_modules/@codor/switchboard/dist/continuation.d.ts.map +1 -0
  285. package/node_modules/@codor/switchboard/dist/continuation.js +177 -0
  286. package/node_modules/@codor/switchboard/dist/continuation.js.map +1 -0
  287. package/node_modules/@codor/switchboard/dist/crypto/browser-sessions.d.ts +22 -0
  288. package/node_modules/@codor/switchboard/dist/crypto/browser-sessions.d.ts.map +1 -0
  289. package/node_modules/@codor/switchboard/dist/crypto/browser-sessions.js +92 -0
  290. package/node_modules/@codor/switchboard/dist/crypto/browser-sessions.js.map +1 -0
  291. package/node_modules/@codor/switchboard/dist/crypto/challenge.d.ts +37 -0
  292. package/node_modules/@codor/switchboard/dist/crypto/challenge.d.ts.map +1 -0
  293. package/node_modules/@codor/switchboard/dist/crypto/challenge.js +132 -0
  294. package/node_modules/@codor/switchboard/dist/crypto/challenge.js.map +1 -0
  295. package/node_modules/@codor/switchboard/dist/crypto/keys.d.ts +41 -0
  296. package/node_modules/@codor/switchboard/dist/crypto/keys.d.ts.map +1 -0
  297. package/node_modules/@codor/switchboard/dist/crypto/keys.js +145 -0
  298. package/node_modules/@codor/switchboard/dist/crypto/keys.js.map +1 -0
  299. package/node_modules/@codor/switchboard/dist/crypto/pairing.d.ts +53 -0
  300. package/node_modules/@codor/switchboard/dist/crypto/pairing.d.ts.map +1 -0
  301. package/node_modules/@codor/switchboard/dist/crypto/pairing.js +182 -0
  302. package/node_modules/@codor/switchboard/dist/crypto/pairing.js.map +1 -0
  303. package/node_modules/@codor/switchboard/dist/crypto/roomkeys.d.ts +30 -0
  304. package/node_modules/@codor/switchboard/dist/crypto/roomkeys.d.ts.map +1 -0
  305. package/node_modules/@codor/switchboard/dist/crypto/roomkeys.js +101 -0
  306. package/node_modules/@codor/switchboard/dist/crypto/roomkeys.js.map +1 -0
  307. package/node_modules/@codor/switchboard/dist/daemon.d.ts +545 -0
  308. package/node_modules/@codor/switchboard/dist/daemon.d.ts.map +1 -0
  309. package/node_modules/@codor/switchboard/dist/daemon.js +3907 -0
  310. package/node_modules/@codor/switchboard/dist/daemon.js.map +1 -0
  311. package/node_modules/@codor/switchboard/dist/fake-adapter.d.ts +103 -0
  312. package/node_modules/@codor/switchboard/dist/fake-adapter.d.ts.map +1 -0
  313. package/node_modules/@codor/switchboard/dist/fake-adapter.js +228 -0
  314. package/node_modules/@codor/switchboard/dist/fake-adapter.js.map +1 -0
  315. package/node_modules/@codor/switchboard/dist/index.d.ts +44 -0
  316. package/node_modules/@codor/switchboard/dist/index.d.ts.map +1 -0
  317. package/node_modules/@codor/switchboard/dist/index.js +24 -0
  318. package/node_modules/@codor/switchboard/dist/index.js.map +1 -0
  319. package/node_modules/@codor/switchboard/dist/ledger/resolve.d.ts +12 -0
  320. package/node_modules/@codor/switchboard/dist/ledger/resolve.d.ts.map +1 -0
  321. package/node_modules/@codor/switchboard/dist/ledger/resolve.js +17 -0
  322. package/node_modules/@codor/switchboard/dist/ledger/resolve.js.map +1 -0
  323. package/node_modules/@codor/switchboard/dist/ledger/vault.d.ts +47 -0
  324. package/node_modules/@codor/switchboard/dist/ledger/vault.d.ts.map +1 -0
  325. package/node_modules/@codor/switchboard/dist/ledger/vault.js +175 -0
  326. package/node_modules/@codor/switchboard/dist/ledger/vault.js.map +1 -0
  327. package/node_modules/@codor/switchboard/dist/ledger/watch.d.ts +73 -0
  328. package/node_modules/@codor/switchboard/dist/ledger/watch.d.ts.map +1 -0
  329. package/node_modules/@codor/switchboard/dist/ledger/watch.js +232 -0
  330. package/node_modules/@codor/switchboard/dist/ledger/watch.js.map +1 -0
  331. package/node_modules/@codor/switchboard/dist/local-dirs.d.ts +14 -0
  332. package/node_modules/@codor/switchboard/dist/local-dirs.d.ts.map +1 -0
  333. package/node_modules/@codor/switchboard/dist/local-dirs.js +40 -0
  334. package/node_modules/@codor/switchboard/dist/local-dirs.js.map +1 -0
  335. package/node_modules/@codor/switchboard/dist/local-socket.d.ts +3 -0
  336. package/node_modules/@codor/switchboard/dist/local-socket.d.ts.map +1 -0
  337. package/node_modules/@codor/switchboard/dist/local-socket.js +16 -0
  338. package/node_modules/@codor/switchboard/dist/local-socket.js.map +1 -0
  339. package/node_modules/@codor/switchboard/dist/pricing.d.ts +32 -0
  340. package/node_modules/@codor/switchboard/dist/pricing.d.ts.map +1 -0
  341. package/node_modules/@codor/switchboard/dist/pricing.js +64 -0
  342. package/node_modules/@codor/switchboard/dist/pricing.js.map +1 -0
  343. package/node_modules/@codor/switchboard/dist/process-liveness.d.ts +2 -0
  344. package/node_modules/@codor/switchboard/dist/process-liveness.d.ts.map +1 -0
  345. package/node_modules/@codor/switchboard/dist/process-liveness.js +9 -0
  346. package/node_modules/@codor/switchboard/dist/process-liveness.js.map +1 -0
  347. package/node_modules/@codor/switchboard/dist/push/producer.d.ts +54 -0
  348. package/node_modules/@codor/switchboard/dist/push/producer.d.ts.map +1 -0
  349. package/node_modules/@codor/switchboard/dist/push/producer.js +168 -0
  350. package/node_modules/@codor/switchboard/dist/push/producer.js.map +1 -0
  351. package/node_modules/@codor/switchboard/dist/push/subscriptions.d.ts +29 -0
  352. package/node_modules/@codor/switchboard/dist/push/subscriptions.d.ts.map +1 -0
  353. package/node_modules/@codor/switchboard/dist/push/subscriptions.js +83 -0
  354. package/node_modules/@codor/switchboard/dist/push/subscriptions.js.map +1 -0
  355. package/node_modules/@codor/switchboard/dist/redact.d.ts +11 -0
  356. package/node_modules/@codor/switchboard/dist/redact.d.ts.map +1 -0
  357. package/node_modules/@codor/switchboard/dist/redact.js +65 -0
  358. package/node_modules/@codor/switchboard/dist/redact.js.map +1 -0
  359. package/node_modules/@codor/switchboard/dist/residency.d.ts +110 -0
  360. package/node_modules/@codor/switchboard/dist/residency.d.ts.map +1 -0
  361. package/node_modules/@codor/switchboard/dist/residency.js +587 -0
  362. package/node_modules/@codor/switchboard/dist/residency.js.map +1 -0
  363. package/node_modules/@codor/switchboard/dist/router.d.ts +120 -0
  364. package/node_modules/@codor/switchboard/dist/router.d.ts.map +1 -0
  365. package/node_modules/@codor/switchboard/dist/router.js +198 -0
  366. package/node_modules/@codor/switchboard/dist/router.js.map +1 -0
  367. package/node_modules/@codor/switchboard/dist/server.d.ts +50 -0
  368. package/node_modules/@codor/switchboard/dist/server.d.ts.map +1 -0
  369. package/node_modules/@codor/switchboard/dist/server.js +1425 -0
  370. package/node_modules/@codor/switchboard/dist/server.js.map +1 -0
  371. package/node_modules/@codor/switchboard/dist/store.d.ts +534 -0
  372. package/node_modules/@codor/switchboard/dist/store.d.ts.map +1 -0
  373. package/node_modules/@codor/switchboard/dist/store.js +2625 -0
  374. package/node_modules/@codor/switchboard/dist/store.js.map +1 -0
  375. package/node_modules/@codor/switchboard/dist/transport/hyperswarm.d.ts +59 -0
  376. package/node_modules/@codor/switchboard/dist/transport/hyperswarm.d.ts.map +1 -0
  377. package/node_modules/@codor/switchboard/dist/transport/hyperswarm.js +183 -0
  378. package/node_modules/@codor/switchboard/dist/transport/hyperswarm.js.map +1 -0
  379. package/node_modules/@codor/switchboard/dist/transport/peer.d.ts +87 -0
  380. package/node_modules/@codor/switchboard/dist/transport/peer.d.ts.map +1 -0
  381. package/node_modules/@codor/switchboard/dist/transport/peer.js +316 -0
  382. package/node_modules/@codor/switchboard/dist/transport/peer.js.map +1 -0
  383. package/node_modules/@codor/switchboard/dist/working-directory.d.ts +2 -0
  384. package/node_modules/@codor/switchboard/dist/working-directory.d.ts.map +1 -0
  385. package/node_modules/@codor/switchboard/dist/working-directory.js +26 -0
  386. package/node_modules/@codor/switchboard/dist/working-directory.js.map +1 -0
  387. package/node_modules/@codor/switchboard/package.json +33 -0
  388. package/package.json +58 -0
@@ -0,0 +1,878 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { randomBytes } from 'node:crypto';
3
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
4
+ import { homedir, release } from 'node:os';
5
+ import { dirname, join, resolve } from 'node:path';
6
+ import { CryptoVault, pairingUrl } from '@codor/switchboard';
7
+ import { packageRuntimePaths, resolveRuntimePaths } from './runtime-paths.js';
8
+ import { defaultInstallIo, detectInstalledRuntime, durableRuntimeLocation, installDurableRuntime, installedCliRoot, resolveInstallSource, } from './runtime-install.js';
9
+ import { SetupSession, isInteractiveSetup, } from './setup-session.js';
10
+ import { SETUP_STAGE_TITLES, renderPairingCard } from './setup-ui.js';
11
+ import { renderTerminalQr } from './terminal-qr.js';
12
+ const HARNESSES = ['claude', 'codex', 'opencode', 'gemini', 'copilot', 'cursor-agent', 'agy'];
13
+ const LAUNCH_AGENT_LABEL = 'app.codor.switchboard';
14
+ const defaultExec = (command, args) => execFileSync(command, args, {
15
+ encoding: 'utf8',
16
+ stdio: ['ignore', 'pipe', 'pipe'],
17
+ }).trim();
18
+ const defaultWhich = (command) => {
19
+ try {
20
+ const locator = process.platform === 'win32' ? 'where.exe' : 'which';
21
+ return defaultExec(locator, [command]).split(/\r?\n/)[0]?.trim() || undefined;
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ };
27
+ function uniquePath(parts, delimiter = ':') {
28
+ return [...new Set(parts.flatMap((part) => part?.split(delimiter) ?? []).filter(Boolean))]
29
+ .join(delimiter);
30
+ }
31
+ // harn:assume wsl-setup-keeps-private-windows-loopback ref=wsl-bind-selection
32
+ function wslSystemdBindHost(env, kernelRelease, exec, which) {
33
+ const isWsl = Boolean(env.WSL_DISTRO_NAME || env.WSL_INTEROP || /microsoft/i.test(kernelRelease));
34
+ if (!isWsl)
35
+ return '127.0.0.1';
36
+ if (!/wsl2/i.test(kernelRelease))
37
+ return '127.0.0.1';
38
+ let networkingMode;
39
+ const wslinfo = which('wslinfo');
40
+ if (wslinfo) {
41
+ try {
42
+ networkingMode = exec('wslinfo', ['--networking-mode']).trim().toLowerCase() || undefined;
43
+ }
44
+ catch {
45
+ // A present-but-broken probe cannot safely distinguish NAT from mirrored networking.
46
+ return '127.0.0.1';
47
+ }
48
+ }
49
+ if ((wslinfo === undefined && networkingMode === undefined)
50
+ || networkingMode === 'nat'
51
+ || networkingMode === 'virtioproxy') {
52
+ return '0.0.0.0';
53
+ }
54
+ return '127.0.0.1';
55
+ }
56
+ // harn:end wsl-setup-keeps-private-windows-loopback
57
+ function systemdQuote(value) {
58
+ if (/[\0\r\n]/.test(value))
59
+ throw new Error('codor setup paths cannot contain control characters');
60
+ return `"${value
61
+ .replaceAll('\\', '\\\\')
62
+ .replaceAll('"', '\\"')
63
+ .replaceAll('%', '%%')}"`;
64
+ }
65
+ function systemdPath(value) {
66
+ if (/[\0\r\n]/.test(value))
67
+ throw new Error('codor setup paths cannot contain control characters');
68
+ return value.replaceAll('%', '%%');
69
+ }
70
+ function renderSystemdUnit(template, options) {
71
+ const args = [
72
+ options.nodePath,
73
+ options.runtime.cliEntrypoint,
74
+ '--data-dir',
75
+ options.dataDir,
76
+ 'up',
77
+ ...(options.host === '0.0.0.0' ? ['--host', options.host] : []),
78
+ '--static-root',
79
+ options.runtime.staticRoot,
80
+ '--channel',
81
+ 'desk',
82
+ '--channel-name',
83
+ 'Desk',
84
+ ];
85
+ const rendered = template
86
+ .replace(/^WorkingDirectory=.*$/m, `WorkingDirectory=${systemdPath(options.runtime.root)}`)
87
+ .replace(/^EnvironmentFile=.*$/m, `EnvironmentFile=${systemdPath(options.envPath)}`)
88
+ .replace(/^ExecStart=.*$/m, `ExecStart=${args.map(systemdQuote).join(' ')}`);
89
+ if (rendered === template || rendered.includes('%h/codor')) {
90
+ throw new Error('codor setup could not render the systemd service for the invoking runtime');
91
+ }
92
+ return rendered;
93
+ }
94
+ function xml(value) {
95
+ return value
96
+ .replaceAll('&', '&')
97
+ .replaceAll('<', '&lt;')
98
+ .replaceAll('>', '&gt;')
99
+ .replaceAll('"', '&quot;')
100
+ .replaceAll("'", '&apos;');
101
+ }
102
+ // harn:assume operator-launches-serve-web-next ref=launchd-current-web-client
103
+ function renderLaunchAgent(options) {
104
+ const values = {
105
+ dataDir: xml(options.dataDir),
106
+ entrypoint: xml(options.runtime.cliEntrypoint),
107
+ errorLog: xml(join(options.logDir, 'codor.err.log')),
108
+ nodePath: xml(options.nodePath),
109
+ outputLog: xml(join(options.logDir, 'codor.log')),
110
+ repoRoot: xml(options.runtime.root),
111
+ servicePath: xml(options.servicePath),
112
+ staticRoot: xml(options.runtime.staticRoot),
113
+ token: xml(options.token),
114
+ };
115
+ return `<?xml version="1.0" encoding="UTF-8"?>
116
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
117
+ <plist version="1.0">
118
+ <dict>
119
+ <key>Label</key>
120
+ <string>${LAUNCH_AGENT_LABEL}</string>
121
+ <key>ProgramArguments</key>
122
+ <array>
123
+ <string>${values.nodePath}</string>
124
+ <string>${values.entrypoint}</string>
125
+ <string>--data-dir</string>
126
+ <string>${values.dataDir}</string>
127
+ <string>up</string>
128
+ <string>--static-root</string>
129
+ <string>${values.staticRoot}</string>
130
+ <string>--channel</string>
131
+ <string>desk</string>
132
+ <string>--channel-name</string>
133
+ <string>Desk</string>
134
+ </array>
135
+ <key>WorkingDirectory</key>
136
+ <string>${values.repoRoot}</string>
137
+ <key>EnvironmentVariables</key>
138
+ <dict>
139
+ <key>CODOR_TOKEN</key>
140
+ <string>${values.token}</string>
141
+ <key>PATH</key>
142
+ <string>${values.servicePath}</string>
143
+ </dict>
144
+ <key>RunAtLoad</key>
145
+ <true/>
146
+ <key>KeepAlive</key>
147
+ <dict>
148
+ <key>SuccessfulExit</key>
149
+ <false/>
150
+ </dict>
151
+ <key>ProcessType</key>
152
+ <string>Background</string>
153
+ <key>Umask</key>
154
+ <integer>63</integer>
155
+ <key>ThrottleInterval</key>
156
+ <integer>5</integer>
157
+ <key>ExitTimeOut</key>
158
+ <integer>30</integer>
159
+ <key>StandardOutPath</key>
160
+ <string>${values.outputLog}</string>
161
+ <key>StandardErrorPath</key>
162
+ <string>${values.errorLog}</string>
163
+ </dict>
164
+ </plist>
165
+ `;
166
+ }
167
+ /** The full launchctl error text and whether it is the transient exit-5. */
168
+ function classifyBootstrapError(error) {
169
+ const err = error;
170
+ const text = [err.message, err.stderr?.toString()].filter(Boolean).join('\n').trim();
171
+ const retryable = err.status === 5 || /input\/output error|bootstrap failed:\s*5\b/i.test(text);
172
+ return { text, retryable };
173
+ }
174
+ // harn:assume setup-macos-launchd-confirms-loaded-and-healthy ref=launchd-bootstrap-recovery
175
+ /**
176
+ * Bootstrap the per-user LaunchAgent, recovering from a transient
177
+ * `Bootstrap failed: 5: Input/output error` (which arrives with the retryable
178
+ * text on a later line and exit status 5). Continues past a bootstrap error
179
+ * only when `launchctl print` confirms the target is loaded AND the HTTP probe
180
+ * answers — a briefly-answering booted-out orphan is not success. Never
181
+ * suggests root.
182
+ */
183
+ export async function bootstrapLaunchAgent(deps) {
184
+ const { exec, probe, sleep, domain, target, plistPath, nodePath, cliEntrypoint, endpoint, log } = deps;
185
+ const exists = deps.exists ?? existsSync;
186
+ const MAX_ATTEMPTS = 3;
187
+ const RETRY_DELAY_MS = 500;
188
+ // Validate before unloading anything, so a broken install never tears down a
189
+ // working prior instance: the plist parses, and the executables it references
190
+ // exist.
191
+ if (!existsSync(plistPath))
192
+ throw new Error(`the LaunchAgent plist is missing at ${plistPath}`);
193
+ try {
194
+ exec('plutil', ['-lint', plistPath]);
195
+ }
196
+ catch (error) {
197
+ throw new Error(`the LaunchAgent plist did not pass plutil -lint: ${classifyBootstrapError(error).text.split('\n')[0]}`);
198
+ }
199
+ if (!exists(nodePath))
200
+ throw new Error(`the LaunchAgent Node executable does not exist at ${nodePath}`);
201
+ if (!exists(cliEntrypoint))
202
+ throw new Error(`the Codor CLI entrypoint does not exist at ${cliEntrypoint}`);
203
+ const bootout = () => { try {
204
+ exec('launchctl', ['bootout', target]);
205
+ }
206
+ catch { /* not loaded */ } };
207
+ // `launchctl print <target>` exits non-zero when the target is not loaded.
208
+ const printState = () => {
209
+ try {
210
+ const printed = exec('launchctl', ['print', target]).trim();
211
+ const line = printed.split('\n').map((entry) => entry.trim()).find((entry) => entry.length > 0);
212
+ return { loaded: true, summary: line === undefined ? '' : ` (launchctl print: ${line})` };
213
+ }
214
+ catch {
215
+ return { loaded: false, summary: ' (launchctl print: target not loaded)' };
216
+ }
217
+ };
218
+ bootout();
219
+ let bootstrapped = false;
220
+ for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt += 1) {
221
+ try {
222
+ exec('launchctl', ['bootstrap', domain, plistPath]);
223
+ bootstrapped = true;
224
+ break;
225
+ }
226
+ catch (error) {
227
+ const { text, retryable } = classifyBootstrapError(error);
228
+ const state = printState();
229
+ const healthy = await probe(endpoint);
230
+ // Loaded AND healthy is the only success on a bootstrap error; a
231
+ // briefly-answering orphan whose target print is absent is not loaded.
232
+ if (state.loaded && healthy) {
233
+ log('Codor is already loaded and healthy; keeping it running');
234
+ return;
235
+ }
236
+ if (attempt >= MAX_ATTEMPTS || !retryable) {
237
+ throw new Error(`launchctl could not start the Codor LaunchAgent: ${text.split('\n').find((line) => line.trim().length > 0) ?? text}${state.summary}`);
238
+ }
239
+ log(`launchctl bootstrap did not take (attempt ${String(attempt)}); unloading and retrying`);
240
+ bootout();
241
+ await sleep(RETRY_DELAY_MS);
242
+ }
243
+ }
244
+ if (bootstrapped) {
245
+ exec('launchctl', ['enable', target]);
246
+ exec('launchctl', ['kickstart', '-k', target]);
247
+ }
248
+ }
249
+ // harn:end setup-macos-launchd-confirms-loaded-and-healthy
250
+ const TAILSCALE_MACOS_LOCATIONS = [
251
+ '/Applications/Tailscale.app/Contents/MacOS/Tailscale',
252
+ ];
253
+ // harn:assume setup-resolves-and-capability-probes-tailscale-serve ref=tailscale-resolution
254
+ /** Resolve the Tailscale CLI through PATH, then standard macOS app locations. */
255
+ export function resolveTailscale(which, platform, exists = existsSync) {
256
+ // Normalize the PATH hit to the absolute executable path actually invoked.
257
+ const onPath = which('tailscale');
258
+ if (onPath !== undefined && onPath.trim() !== '')
259
+ return resolve(onPath.trim());
260
+ if (platform === 'darwin') {
261
+ for (const location of TAILSCALE_MACOS_LOCATIONS)
262
+ if (exists(location))
263
+ return location;
264
+ }
265
+ return undefined;
266
+ }
267
+ /** Capability-probe the resolved CLI for Serve support (not an OS allowlist). */
268
+ export function tailscaleServeSupported(tailscalePath, exec) {
269
+ try {
270
+ exec(tailscalePath, ['serve', '--help']);
271
+ return true;
272
+ }
273
+ catch {
274
+ return false;
275
+ }
276
+ }
277
+ /** Publish Serve through the resolved absolute path and return the HTTPS origin.
278
+ * Throws a distinct diagnostic when the serve command itself fails. */
279
+ export function configureTailscaleServe(tailscalePath, localEndpoint, exec) {
280
+ // Preserve the full message and stderr: real permission/operator guidance often
281
+ // lands on a later line (the same class of bug fixed for launchctl).
282
+ const diagnostic = (error) => {
283
+ const err = error;
284
+ return [err.message, err.stderr?.toString()].filter(Boolean).join('\n').trim() || String(error);
285
+ };
286
+ let status;
287
+ try {
288
+ exec(tailscalePath, ['serve', '--bg', localEndpoint]);
289
+ status = exec(tailscalePath, ['serve', 'status']);
290
+ }
291
+ catch (error) {
292
+ throw new Error(`Tailscale Serve command failed: ${diagnostic(error)}`);
293
+ }
294
+ const origin = status.match(/https:\/\/[^\s/]+/)?.[0];
295
+ if (origin === undefined)
296
+ throw new Error('Tailscale Serve did not report a private HTTPS origin');
297
+ return origin;
298
+ }
299
+ const RETRY_OR_LOCAL = [
300
+ { id: 'retry', label: 'Retry detection', description: 'Check again for Tailscale.', available: true },
301
+ { id: 'here', label: 'Continue on this computer', description: 'Skip remote access for now.', available: true },
302
+ ];
303
+ // harn:assume setup-defers-remote-access-behind-consent ref=setup-remote-access-subflow
304
+ /**
305
+ * Resolve interactive access. "This computer" never touches Tailscale. "Remote"
306
+ * detects Tailscale only now, offers Retry/Continue-local when it is missing or
307
+ * cannot Serve, asks a separate consent before configuring Serve, and degrades
308
+ * to local — with the exact copyable recovery command — if configuring fails.
309
+ * Purely a decision function: it mutates nothing but the injected log.
310
+ */
311
+ export async function runRemoteAccess(deps) {
312
+ const local = (note) => {
313
+ deps.log(note);
314
+ return { access: 'localhost', endpoint: deps.localEndpoint, summary: 'This computer' };
315
+ };
316
+ if (deps.choice !== 'remote')
317
+ return local('this computer only');
318
+ for (;;) {
319
+ const { path, serve } = deps.detect();
320
+ if (path === undefined || !serve) {
321
+ const message = path === undefined
322
+ ? 'Tailscale is not installed. Install it from https://tailscale.com/download, then retry.'
323
+ : 'This Tailscale CLI cannot Serve. Update Tailscale, then retry.';
324
+ const next = await deps.choose({ message, options: RETRY_OR_LOCAL });
325
+ if (next === 'retry') {
326
+ deps.resetDetect();
327
+ continue;
328
+ }
329
+ return local('continuing on this computer only');
330
+ }
331
+ const consent = await deps.choose({
332
+ message: 'Codor can configure Tailscale Serve so you can reach it securely from your other devices. Configure it now?',
333
+ options: [
334
+ { id: 'configure', label: 'Configure Tailscale Serve', description: 'Publish Codor privately to your tailnet.', available: true },
335
+ { id: 'here', label: 'Just this computer', description: 'Keep Codor local for now.', available: true },
336
+ ],
337
+ });
338
+ if (consent !== 'configure')
339
+ return local('this computer only');
340
+ try {
341
+ const endpoint = deps.configureServe(path);
342
+ deps.log(`private browser origin ${endpoint}`);
343
+ return { access: 'tailscale', endpoint, summary: 'Tailscale Serve' };
344
+ }
345
+ catch (error) {
346
+ // Keep local Codor working and hand over the exact command to finish later,
347
+ // derived from the real resolved path and error — never invented sudo.
348
+ deps.log(`could not configure Tailscale Serve: ${error instanceof Error ? error.message : String(error)}`);
349
+ deps.log(`to finish remote access later, run: ${path} serve --bg ${deps.localEndpoint}`);
350
+ deps.log('Codor still works on this computer.');
351
+ return { access: 'localhost', endpoint: deps.localEndpoint, summary: 'This computer (remote access deferred)' };
352
+ }
353
+ }
354
+ }
355
+ // harn:end setup-defers-remote-access-behind-consent
356
+ // harn:assume windows-setup-installs-private-task-service ref=windows-service-rendering
357
+ export function renderWindowsServiceScript(options) {
358
+ const quote = (value) => value.replaceAll("'", "''");
359
+ const entrypoint = options.runtime.cliEntrypoint;
360
+ const staticRoot = options.runtime.staticRoot;
361
+ return [
362
+ `$env:CODOR_TOKEN = (Get-Content -Raw -Path '${quote(options.tokenPath)}').Trim()`,
363
+ `$env:PATH = '${quote(options.servicePath)}'`,
364
+ `Set-Location -Path '${quote(options.runtime.root)}'`,
365
+ `& '${quote(options.nodePath)}' '${quote(entrypoint)}' --data-dir '${quote(options.dataDir)}' up --static-root '${quote(staticRoot)}' --channel desk --channel-name Desk >> '${quote(join(options.logDir, 'codor.out.log'))}' 2>> '${quote(join(options.logDir, 'codor.err.log'))}'`,
366
+ 'exit $LASTEXITCODE',
367
+ ].join('\r\n') + '\r\n';
368
+ }
369
+ export function renderWindowsScheduledTask(options) {
370
+ const command = `-NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File "${options.scriptPath}"`;
371
+ return `<?xml version="1.0" encoding="UTF-16"?>
372
+ <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
373
+ <Triggers><LogonTrigger><Enabled>true</Enabled><UserId>${xml(options.user)}</UserId></LogonTrigger></Triggers>
374
+ <Principals><Principal id="Author"><UserId>${xml(options.user)}</UserId><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals>
375
+ <Settings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><AllowHardTerminate>true</AllowHardTerminate><StartWhenAvailable>true</StartWhenAvailable><RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable><IdleSettings><StopOnIdleEnd>false</StopOnIdleEnd><RestartOnIdle>false</RestartOnIdle></IdleSettings><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>true</Hidden><RunOnlyIfIdle>false</RunOnlyIfIdle><WakeToRun>false</WakeToRun><ExecutionTimeLimit>PT0S</ExecutionTimeLimit><Priority>7</Priority></Settings>
376
+ <Actions Context="Author"><Exec><Command>powershell.exe</Command><Arguments>${xml(command)}</Arguments></Exec></Actions>
377
+ </Task>
378
+ `;
379
+ }
380
+ // harn:end windows-setup-installs-private-task-service
381
+ export async function probeCodorStatus(endpoint) {
382
+ try {
383
+ const response = await fetch(new URL('/api/pairing/status', endpoint), {
384
+ signal: AbortSignal.timeout(1_000),
385
+ });
386
+ if (!response.ok)
387
+ return false;
388
+ const body = await response.json();
389
+ return typeof body.trusted_enrollment === 'boolean';
390
+ }
391
+ catch {
392
+ return false;
393
+ }
394
+ }
395
+ const defaultSleep = async (milliseconds) => new Promise((resolveSleep) => setTimeout(resolveSleep, milliseconds));
396
+ // harn:assume setup-verifies-codor-before-creating-pairing-code ref=setup-readiness-and-pairing
397
+ export async function waitForCodor(endpoint, probe, sleep) {
398
+ for (let attempt = 1; attempt <= 20; attempt += 1) {
399
+ if (await probe(endpoint))
400
+ return;
401
+ if (attempt < 20)
402
+ await sleep(250);
403
+ }
404
+ throw new Error(`Codor did not become ready at ${endpoint}; inspect the user-service logs`);
405
+ }
406
+ // harn:end setup-verifies-codor-before-creating-pairing-code
407
+ function runtimeVersion(runtime) {
408
+ const manifestPath = runtime.layout === 'installed-package'
409
+ ? join(runtime.root, 'package.json')
410
+ : join(runtime.root, 'packages', 'cli', 'package.json');
411
+ try {
412
+ const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
413
+ return typeof manifest.version === 'string' ? manifest.version : 'dev';
414
+ }
415
+ catch {
416
+ return 'dev';
417
+ }
418
+ }
419
+ // harn:assume windows-setup-installs-private-task-service ref=windows-setup-runtime
420
+ // harn:assume setup-preserves-private-platform-service ref=setup-platform-service-runtime
421
+ export async function runSetup(options) {
422
+ const overrides = options.overrides ?? {};
423
+ const platform = overrides.platform ?? process.platform;
424
+ if (platform !== 'linux' && platform !== 'darwin' && platform !== 'win32') {
425
+ throw new Error(`codor setup supports Linux, macOS, and Windows; received ${platform}`);
426
+ }
427
+ const runtime = overrides.runtime ?? resolveRuntimePaths({ repoRoot: overrides.repoRoot });
428
+ const home = resolve(overrides.home ?? options.env.HOME ?? homedir());
429
+ const nodePath = resolve(overrides.nodePath ?? process.execPath);
430
+ const exec = overrides.exec ?? defaultExec;
431
+ const which = overrides.which ?? defaultWhich;
432
+ const renderQr = overrides.renderQr ?? renderTerminalQr;
433
+ const probe = overrides.probe ?? probeCodorStatus;
434
+ const sleep = overrides.sleep ?? defaultSleep;
435
+ const configDir = join(home, '.config', 'codor');
436
+ const dataDir = join(home, '.codor');
437
+ const tokenPath = join(configDir, 'token');
438
+ const envPath = join(configDir, 'env');
439
+ const userUnitDir = join(home, '.config', 'systemd', 'user');
440
+ const userUnitPath = join(userUnitDir, 'codor.service');
441
+ const launchAgentDir = join(home, 'Library', 'LaunchAgents');
442
+ const launchAgentPath = join(launchAgentDir, `${LAUNCH_AGENT_LABEL}.plist`);
443
+ const logDir = join(dataDir, 'logs');
444
+ // The service must reference a durable runtime. An ephemeral (npx/temp)
445
+ // invoking runtime is copied to ~/.codor/runtime by the Install step; the
446
+ // service is rendered against that stable copy, while the service template is
447
+ // still read from the source runtime, which exists now.
448
+ const version = overrides.version ?? runtimeVersion(runtime);
449
+ const installIo = overrides.installIo ?? defaultInstallIo;
450
+ const installSource = resolveInstallSource(runtime);
451
+ const serviceLocation = installSource.durable ? installSource.installRoot : durableRuntimeLocation(dataDir);
452
+ const serviceRuntime = installSource.durable ? runtime : packageRuntimePaths(installedCliRoot(serviceLocation));
453
+ const windowsScriptPath = join(configDir, 'codor-service.ps1');
454
+ const windowsTaskPath = join(configDir, 'codor-task.xml');
455
+ const windowsUser = options.env.USERNAME ?? options.env.USER;
456
+ if (platform === 'win32' && !windowsUser) {
457
+ throw new Error('codor setup could not determine the Windows user name');
458
+ }
459
+ const detected = HARNESSES.flatMap((harness) => {
460
+ const path = which(harness);
461
+ return path === undefined ? [] : [{ harness, path }];
462
+ });
463
+ // Tailscale is inspected lazily: step 1 never touches it, and the interactive
464
+ // remote sub-flow probes only after the operator chooses remote access.
465
+ let tailscaleProbe;
466
+ const detectTailscale = () => {
467
+ if (tailscaleProbe === undefined) {
468
+ const path = resolveTailscale(which, platform);
469
+ tailscaleProbe = { path, serve: path !== undefined && tailscaleServeSupported(path, exec) };
470
+ }
471
+ return tailscaleProbe;
472
+ };
473
+ const servicePath = uniquePath([
474
+ join(home, '.local', 'bin'),
475
+ dirname(nodePath),
476
+ ...detected.map(({ path }) => dirname(path)),
477
+ options.env.PATH,
478
+ ], platform === 'win32' ? ';' : ':');
479
+ const systemdBindHost = platform === 'linux'
480
+ ? wslSystemdBindHost(options.env, overrides.kernelRelease ?? release(), exec, which)
481
+ : '127.0.0.1';
482
+ const unitContent = platform === 'linux'
483
+ ? renderSystemdUnit(readFileSync(runtime.serviceTemplate, 'utf8'), {
484
+ dataDir, envPath, host: systemdBindHost, nodePath, runtime: serviceRuntime,
485
+ })
486
+ : undefined;
487
+ const launchUid = platform === 'darwin'
488
+ ? overrides.uid ?? (typeof process.getuid === 'function' ? process.getuid() : undefined)
489
+ : undefined;
490
+ if (platform === 'darwin' && (!Number.isInteger(launchUid) || launchUid < 0)) {
491
+ throw new Error('codor setup could not determine the macOS user id');
492
+ }
493
+ const launchDomain = launchUid === undefined ? undefined : `gui/${String(launchUid)}`;
494
+ const launchTarget = launchDomain === undefined ? undefined : `${launchDomain}/${LAUNCH_AGENT_LABEL}`;
495
+ const windowsScript = platform === 'win32'
496
+ ? renderWindowsServiceScript({ dataDir, logDir, nodePath, runtime: serviceRuntime, servicePath, tokenPath })
497
+ : undefined;
498
+ const windowsTask = platform === 'win32'
499
+ ? renderWindowsScheduledTask({ scriptPath: windowsScriptPath, user: windowsUser })
500
+ : undefined;
501
+ // harn:assume setup-unattended-mutation-requires-explicit-intent ref=setup-unattended-runtime
502
+ const interactive = !options.dryRun && options.yes !== true && isInteractiveSetup(overrides.streams);
503
+ if (!options.dryRun && !interactive) {
504
+ if (options.yes !== true) {
505
+ throw new Error('non-interactive setup requires --yes and --access <localhost|tailscale>');
506
+ }
507
+ if (options.access === undefined) {
508
+ throw new Error('non-interactive setup with --yes also requires --access <localhost|tailscale>');
509
+ }
510
+ }
511
+ // harn:end setup-unattended-mutation-requires-explicit-intent
512
+ // harn:assume setup-dry-run-reports-without-mutation-or-secret ref=setup-dry-run-runtime
513
+ if (options.dryRun) {
514
+ const access = options.access ?? 'localhost';
515
+ if (access === 'tailscale') {
516
+ const { path, serve } = detectTailscale();
517
+ if (!serve) {
518
+ throw new Error(path === undefined
519
+ ? '--access tailscale requires the Tailscale CLI (not found on PATH or in /Applications)'
520
+ : '--access tailscale requires a Tailscale CLI that supports Serve');
521
+ }
522
+ }
523
+ options.out(installSource.durable
524
+ ? `[dry-run] use the Codor runtime in place at ${serviceLocation}`
525
+ : `[dry-run] install a durable Codor runtime -> ${serviceLocation}`);
526
+ options.out(`[dry-run] create ${configDir} and ${dataDir} mode 700; create ${tokenPath} mode 600 if absent`);
527
+ if (platform === 'linux') {
528
+ options.out(`[dry-run] install ${runtime.serviceTemplate} -> ${userUnitPath} mode 600`);
529
+ options.out('[dry-run] unit content:');
530
+ for (const line of unitContent.trimEnd().split('\n'))
531
+ options.out(line);
532
+ options.out(`[dry-run] write ${envPath} mode 600`);
533
+ options.out('CODOR_TOKEN=<redacted generated-or-existing token>');
534
+ options.out(`PATH=${servicePath}`);
535
+ options.out('[dry-run] systemctl --user daemon-reload');
536
+ options.out('[dry-run] systemctl --user enable --now codor.service');
537
+ }
538
+ else if (platform === 'darwin') {
539
+ const launchAgent = renderLaunchAgent({
540
+ dataDir, logDir, nodePath, runtime: serviceRuntime, servicePath,
541
+ token: '<redacted generated-or-existing token>',
542
+ });
543
+ options.out(`[dry-run] create ${logDir} mode 700`);
544
+ options.out(`[dry-run] install generated LaunchAgent -> ${launchAgentPath} mode 600`);
545
+ options.out('[dry-run] launch agent content:');
546
+ for (const line of launchAgent.trimEnd().split('\n'))
547
+ options.out(line);
548
+ options.out(`[dry-run] launchctl bootout ${launchTarget} (ignore not-loaded)`);
549
+ options.out(`[dry-run] launchctl bootstrap ${launchDomain} ${launchAgentPath}`);
550
+ options.out(`[dry-run] launchctl enable ${launchTarget}`);
551
+ options.out(`[dry-run] launchctl kickstart -k ${launchTarget}`);
552
+ }
553
+ else {
554
+ options.out(`[dry-run] protect ${tokenPath} for ${windowsUser} with icacls`);
555
+ options.out(`[dry-run] create ${logDir}`);
556
+ options.out(`[dry-run] install generated ServiceScript -> ${windowsScriptPath}`);
557
+ for (const line of windowsScript.trimEnd().split(/\r?\n/))
558
+ options.out(line);
559
+ options.out(`[dry-run] install generated ScheduledTaskXml -> ${windowsTaskPath} as UTF-16LE`);
560
+ for (const line of windowsTask.trimEnd().split('\n'))
561
+ options.out(line);
562
+ options.out(`[dry-run] schtasks /Create /TN "Codor Switchboard" /XML "${windowsTaskPath}" /F`);
563
+ options.out('[dry-run] schtasks /Run /TN "Codor Switchboard"');
564
+ }
565
+ if (access === 'tailscale') {
566
+ options.out('[dry-run] tailscale serve --bg http://127.0.0.1:8137');
567
+ options.out('[dry-run] tailscale serve status');
568
+ }
569
+ else {
570
+ options.out('[dry-run] access localhost; skip Tailscale Serve');
571
+ }
572
+ options.out('[dry-run] wait for Codor pairing status, then generate a ten-minute QR, URL, and pairing code');
573
+ return;
574
+ }
575
+ // harn:end setup-dry-run-reports-without-mutation-or-secret
576
+ const stepTitles = SETUP_STAGE_TITLES;
577
+ // Shared state the steps thread through. `pairing` and `serviceStarted` are
578
+ // memoized so a Retry re-runs the step's work idempotently: the daemon is not
579
+ // restarted and the pairing code is not re-minted.
580
+ // The readiness probe always targets the local daemon; the pairing endpoint
581
+ // becomes the tailnet HTTPS origin only when Tailscale Serve succeeds.
582
+ const localEndpoint = 'http://127.0.0.1:8137';
583
+ let endpoint = localEndpoint;
584
+ let selectedAccess = options.access;
585
+ let pairing;
586
+ let serviceStarted = false;
587
+ const checkStep = (log) => {
588
+ // Read-only detection; Tailscale is not inspected here.
589
+ log(`${platform} with Node ${process.versions.node}`);
590
+ log(detected.length > 0
591
+ ? `found ${detected.map(({ harness }) => harness).join(', ')}`
592
+ : 'no supported coding agents detected');
593
+ return detected.length > 0
594
+ ? `${platform}; ${detected.map(({ harness }) => harness).join(', ')}`
595
+ : `${platform}; no agents on PATH`;
596
+ };
597
+ const prepareStep = (log) => {
598
+ mkdirSync(configDir, { recursive: true, mode: 0o700 });
599
+ mkdirSync(dataDir, { recursive: true, mode: 0o700 });
600
+ if (!existsSync(tokenPath)) {
601
+ const token = overrides.randomToken?.() ?? randomBytes(32).toString('hex');
602
+ writeFileSync(tokenPath, `${token}\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
603
+ }
604
+ if (platform === 'win32')
605
+ exec('icacls', [tokenPath, '/inheritance:r', '/grant:r', `${windowsUser}:F`]);
606
+ else {
607
+ chmodSync(configDir, 0o700);
608
+ chmodSync(dataDir, 0o700);
609
+ chmodSync(tokenPath, 0o600);
610
+ }
611
+ log('private configuration and data are ready');
612
+ return 'config and mode-600 token ready';
613
+ };
614
+ // harn:assume setup-installs-durable-per-user-runtime-atomically ref=setup-install-runtime-wiring
615
+ // Install Codor: make the invoking runtime durable (so the service never
616
+ // references an npx cache), then create the private config, data, and token.
617
+ const installStep = (log, intent = 'ensure') => {
618
+ const result = installDurableRuntime({ runtime, dataDir, version, intent, io: installIo });
619
+ log(result.action === 'in-place'
620
+ ? `using the Codor runtime in place at ${result.location}`
621
+ : `${result.action} the Codor ${result.version} runtime at ${result.location}`);
622
+ prepareStep(log);
623
+ return `Codor ${result.version} at ${result.location}`;
624
+ };
625
+ // harn:end setup-installs-durable-per-user-runtime-atomically
626
+ // Non-interactive access selection (used by --yes and the linear fallback).
627
+ const chooseStep = (log, choice) => {
628
+ if (choice !== 'localhost' && choice !== 'tailscale')
629
+ throw new Error('setup requires an access choice');
630
+ if (choice === 'localhost') {
631
+ selectedAccess = 'localhost';
632
+ endpoint = localEndpoint;
633
+ log('localhost only');
634
+ return 'Localhost';
635
+ }
636
+ const { path, serve } = detectTailscale();
637
+ if (path === undefined)
638
+ throw new Error('Tailscale is not installed; pick localhost or install Tailscale');
639
+ if (!serve)
640
+ throw new Error('this Tailscale CLI does not support Serve; pick localhost');
641
+ endpoint = configureTailscaleServe(path, localEndpoint, exec);
642
+ selectedAccess = 'tailscale';
643
+ log(`private browser origin ${endpoint}`);
644
+ return 'Tailscale Serve';
645
+ };
646
+ // Interactive access: delegates to the testable runRemoteAccess and applies
647
+ // its decision to the shared endpoint/access state.
648
+ const whereStep = async (log, choice, choose) => {
649
+ const result = await runRemoteAccess({
650
+ choice, localEndpoint, log, choose,
651
+ detect: detectTailscale,
652
+ resetDetect: () => { tailscaleProbe = undefined; },
653
+ configureServe: (path) => configureTailscaleServe(path, localEndpoint, exec),
654
+ });
655
+ selectedAccess = result.access;
656
+ endpoint = result.endpoint;
657
+ return result.summary;
658
+ };
659
+ const startStep = async (log) => {
660
+ // A Retry must not reinstall or restart a daemon that is already up; when
661
+ // the service was started this run and still answers, short-circuit.
662
+ if (serviceStarted && await probe(localEndpoint)) {
663
+ log('Codor is already running; reusing it');
664
+ return 'service already running';
665
+ }
666
+ if (!existsSync(tokenPath))
667
+ throw new Error(`operator token is missing at ${tokenPath}`);
668
+ serviceStarted = true;
669
+ if (platform === 'linux') {
670
+ const token = readFileSync(tokenPath, 'utf8').trim();
671
+ mkdirSync(userUnitDir, { recursive: true, mode: 0o700 });
672
+ writeFileSync(userUnitPath, unitContent, { encoding: 'utf8', mode: 0o600 });
673
+ chmodSync(userUnitPath, 0o600);
674
+ writeFileSync(envPath, `CODOR_TOKEN=${token}\nPATH=${servicePath}\n`, { encoding: 'utf8', mode: 0o600 });
675
+ chmodSync(envPath, 0o600);
676
+ exec('systemctl', ['--user', 'daemon-reload']);
677
+ exec('systemctl', ['--user', 'enable', '--now', 'codor.service']);
678
+ try {
679
+ const linger = exec('loginctl', ['show-user', options.env.USER ?? '', '-p', 'Linger', '--value']);
680
+ if (linger.trim() !== 'yes')
681
+ log(`for boot startup: loginctl enable-linger ${options.env.USER ?? '$USER'}`);
682
+ }
683
+ catch {
684
+ log(`check lingering: loginctl enable-linger ${options.env.USER ?? '$USER'}`);
685
+ }
686
+ }
687
+ else if (platform === 'darwin') {
688
+ const token = readFileSync(tokenPath, 'utf8').trim();
689
+ mkdirSync(launchAgentDir, { recursive: true });
690
+ mkdirSync(logDir, { recursive: true, mode: 0o700 });
691
+ chmodSync(logDir, 0o700);
692
+ writeFileSync(launchAgentPath, renderLaunchAgent({
693
+ dataDir, logDir, nodePath, runtime: serviceRuntime, servicePath, token,
694
+ }), { encoding: 'utf8', mode: 0o600 });
695
+ chmodSync(launchAgentPath, 0o600);
696
+ await bootstrapLaunchAgent({
697
+ exec, probe, sleep,
698
+ exists: overrides.exists,
699
+ domain: launchDomain,
700
+ target: launchTarget,
701
+ plistPath: launchAgentPath,
702
+ nodePath,
703
+ cliEntrypoint: serviceRuntime.cliEntrypoint,
704
+ endpoint: localEndpoint,
705
+ log,
706
+ });
707
+ }
708
+ else {
709
+ mkdirSync(logDir, { recursive: true });
710
+ writeFileSync(windowsScriptPath, windowsScript, 'utf8');
711
+ writeFileSync(windowsTaskPath, Buffer.from(`${windowsTask}`, 'utf16le'));
712
+ exec('schtasks', ['/Create', '/TN', 'Codor Switchboard', '/XML', windowsTaskPath, '/F']);
713
+ exec('schtasks', ['/Run', '/TN', 'Codor Switchboard']);
714
+ }
715
+ await waitForCodor(localEndpoint, probe, sleep);
716
+ log('Codor answered its pairing status check');
717
+ if (systemdBindHost === '0.0.0.0')
718
+ log('WSL2 NAT is reachable through Windows localhost');
719
+ return 'service enabled and answering';
720
+ };
721
+ const pairStep = (log) => {
722
+ if (pairing === undefined) {
723
+ const crypto = new CryptoVault(dataDir);
724
+ try {
725
+ const offer = crypto.pairing.issue(endpoint);
726
+ const url = pairingUrl(offer);
727
+ pairing = { code: offer.pairing_code, expires: offer.expires_at, qr: renderQr(url), url };
728
+ }
729
+ finally {
730
+ crypto.close();
731
+ }
732
+ }
733
+ log(`pairing code ${pairing.code}`);
734
+ return `code ${pairing.code}`;
735
+ };
736
+ const cardColumns = overrides.streams?.output?.columns ?? process.stdout.columns ?? 80;
737
+ // Rows available to the pairing card once the frame's header, heading, and the
738
+ // reserved Finish control are set aside; the card omits its QR to fit.
739
+ const cardRows = overrides.streams?.output?.rows ?? process.stdout.rows ?? 24;
740
+ const cardMaxRows = Math.max(8, cardRows - 8);
741
+ const emitPairing = () => {
742
+ options.out(renderPairingCard({
743
+ code: pairing.code,
744
+ url: pairing.url,
745
+ expires: pairing.expires,
746
+ qr: pairing.qr,
747
+ instruction: 'Scan the QR or enter the code in your browser to finish pairing.',
748
+ }, cardColumns));
749
+ };
750
+ if (interactive) {
751
+ const session = new SetupSession({ version, streams: overrides.streams });
752
+ const existingInstall = detectInstalledRuntime(dataDir, installIo);
753
+ const installMenu = existingInstall === undefined
754
+ ? {
755
+ message: 'Install Codor on this computer?',
756
+ options: [
757
+ { id: 'install', label: 'Install Codor', description: 'Copy a durable runtime, then create your private config, data, and token.', available: true },
758
+ { id: 'later', label: 'Not now', description: 'Do not change anything on this computer.', available: true },
759
+ ],
760
+ }
761
+ : existingInstall.version === version
762
+ ? {
763
+ message: `Codor ${version} is already installed. Continue?`,
764
+ options: [
765
+ { id: 'continue', label: 'Continue', description: 'Use the installed runtime and ensure your private files.', available: true },
766
+ { id: 'update', label: 'Reinstall', description: 'Re-copy the durable runtime.', available: true },
767
+ { id: 'later', label: 'Not now', description: 'Do not change anything.', available: true },
768
+ ],
769
+ }
770
+ : {
771
+ message: `Update Codor from ${existingInstall.version} to ${version}?`,
772
+ options: [
773
+ { id: 'update', label: 'Update Codor', description: 'Re-copy the durable runtime at the new version.', available: true },
774
+ { id: 'keep', label: 'Keep current', description: `Keep ${existingInstall.version} and ensure your private files.`, available: true },
775
+ { id: 'later', label: 'Not now', description: 'Do not change anything.', available: true },
776
+ ],
777
+ };
778
+ const steps = [
779
+ { title: stepTitles[0], description: 'Read-only — nothing on your computer changes.', run: async ({ log }) => checkStep(log) },
780
+ {
781
+ title: stepTitles[1],
782
+ description: 'Set up Codor in a stable per-user location.',
783
+ // Consent gate: no runtime is copied and no files are created until an
784
+ // affirmative choice; "Not now" leaves the computer unchanged.
785
+ menu: installMenu,
786
+ run: async ({ log, choice }) => (choice === 'later'
787
+ ? { skip: true, summary: '(run codor install when ready)', skipFollowing: true }
788
+ : installStep(log, choice === 'update' ? 'update' : choice === 'keep' ? 'keep' : 'ensure')),
789
+ },
790
+ {
791
+ title: stepTitles[2],
792
+ description: 'Choose where you will use Codor.',
793
+ menu: {
794
+ message: 'Where will you use Codor?',
795
+ options: [
796
+ { id: 'here', label: 'On this computer only', description: 'Reach Codor from this computer.', available: true },
797
+ { id: 'remote', label: 'On this computer and remotely', description: 'Also reach Codor from your other devices, over Tailscale.', available: true },
798
+ ],
799
+ },
800
+ run: async ({ log, choice, choose }) => whereStep(log, choice, choose),
801
+ },
802
+ {
803
+ title: stepTitles[3],
804
+ description: 'Install and start the private background service.',
805
+ // Consent gate: nothing is installed or started until Start is chosen.
806
+ menu: {
807
+ message: 'Run Codor in the background?',
808
+ options: [
809
+ { id: 'start', label: 'Start Codor', description: 'Install and start the private background service.', available: true },
810
+ { id: 'later', label: 'Not now', description: 'Do not install or start anything yet.', available: true },
811
+ ],
812
+ },
813
+ run: async ({ log, choice }) => (choice === 'start'
814
+ ? startStep(log)
815
+ : { skip: true, summary: '(run codor install when ready)', skipFollowing: true }),
816
+ },
817
+ {
818
+ title: stepTitles[4],
819
+ description: 'Connect a browser with a short-lived pairing code.',
820
+ // Consent gate: no pairing code is minted until Create is chosen.
821
+ menu: {
822
+ message: 'Pair a browser now?',
823
+ options: [
824
+ { id: 'create', label: 'Create a pairing code', description: 'Mint a ten-minute code and QR now.', available: true },
825
+ { id: 'later', label: 'Set this up later', description: 'Keep the service running and pair from a browser later.', available: true },
826
+ ],
827
+ },
828
+ run: async ({ log, choice, presentResult }) => {
829
+ if (choice !== 'create')
830
+ return { skip: true, summary: '(run codor pair later)' };
831
+ const summary = pairStep(log);
832
+ // Replace the question in-frame with the QR/code result card, so it is
833
+ // visible before Finish closes the installer.
834
+ presentResult(renderPairingCard({
835
+ code: pairing.code,
836
+ url: pairing.url,
837
+ expires: pairing.expires,
838
+ qr: pairing.qr,
839
+ instruction: 'Scan the QR or enter the code in your browser to finish pairing.',
840
+ }, cardColumns, cardMaxRows));
841
+ return summary;
842
+ },
843
+ },
844
+ ];
845
+ await session.run(steps);
846
+ const harnesses = detected.map(({ harness }) => harness);
847
+ if (!serviceStarted) {
848
+ // Start was declined: nothing was installed, and pairing was skipped too.
849
+ session.finish({ headline: 'Setup paused - Codor is not running.', harnesses, nextAction: 'Run `codor install` when you are ready to install and start Codor.' });
850
+ }
851
+ else if (pairing === undefined) {
852
+ // The service is up but the operator declined pairing.
853
+ session.finish({ headline: 'Codor is running.', endpoint, harnesses, nextAction: 'Run `codor pair` when you want to connect a browser.' });
854
+ }
855
+ else {
856
+ // The pairing result card is already visible in-frame; keep it as the
857
+ // final frame and close without re-emitting it.
858
+ session.finish();
859
+ }
860
+ }
861
+ else {
862
+ const linear = (index) => (message) => options.out(`[${String(index + 1)}/5] ${message}`);
863
+ options.out(`[1/5] ${stepTitles[0]}`);
864
+ checkStep(linear(0));
865
+ options.out(`[2/5] ${stepTitles[1]}`);
866
+ installStep(linear(1));
867
+ options.out(`[3/5] ${stepTitles[2]}`);
868
+ chooseStep(linear(2), options.access);
869
+ options.out(`[4/5] ${stepTitles[3]}`);
870
+ await startStep(linear(3));
871
+ options.out(`[5/5] ${stepTitles[4]}`);
872
+ pairStep(linear(4));
873
+ emitPairing();
874
+ }
875
+ }
876
+ // harn:end setup-preserves-private-platform-service
877
+ // harn:end windows-setup-installs-private-task-service
878
+ //# sourceMappingURL=setup.js.map