aimux-cli 0.1.16 → 0.1.19

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 (357) hide show
  1. package/README.md +184 -67
  2. package/bin/aimux-dev +10 -0
  3. package/dist/agent-events.js +0 -1
  4. package/dist/agent-output-parser.js +0 -1
  5. package/dist/agent-prompt-delivery.js +0 -1
  6. package/dist/agent-tracker.js +0 -1
  7. package/dist/agent-watcher.js +0 -1
  8. package/dist/alert-display.d.ts +21 -0
  9. package/dist/alert-display.js +85 -0
  10. package/dist/atomic-write.js +0 -1
  11. package/dist/attachment-store.d.ts +0 -7
  12. package/dist/attachment-store.js +2 -87
  13. package/dist/builtin-metadata-watchers.js +4 -5
  14. package/dist/claude-hooks.d.ts +1 -0
  15. package/dist/claude-hooks.js +25 -1
  16. package/dist/config.d.ts +19 -13
  17. package/dist/config.js +28 -15
  18. package/dist/connection-targets.d.ts +8 -0
  19. package/dist/connection-targets.js +27 -0
  20. package/dist/context/compactor.js +0 -1
  21. package/dist/context/context-bridge.js +0 -1
  22. package/dist/context/context-file.js +0 -1
  23. package/dist/context/history.js +0 -1
  24. package/dist/credentials.d.ts +12 -0
  25. package/dist/credentials.js +48 -0
  26. package/dist/daemon.d.ts +23 -0
  27. package/dist/daemon.js +391 -67
  28. package/dist/dashboard/command-spec.js +0 -1
  29. package/dist/dashboard/feedback.js +0 -1
  30. package/dist/dashboard/index.d.ts +13 -10
  31. package/dist/dashboard/index.js +3 -27
  32. package/dist/dashboard/operation-failures.js +0 -1
  33. package/dist/dashboard/order.d.ts +22 -0
  34. package/dist/dashboard/order.js +54 -0
  35. package/dist/dashboard/pending-actions.d.ts +39 -10
  36. package/dist/dashboard/pending-actions.js +166 -37
  37. package/dist/dashboard/quick-jump.d.ts +2 -1
  38. package/dist/dashboard/quick-jump.js +7 -5
  39. package/dist/dashboard/runtime-evidence.js +0 -1
  40. package/dist/dashboard/session-actions.d.ts +4 -4
  41. package/dist/dashboard/session-actions.js +1 -2
  42. package/dist/dashboard/session-registry.d.ts +4 -3
  43. package/dist/dashboard/session-registry.js +16 -51
  44. package/dist/dashboard/sort.js +0 -1
  45. package/dist/dashboard/state.d.ts +1 -1
  46. package/dist/dashboard/state.js +0 -1
  47. package/dist/dashboard/targets.js +0 -1
  48. package/dist/dashboard/ui-state-store.d.ts +16 -1
  49. package/dist/dashboard/ui-state-store.js +73 -3
  50. package/dist/debug-state.d.ts +97 -0
  51. package/dist/debug-state.js +540 -0
  52. package/dist/debug.d.ts +38 -0
  53. package/dist/debug.js +219 -16
  54. package/dist/default-plugins/gh-pr-context.d.ts +2 -1
  55. package/dist/default-plugins/gh-pr-context.js +17 -12
  56. package/dist/default-plugins/transcript-length.js +15 -3
  57. package/dist/fast-control.js +37 -20
  58. package/dist/hotkeys.js +0 -1
  59. package/dist/http-client.js +31 -3
  60. package/dist/key-parser.js +0 -1
  61. package/dist/last-used.js +0 -1
  62. package/dist/local-ui-server.d.ts +22 -0
  63. package/dist/local-ui-server.js +185 -0
  64. package/dist/login-flow.d.ts +7 -0
  65. package/dist/login-flow.js +119 -0
  66. package/dist/main.js +821 -152
  67. package/dist/managed-launch-env.js +14 -1
  68. package/dist/metadata-server.d.ts +36 -36
  69. package/dist/metadata-server.js +638 -138
  70. package/dist/metadata-store.d.ts +4 -1
  71. package/dist/metadata-store.js +30 -3
  72. package/dist/multiplexer/agent-io-methods.d.ts +2 -10
  73. package/dist/multiplexer/agent-io-methods.js +12 -44
  74. package/dist/multiplexer/archives.js +8 -10
  75. package/dist/multiplexer/dashboard-actions-methods.js +0 -1
  76. package/dist/multiplexer/dashboard-control.js +45 -14
  77. package/dist/multiplexer/dashboard-interaction.d.ts +8 -2
  78. package/dist/multiplexer/dashboard-interaction.js +187 -29
  79. package/dist/multiplexer/dashboard-model.d.ts +10 -3
  80. package/dist/multiplexer/dashboard-model.js +417 -36
  81. package/dist/multiplexer/dashboard-ops.d.ts +9 -7
  82. package/dist/multiplexer/dashboard-ops.js +178 -69
  83. package/dist/multiplexer/dashboard-state-methods.d.ts +2 -1
  84. package/dist/multiplexer/dashboard-state-methods.js +3 -3
  85. package/dist/multiplexer/dashboard-tail-methods.d.ts +22 -10
  86. package/dist/multiplexer/dashboard-tail-methods.js +164 -48
  87. package/dist/multiplexer/dashboard-view-methods.d.ts +1 -1
  88. package/dist/multiplexer/dashboard-view-methods.js +23 -9
  89. package/dist/multiplexer/graveyard-view-model.d.ts +9 -1
  90. package/dist/multiplexer/graveyard-view-model.js +39 -1
  91. package/dist/multiplexer/index.d.ts +15 -12
  92. package/dist/multiplexer/index.js +64 -44
  93. package/dist/multiplexer/navigation.js +0 -1
  94. package/dist/multiplexer/notifications.js +107 -25
  95. package/dist/multiplexer/persistence-methods.d.ts +31 -4
  96. package/dist/multiplexer/persistence-methods.js +304 -309
  97. package/dist/multiplexer/runtime-lifecycle-methods.d.ts +8 -10
  98. package/dist/multiplexer/runtime-lifecycle-methods.js +104 -87
  99. package/dist/multiplexer/runtime-state.d.ts +8 -10
  100. package/dist/multiplexer/runtime-state.js +82 -146
  101. package/dist/multiplexer/runtime-sync.d.ts +2 -10
  102. package/dist/multiplexer/runtime-sync.js +3 -19
  103. package/dist/multiplexer/service-state-snapshot.d.ts +2 -4
  104. package/dist/multiplexer/service-state-snapshot.js +4 -52
  105. package/dist/multiplexer/services.d.ts +1 -0
  106. package/dist/multiplexer/services.js +55 -6
  107. package/dist/multiplexer/session-capture.d.ts +1 -0
  108. package/dist/multiplexer/session-capture.js +23 -0
  109. package/dist/multiplexer/session-launch.d.ts +4 -1
  110. package/dist/multiplexer/session-launch.js +152 -64
  111. package/dist/multiplexer/session-runtime-core.d.ts +8 -20
  112. package/dist/multiplexer/session-runtime-core.js +40 -136
  113. package/dist/multiplexer/subscreens.js +10 -4
  114. package/dist/multiplexer/tool-picker.js +0 -1
  115. package/dist/multiplexer/worktree-graveyard.d.ts +0 -1
  116. package/dist/multiplexer/worktree-graveyard.js +15 -17
  117. package/dist/multiplexer/worktrees.js +96 -41
  118. package/dist/notification-context.js +8 -5
  119. package/dist/notifications.js +163 -102
  120. package/dist/notify.d.ts +4 -0
  121. package/dist/notify.js +14 -1
  122. package/dist/orchestration-actions.js +0 -1
  123. package/dist/orchestration-routing.js +0 -1
  124. package/dist/orchestration.js +0 -1
  125. package/dist/osc-notifications.js +0 -1
  126. package/dist/paths.d.ts +32 -7
  127. package/dist/paths.js +82 -59
  128. package/dist/pending-actions.d.ts +5 -0
  129. package/dist/pending-actions.js +13 -0
  130. package/dist/plugin-runtime.js +9 -3
  131. package/dist/project-events.d.ts +1 -10
  132. package/dist/project-events.js +0 -11
  133. package/dist/project-scanner.d.ts +2 -3
  134. package/dist/project-scanner.js +58 -130
  135. package/dist/project-service-manifest.d.ts +1 -3
  136. package/dist/project-service-manifest.js +1 -4
  137. package/dist/recency.js +0 -1
  138. package/dist/recorder.js +0 -1
  139. package/dist/relay-client.d.ts +30 -0
  140. package/dist/relay-client.js +190 -0
  141. package/dist/remote-access.d.ts +16 -0
  142. package/dist/remote-access.js +90 -0
  143. package/dist/runtime-core/exchange-derived.d.ts +2 -0
  144. package/dist/runtime-core/exchange-derived.js +153 -0
  145. package/dist/runtime-core/exchange-import.d.ts +24 -0
  146. package/dist/runtime-core/exchange-import.js +317 -0
  147. package/dist/runtime-core/exchange-store.d.ts +157 -0
  148. package/dist/runtime-core/exchange-store.js +452 -0
  149. package/dist/runtime-core/topology-services.d.ts +38 -0
  150. package/dist/runtime-core/topology-services.js +170 -0
  151. package/dist/runtime-core/topology-sessions.d.ts +52 -0
  152. package/dist/runtime-core/topology-sessions.js +238 -0
  153. package/dist/runtime-core/topology-store.d.ts +171 -0
  154. package/dist/runtime-core/topology-store.js +419 -0
  155. package/dist/runtime-core/topology-worktrees.d.ts +60 -0
  156. package/dist/runtime-core/topology-worktrees.js +199 -0
  157. package/dist/runtime-migration.d.ts +69 -0
  158. package/dist/runtime-migration.js +398 -0
  159. package/dist/session-bootstrap.d.ts +8 -6
  160. package/dist/session-bootstrap.js +51 -159
  161. package/dist/session-runtime.d.ts +2 -0
  162. package/dist/session-runtime.js +1 -1
  163. package/dist/session-semantics.d.ts +12 -4
  164. package/dist/session-semantics.js +14 -1
  165. package/dist/shell-args.js +0 -1
  166. package/dist/shell-hooks.js +32 -11
  167. package/dist/shell-state.d.ts +2 -0
  168. package/dist/shell-state.js +26 -2
  169. package/dist/status-detector.js +0 -1
  170. package/dist/statusline-model.d.ts +10 -2
  171. package/dist/statusline-model.js +106 -31
  172. package/dist/task-workflow.d.ts +6 -9
  173. package/dist/task-workflow.js +37 -85
  174. package/dist/tasks.d.ts +6 -33
  175. package/dist/tasks.js +46 -89
  176. package/dist/team.d.ts +29 -0
  177. package/dist/team.js +40 -1
  178. package/dist/terminal-host.js +0 -1
  179. package/dist/threads.d.ts +6 -35
  180. package/dist/threads.js +89 -99
  181. package/dist/tmux/doctor.js +0 -1
  182. package/dist/tmux/inbox-popup.js +37 -16
  183. package/dist/tmux/runtime-manager.d.ts +3 -0
  184. package/dist/tmux/runtime-manager.js +21 -5
  185. package/dist/tmux/session-transport.js +0 -1
  186. package/dist/tmux/statusline-cache.js +0 -1
  187. package/dist/tmux/statusline.js +49 -10
  188. package/dist/tmux/switcher.js +0 -1
  189. package/dist/tmux/window-open.js +1 -3
  190. package/dist/tool-output-watchers.d.ts +0 -18
  191. package/dist/tool-output-watchers.js +0 -323
  192. package/dist/tui/render/box.js +0 -1
  193. package/dist/tui/render/text.js +0 -1
  194. package/dist/tui/screens/dashboard-renderers.js +37 -26
  195. package/dist/tui/screens/overlay-renderers.d.ts +2 -0
  196. package/dist/tui/screens/overlay-renderers.js +37 -2
  197. package/dist/tui/screens/subscreen-renderers.js +7 -1
  198. package/dist/workflow.js +0 -1
  199. package/dist/worktree.js +17 -1
  200. package/dist-ui/_expo/static/css/web-30453ede1678c16acb08b97e83e8646d.css +1 -0
  201. package/dist-ui/_expo/static/js/web/entry-477c745b2adc79367a4380ecf07d9ff6.js +14620 -0
  202. package/dist-ui/assets/assets/images/icon.a5413dcd2e811c9f2317d01a28118d8a.png +0 -0
  203. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
  204. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
  205. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
  206. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
  207. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
  208. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
  209. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
  210. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
  211. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
  212. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
  213. package/dist-ui/assets/node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
  214. package/dist-ui/assets/node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
  215. package/dist-ui/assets/node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
  216. package/dist-ui/assets/node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
  217. package/dist-ui/assets/node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
  218. package/dist-ui/assets/node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
  219. package/dist-ui/assets/node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
  220. package/dist-ui/assets/node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
  221. package/dist-ui/favicon.ico +0 -0
  222. package/dist-ui/index.html +38 -0
  223. package/dist-ui/metadata.json +1 -0
  224. package/package.json +29 -12
  225. package/dist/agent-events.js.map +0 -1
  226. package/dist/agent-message-parts.d.ts +0 -17
  227. package/dist/agent-message-parts.js +0 -31
  228. package/dist/agent-message-parts.js.map +0 -1
  229. package/dist/agent-output-parser.js.map +0 -1
  230. package/dist/agent-prompt-delivery.js.map +0 -1
  231. package/dist/agent-tracker.js.map +0 -1
  232. package/dist/agent-watcher.js.map +0 -1
  233. package/dist/atomic-write.js.map +0 -1
  234. package/dist/attachment-store.js.map +0 -1
  235. package/dist/builtin-metadata-watchers.js.map +0 -1
  236. package/dist/claude-hooks.js.map +0 -1
  237. package/dist/config.js.map +0 -1
  238. package/dist/context/compactor.js.map +0 -1
  239. package/dist/context/context-bridge.js.map +0 -1
  240. package/dist/context/context-file.js.map +0 -1
  241. package/dist/context/history.js.map +0 -1
  242. package/dist/daemon.js.map +0 -1
  243. package/dist/dashboard/command-spec.js.map +0 -1
  244. package/dist/dashboard/feedback.js.map +0 -1
  245. package/dist/dashboard/index.js.map +0 -1
  246. package/dist/dashboard/operation-failures.js.map +0 -1
  247. package/dist/dashboard/pending-actions.js.map +0 -1
  248. package/dist/dashboard/quick-jump.js.map +0 -1
  249. package/dist/dashboard/runtime-evidence.js.map +0 -1
  250. package/dist/dashboard/session-actions.js.map +0 -1
  251. package/dist/dashboard/session-registry.js.map +0 -1
  252. package/dist/dashboard/sort.js.map +0 -1
  253. package/dist/dashboard/state.js.map +0 -1
  254. package/dist/dashboard/targets.js.map +0 -1
  255. package/dist/dashboard/ui-state-store.js.map +0 -1
  256. package/dist/debug.js.map +0 -1
  257. package/dist/default-plugins/gh-pr-context.js.map +0 -1
  258. package/dist/default-plugins/transcript-length.js.map +0 -1
  259. package/dist/fast-control.js.map +0 -1
  260. package/dist/hotkeys.js.map +0 -1
  261. package/dist/http-client.js.map +0 -1
  262. package/dist/instance-directory.d.ts +0 -32
  263. package/dist/instance-directory.js +0 -82
  264. package/dist/instance-directory.js.map +0 -1
  265. package/dist/instance-registry.d.ts +0 -39
  266. package/dist/instance-registry.js +0 -208
  267. package/dist/instance-registry.js.map +0 -1
  268. package/dist/key-parser.js.map +0 -1
  269. package/dist/last-used.js.map +0 -1
  270. package/dist/main.js.map +0 -1
  271. package/dist/managed-launch-env.js.map +0 -1
  272. package/dist/metadata-server.js.map +0 -1
  273. package/dist/metadata-store.js.map +0 -1
  274. package/dist/multiplexer/agent-io-methods.js.map +0 -1
  275. package/dist/multiplexer/archives.js.map +0 -1
  276. package/dist/multiplexer/dashboard-actions-methods.js.map +0 -1
  277. package/dist/multiplexer/dashboard-control.js.map +0 -1
  278. package/dist/multiplexer/dashboard-interaction.js.map +0 -1
  279. package/dist/multiplexer/dashboard-model.js.map +0 -1
  280. package/dist/multiplexer/dashboard-ops.js.map +0 -1
  281. package/dist/multiplexer/dashboard-state-methods.js.map +0 -1
  282. package/dist/multiplexer/dashboard-tail-methods.js.map +0 -1
  283. package/dist/multiplexer/dashboard-view-methods.js.map +0 -1
  284. package/dist/multiplexer/graveyard-view-model.js.map +0 -1
  285. package/dist/multiplexer/index.js.map +0 -1
  286. package/dist/multiplexer/navigation.js.map +0 -1
  287. package/dist/multiplexer/notifications.js.map +0 -1
  288. package/dist/multiplexer/persistence-methods.js.map +0 -1
  289. package/dist/multiplexer/runtime-lifecycle-methods.js.map +0 -1
  290. package/dist/multiplexer/runtime-state.js.map +0 -1
  291. package/dist/multiplexer/runtime-sync.js.map +0 -1
  292. package/dist/multiplexer/service-state-snapshot.js.map +0 -1
  293. package/dist/multiplexer/services.js.map +0 -1
  294. package/dist/multiplexer/session-actions.d.ts +0 -40
  295. package/dist/multiplexer/session-actions.js +0 -110
  296. package/dist/multiplexer/session-actions.js.map +0 -1
  297. package/dist/multiplexer/session-launch.js.map +0 -1
  298. package/dist/multiplexer/session-runtime-core.js.map +0 -1
  299. package/dist/multiplexer/subscreens.js.map +0 -1
  300. package/dist/multiplexer/tool-picker.js.map +0 -1
  301. package/dist/multiplexer/worktree-graveyard.js.map +0 -1
  302. package/dist/multiplexer/worktrees.js.map +0 -1
  303. package/dist/notification-context.js.map +0 -1
  304. package/dist/notifications.js.map +0 -1
  305. package/dist/notify.js.map +0 -1
  306. package/dist/orchestration-actions.js.map +0 -1
  307. package/dist/orchestration-dispatcher.d.ts +0 -25
  308. package/dist/orchestration-dispatcher.js +0 -59
  309. package/dist/orchestration-dispatcher.js.map +0 -1
  310. package/dist/orchestration-routing.js.map +0 -1
  311. package/dist/orchestration.js.map +0 -1
  312. package/dist/osc-notifications.js.map +0 -1
  313. package/dist/paths.js.map +0 -1
  314. package/dist/plugin-runtime.js.map +0 -1
  315. package/dist/project-events.js.map +0 -1
  316. package/dist/project-scanner.js.map +0 -1
  317. package/dist/project-service-manifest.js.map +0 -1
  318. package/dist/recency.js.map +0 -1
  319. package/dist/recorder.js.map +0 -1
  320. package/dist/session-bootstrap.js.map +0 -1
  321. package/dist/session-input-operations.d.ts +0 -19
  322. package/dist/session-input-operations.js +0 -46
  323. package/dist/session-input-operations.js.map +0 -1
  324. package/dist/session-message-history.d.ts +0 -27
  325. package/dist/session-message-history.js +0 -105
  326. package/dist/session-message-history.js.map +0 -1
  327. package/dist/session-runtime.js.map +0 -1
  328. package/dist/session-semantics.js.map +0 -1
  329. package/dist/shell-args.js.map +0 -1
  330. package/dist/shell-hooks.js.map +0 -1
  331. package/dist/shell-state.js.map +0 -1
  332. package/dist/status-detector.js.map +0 -1
  333. package/dist/statusline-model.js.map +0 -1
  334. package/dist/task-dispatcher.d.ts +0 -64
  335. package/dist/task-dispatcher.js +0 -213
  336. package/dist/task-dispatcher.js.map +0 -1
  337. package/dist/task-workflow.js.map +0 -1
  338. package/dist/tasks.js.map +0 -1
  339. package/dist/team.js.map +0 -1
  340. package/dist/terminal-host.js.map +0 -1
  341. package/dist/threads.js.map +0 -1
  342. package/dist/tmux/doctor.js.map +0 -1
  343. package/dist/tmux/inbox-popup.js.map +0 -1
  344. package/dist/tmux/runtime-manager.js.map +0 -1
  345. package/dist/tmux/session-transport.js.map +0 -1
  346. package/dist/tmux/statusline-cache.js.map +0 -1
  347. package/dist/tmux/statusline.js.map +0 -1
  348. package/dist/tmux/switcher.js.map +0 -1
  349. package/dist/tmux/window-open.js.map +0 -1
  350. package/dist/tool-output-watchers.js.map +0 -1
  351. package/dist/tui/render/box.js.map +0 -1
  352. package/dist/tui/render/text.js.map +0 -1
  353. package/dist/tui/screens/dashboard-renderers.js.map +0 -1
  354. package/dist/tui/screens/overlay-renderers.js.map +0 -1
  355. package/dist/tui/screens/subscreen-renderers.js.map +0 -1
  356. package/dist/workflow.js.map +0 -1
  357. package/dist/worktree.js.map +0 -1
@@ -0,0 +1,185 @@
1
+ import { createReadStream, existsSync, statSync } from "node:fs";
2
+ import { createServer } from "node:http";
3
+ import { extname, resolve as pathResolve, sep } from "node:path";
4
+ import { platform } from "node:os";
5
+ import { spawn } from "node:child_process";
6
+ import { fileURLToPath } from "node:url";
7
+ export const DEFAULT_LOCAL_UI_HOST = "127.0.0.1";
8
+ export const DEFAULT_LOCAL_UI_PORT = 43192;
9
+ const MIME_TYPES = {
10
+ ".css": "text/css; charset=utf-8",
11
+ ".html": "text/html; charset=utf-8",
12
+ ".ico": "image/x-icon",
13
+ ".js": "text/javascript; charset=utf-8",
14
+ ".json": "application/json; charset=utf-8",
15
+ ".map": "application/json; charset=utf-8",
16
+ ".png": "image/png",
17
+ ".svg": "image/svg+xml",
18
+ ".txt": "text/plain; charset=utf-8",
19
+ ".webp": "image/webp",
20
+ ".woff": "font/woff",
21
+ ".woff2": "font/woff2",
22
+ };
23
+ function packageRoot() {
24
+ return pathResolve(fileURLToPath(import.meta.url), "..", "..");
25
+ }
26
+ export function resolveDefaultLocalUiRoot() {
27
+ return pathResolve(packageRoot(), "dist-ui");
28
+ }
29
+ function isLoopbackHost(host) {
30
+ return host === "localhost" || host === "::1" || host === "127.0.0.1";
31
+ }
32
+ function formatHostForUrl(host) {
33
+ return host.includes(":") ? `[${host}]` : host;
34
+ }
35
+ function send(res, status, body) {
36
+ res.writeHead(status, {
37
+ "Content-Type": "text/plain; charset=utf-8",
38
+ "Cache-Control": "no-store",
39
+ });
40
+ res.end(body);
41
+ }
42
+ function setCommonHeaders(res) {
43
+ res.setHeader("X-Content-Type-Options", "nosniff");
44
+ }
45
+ function localConfigJavascript(config) {
46
+ return `window.__AIMUX_LOCAL_CONFIG__=${JSON.stringify(config)};\n`;
47
+ }
48
+ function isInsideRoot(root, target) {
49
+ const resolvedRoot = pathResolve(root);
50
+ const resolvedTarget = pathResolve(target);
51
+ return resolvedTarget === resolvedRoot || resolvedTarget.startsWith(`${resolvedRoot}${sep}`);
52
+ }
53
+ function resolveRequestPath(uiRoot, req) {
54
+ const rawPath = (req.url ?? "/").split(/[?#]/, 1)[0] ?? "/";
55
+ try {
56
+ if (decodeURIComponent(rawPath).split("/").includes(".."))
57
+ return null;
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ const url = new URL(req.url ?? "/", "http://local.aimux");
63
+ let pathname;
64
+ try {
65
+ pathname = decodeURIComponent(url.pathname);
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ if (pathname.includes("\0"))
71
+ return null;
72
+ if (pathname === "/")
73
+ pathname = "/index.html";
74
+ const target = pathResolve(uiRoot, `.${pathname}`);
75
+ if (!isInsideRoot(uiRoot, target))
76
+ return null;
77
+ return target;
78
+ }
79
+ function serveFile(req, res, path) {
80
+ const ext = extname(path).toLowerCase();
81
+ const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
82
+ const isIndex = ext === ".html";
83
+ res.writeHead(200, {
84
+ "Content-Type": contentType,
85
+ "Cache-Control": isIndex ? "no-cache" : "public, max-age=31536000, immutable",
86
+ });
87
+ if (req.method === "HEAD") {
88
+ res.end();
89
+ return;
90
+ }
91
+ createReadStream(path)
92
+ .on("error", () => {
93
+ if (!res.headersSent)
94
+ send(res, 500, "Internal server error");
95
+ else
96
+ res.destroy();
97
+ })
98
+ .pipe(res);
99
+ }
100
+ function requestHandler(uiRoot, config) {
101
+ return (req, res) => {
102
+ setCommonHeaders(res);
103
+ if (req.method !== "GET" && req.method !== "HEAD") {
104
+ send(res, 405, "Method not allowed");
105
+ return;
106
+ }
107
+ const url = new URL(req.url ?? "/", "http://local.aimux");
108
+ if (url.pathname === "/aimux-local-config.js") {
109
+ res.writeHead(200, {
110
+ "Content-Type": "text/javascript; charset=utf-8",
111
+ "Cache-Control": "no-store",
112
+ });
113
+ res.end(req.method === "HEAD" ? undefined : localConfigJavascript(config));
114
+ return;
115
+ }
116
+ const target = resolveRequestPath(uiRoot, req);
117
+ if (!target) {
118
+ send(res, 403, "Forbidden");
119
+ return;
120
+ }
121
+ if (existsSync(target) && statSync(target).isFile()) {
122
+ serveFile(req, res, target);
123
+ return;
124
+ }
125
+ if (!extname(new URL(req.url ?? "/", "http://local.aimux").pathname)) {
126
+ const indexPath = pathResolve(uiRoot, "index.html");
127
+ if (existsSync(indexPath)) {
128
+ serveFile(req, res, indexPath);
129
+ return;
130
+ }
131
+ }
132
+ send(res, 404, "Not found");
133
+ };
134
+ }
135
+ export async function startLocalUiServer(options) {
136
+ const host = options.host ?? DEFAULT_LOCAL_UI_HOST;
137
+ const port = options.port ?? DEFAULT_LOCAL_UI_PORT;
138
+ if (!isLoopbackHost(host)) {
139
+ throw new Error(`Local UI host must be loopback (127.0.0.1, localhost, or ::1), got ${host}`);
140
+ }
141
+ const uiRoot = pathResolve(options.uiRoot ?? resolveDefaultLocalUiRoot());
142
+ const indexPath = pathResolve(uiRoot, "index.html");
143
+ if (!existsSync(indexPath)) {
144
+ throw new Error(`Local UI build not found at ${uiRoot}. Run yarn build:ui:local first.`);
145
+ }
146
+ const server = createServer(requestHandler(uiRoot, options.config));
147
+ await new Promise((resolve, reject) => {
148
+ const onError = (error) => {
149
+ server.off("listening", onListening);
150
+ reject(error);
151
+ };
152
+ const onListening = () => {
153
+ server.off("error", onError);
154
+ resolve();
155
+ };
156
+ server.once("error", onError);
157
+ server.once("listening", onListening);
158
+ server.listen(port, host);
159
+ });
160
+ const address = server.address();
161
+ const actualPort = typeof address === "object" && address ? address.port : port;
162
+ const url = `http://${formatHostForUrl(host)}:${actualPort}`;
163
+ return {
164
+ host,
165
+ port: actualPort,
166
+ url,
167
+ uiRoot,
168
+ close: () => closeServer(server),
169
+ };
170
+ }
171
+ function closeServer(server) {
172
+ return new Promise((resolve, reject) => {
173
+ server.close((error) => (error ? reject(error) : resolve()));
174
+ });
175
+ }
176
+ export function openUrlInBrowser(url) {
177
+ const os = platform();
178
+ const command = os === "darwin" ? "open" : os === "win32" ? "cmd" : "xdg-open";
179
+ const args = os === "win32" ? ["/c", "start", "", url] : [url];
180
+ const child = spawn(command, args, {
181
+ detached: true,
182
+ stdio: "ignore",
183
+ });
184
+ child.unref();
185
+ }
@@ -0,0 +1,7 @@
1
+ export interface LoginOptions {
2
+ webAppUrl?: string;
3
+ action?: "security-unlock";
4
+ }
5
+ export declare function runLoginFlow(opts?: LoginOptions): Promise<{
6
+ userId: string;
7
+ }>;
@@ -0,0 +1,119 @@
1
+ // Browser-based `aimux login` flow.
2
+ //
3
+ // Mirrors the `gh auth login` / `vercel login` pattern:
4
+ // 1. Spin up a localhost callback server on an ephemeral port.
5
+ // 2. Open the browser to the web app's /cli-auth page, passing the callback.
6
+ // 3. The web app signs the user in via Clerk, calls the relay to mint a
7
+ // long-lived daemon token, and redirects to the callback with the token.
8
+ // 4. We capture the token, persist it, and shut the server down.
9
+ import { createServer } from "node:http";
10
+ import { randomBytes } from "node:crypto";
11
+ import { spawn } from "node:child_process";
12
+ import { platform } from "node:os";
13
+ import { saveCredentials } from "./credentials.js";
14
+ import { resolveRelayUrl, resolveWebAppUrl } from "./connection-targets.js";
15
+ const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
16
+ const HTML_CONTENT_TYPE = "text/html; charset=utf-8";
17
+ function openBrowser(url) {
18
+ const cmd = platform() === "darwin" ? "open" : platform() === "win32" ? "cmd" : "xdg-open";
19
+ const args = platform() === "win32" ? ["/c", "start", "", url] : [url];
20
+ try {
21
+ const child = spawn(cmd, args, { stdio: "ignore", detached: true });
22
+ child.on("error", () => { });
23
+ child.unref();
24
+ }
25
+ catch { }
26
+ }
27
+ export async function runLoginFlow(opts = {}) {
28
+ // Relay URL is read from env only (no CLI override): the daemon token is
29
+ // minted by whichever relay the web app uses, so it has to be the same
30
+ // one the daemon then connects to — pinning it to env keeps both ends in
31
+ // sync.
32
+ const webAppUrl = resolveWebAppUrl(opts.webAppUrl);
33
+ const relayUrl = resolveRelayUrl();
34
+ const state = randomBytes(16).toString("hex");
35
+ return new Promise((resolve, reject) => {
36
+ const server = createServer((req, res) => {
37
+ const url = new URL(req.url ?? "/", "http://127.0.0.1");
38
+ if (url.pathname !== "/callback") {
39
+ res.statusCode = 404;
40
+ res.end("Not found");
41
+ return;
42
+ }
43
+ if (url.searchParams.get("state") !== state) {
44
+ res.statusCode = 403;
45
+ res.setHeader("content-type", HTML_CONTENT_TYPE);
46
+ res.end('<html><body style="font-family:system-ui;text-align:center;padding-top:80px"><h2>Login failed</h2><p>State mismatch — this callback was not initiated by this login session.</p></body></html>');
47
+ return;
48
+ }
49
+ const token = url.searchParams.get("token");
50
+ const userId = url.searchParams.get("userId");
51
+ const error = url.searchParams.get("error");
52
+ clearTimeout(timer);
53
+ server.close();
54
+ if (error) {
55
+ res.statusCode = 400;
56
+ res.setHeader("content-type", HTML_CONTENT_TYPE);
57
+ res.end(`<html><body style="font-family:system-ui;text-align:center;padding-top:80px"><h2>Login failed</h2><p>${escapeHtml(error)}</p><p>You can close this tab and try again.</p></body></html>`);
58
+ reject(new Error(error));
59
+ return;
60
+ }
61
+ if (!token || !userId) {
62
+ const message = "Callback missing token or userId";
63
+ res.statusCode = 400;
64
+ res.setHeader("content-type", HTML_CONTENT_TYPE);
65
+ res.end(`<html><body style="font-family:system-ui;text-align:center;padding-top:80px"><h2>Login failed</h2><p>${escapeHtml(message)}</p><p>You can close this tab and try again.</p></body></html>`);
66
+ reject(new Error(message));
67
+ return;
68
+ }
69
+ try {
70
+ saveCredentials({
71
+ version: 1,
72
+ relayUrl,
73
+ token,
74
+ userId,
75
+ createdAt: new Date().toISOString(),
76
+ remoteEnabled: true,
77
+ });
78
+ }
79
+ catch (err) {
80
+ const message = err instanceof Error ? err.message : String(err);
81
+ res.statusCode = 500;
82
+ res.setHeader("content-type", HTML_CONTENT_TYPE);
83
+ res.end(`<html><body style="font-family:system-ui;text-align:center;padding-top:80px"><h2>Login failed</h2><p>Could not save credentials: ${escapeHtml(message)}</p><p>You can close this tab and try again.</p></body></html>`);
84
+ reject(new Error(`Could not save credentials: ${message}`));
85
+ return;
86
+ }
87
+ res.statusCode = 200;
88
+ res.setHeader("content-type", HTML_CONTENT_TYPE);
89
+ res.end(`<html><body style="font-family:system-ui;text-align:center;padding-top:80px"><h2>✓ Logged in to aimux</h2><p>You can close this tab and return to the terminal.</p></body></html>`);
90
+ resolve({ userId });
91
+ });
92
+ const timer = setTimeout(() => {
93
+ server.close();
94
+ reject(new Error("Login timed out after 5 minutes"));
95
+ }, LOGIN_TIMEOUT_MS);
96
+ server.on("error", (err) => {
97
+ clearTimeout(timer);
98
+ reject(err);
99
+ });
100
+ server.listen(0, "127.0.0.1", () => {
101
+ const address = server.address();
102
+ const port = typeof address === "object" && address ? address.port : 0;
103
+ const callback = `http://127.0.0.1:${port}/callback`;
104
+ const qs = new URLSearchParams({
105
+ callback,
106
+ state,
107
+ });
108
+ if (opts.action)
109
+ qs.set("action", opts.action);
110
+ const authUrl = `${webAppUrl}/cli-auth?${qs.toString()}`;
111
+ console.log("Opening your browser to sign in...");
112
+ console.log(`If it doesn't open, visit:\n ${authUrl}\n`);
113
+ openBrowser(authUrl);
114
+ });
115
+ });
116
+ }
117
+ function escapeHtml(s) {
118
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
119
+ }