@aria-cli/cli 1.0.54 → 1.0.56

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 (622) hide show
  1. package/bin/aria.mjs +671 -802
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/attached-local-control-client.js +826 -0
  4. package/dist/attached-local-control-client.js.map +1 -0
  5. package/dist/bootstrap-local-control-client.js +2 -0
  6. package/dist/bootstrap-local-control-client.js.map +1 -0
  7. package/dist/capability-aware-method-proxy.js +42 -0
  8. package/dist/capability-aware-method-proxy.js.map +1 -0
  9. package/dist/cli-context.js +160 -0
  10. package/dist/cli-context.js.map +1 -0
  11. package/dist/commands/arions.js +174 -0
  12. package/dist/commands/arions.js.map +1 -0
  13. package/dist/commands/auth.js +123 -0
  14. package/dist/commands/auth.js.map +1 -0
  15. package/dist/commands/daemon.js +367 -0
  16. package/dist/commands/daemon.js.map +1 -0
  17. package/dist/commands/definitions.js +176 -0
  18. package/dist/commands/definitions.js.map +1 -0
  19. package/dist/commands/index.js +80 -0
  20. package/dist/commands/index.js.map +1 -0
  21. package/dist/commands/login-handler.js +1108 -0
  22. package/dist/commands/login-handler.js.map +1 -0
  23. package/dist/commands/logout-handler.js +92 -0
  24. package/dist/commands/logout-handler.js.map +1 -0
  25. package/dist/commands/memory-handlers.js +89 -0
  26. package/dist/commands/memory-handlers.js.map +1 -0
  27. package/dist/commands/pairing.js +60 -0
  28. package/dist/commands/pairing.js.map +1 -0
  29. package/dist/commands/runtime-cutover-reset-command.js +12 -0
  30. package/dist/commands/runtime-cutover-reset-command.js.map +1 -0
  31. package/dist/commands/runtime-cutover-reset.js +265 -0
  32. package/dist/commands/runtime-cutover-reset.js.map +1 -0
  33. package/dist/commands/terminal-setup.js +84 -0
  34. package/dist/commands/terminal-setup.js.map +1 -0
  35. package/dist/config/aria-config.js +238 -0
  36. package/dist/config/aria-config.js.map +1 -0
  37. package/dist/config/index.js +3 -0
  38. package/dist/config/index.js.map +1 -0
  39. package/dist/config/loader.js +97 -0
  40. package/dist/config/loader.js.map +1 -0
  41. package/dist/config.js +142 -0
  42. package/dist/config.js.map +1 -0
  43. package/dist/daemon-info.js +10 -0
  44. package/dist/daemon-info.js.map +1 -0
  45. package/dist/ensure-daemon.js +128 -0
  46. package/dist/ensure-daemon.js.map +1 -0
  47. package/dist/entrypoints/command-mode.js +5 -0
  48. package/dist/entrypoints/command-mode.js.map +1 -0
  49. package/dist/entrypoints/daemon.js +50 -0
  50. package/dist/entrypoints/daemon.js.map +1 -0
  51. package/dist/entrypoints/headless-stdio.js +25 -0
  52. package/dist/entrypoints/headless-stdio.js.map +1 -0
  53. package/dist/entrypoints/interactive.d.ts.map +1 -0
  54. package/dist/entrypoints/interactive.js +80 -0
  55. package/dist/entrypoints/interactive.js.map +1 -0
  56. package/dist/event-loop-watchdog.js +73 -0
  57. package/dist/event-loop-watchdog.js.map +1 -0
  58. package/dist/headless/auth-orchestrator.js +508 -0
  59. package/dist/headless/auth-orchestrator.js.map +1 -0
  60. package/dist/headless/auth-service.js +43 -0
  61. package/dist/headless/auth-service.js.map +1 -0
  62. package/dist/headless/bootstrap-fast-path.js +112 -0
  63. package/dist/headless/bootstrap-fast-path.js.map +1 -0
  64. package/dist/headless/call-command.js +143 -0
  65. package/dist/headless/call-command.js.map +1 -0
  66. package/dist/headless/daemon-service.js +318 -0
  67. package/dist/headless/daemon-service.js.map +1 -0
  68. package/dist/headless/hook-actions.js +235 -0
  69. package/dist/headless/hook-actions.js.map +1 -0
  70. package/dist/headless/hook-service.js +42 -0
  71. package/dist/headless/hook-service.js.map +1 -0
  72. package/dist/headless/kernel-services.js +216 -0
  73. package/dist/headless/kernel-services.js.map +1 -0
  74. package/dist/headless/kernel.js +785 -0
  75. package/dist/headless/kernel.js.map +1 -0
  76. package/dist/headless/operations/arion.js +119 -0
  77. package/dist/headless/operations/arion.js.map +1 -0
  78. package/dist/headless/operations/auth.js +45 -0
  79. package/dist/headless/operations/auth.js.map +1 -0
  80. package/dist/headless/operations/client.js +31 -0
  81. package/dist/headless/operations/client.js.map +1 -0
  82. package/dist/headless/operations/config.js +69 -0
  83. package/dist/headless/operations/config.js.map +1 -0
  84. package/dist/headless/operations/daemon.js +47 -0
  85. package/dist/headless/operations/daemon.js.map +1 -0
  86. package/dist/headless/operations/hook.js +56 -0
  87. package/dist/headless/operations/hook.js.map +1 -0
  88. package/dist/headless/operations/index.js +11 -0
  89. package/dist/headless/operations/index.js.map +1 -0
  90. package/dist/headless/operations/memory.js +102 -0
  91. package/dist/headless/operations/memory.js.map +1 -0
  92. package/dist/headless/operations/message.js +279 -0
  93. package/dist/headless/operations/message.js.map +1 -0
  94. package/dist/headless/operations/model.js +100 -0
  95. package/dist/headless/operations/model.js.map +1 -0
  96. package/dist/headless/operations/peer.js +56 -0
  97. package/dist/headless/operations/peer.js.map +1 -0
  98. package/dist/headless/operations/run.js +24 -0
  99. package/dist/headless/operations/run.js.map +1 -0
  100. package/dist/headless/operations/session.js +90 -0
  101. package/dist/headless/operations/session.js.map +1 -0
  102. package/dist/headless/operations/system.js +19 -0
  103. package/dist/headless/operations/system.js.map +1 -0
  104. package/dist/headless/operations/utils.js +35 -0
  105. package/dist/headless/operations/utils.js.map +1 -0
  106. package/dist/headless/run-orchestrator.js +703 -0
  107. package/dist/headless/run-orchestrator.js.map +1 -0
  108. package/dist/headless/stdio-server.js +439 -0
  109. package/dist/headless/stdio-server.js.map +1 -0
  110. package/dist/history/SessionHistory.js +8 -0
  111. package/dist/history/SessionHistory.js.map +1 -0
  112. package/dist/history/SessionHistoryClient.js +186 -0
  113. package/dist/history/SessionHistoryClient.js.map +1 -0
  114. package/dist/history/conversation-message.js +112 -0
  115. package/dist/history/conversation-message.js.map +1 -0
  116. package/dist/history/index.js +8 -0
  117. package/dist/history/index.js.map +1 -0
  118. package/dist/history/jsonl-replay.js +154 -0
  119. package/dist/history/jsonl-replay.js.map +1 -0
  120. package/dist/history/repair-tool-pairing.js +84 -0
  121. package/dist/history/repair-tool-pairing.js.map +1 -0
  122. package/dist/history/stall-phase-bridge.js +11 -0
  123. package/dist/history/stall-phase-bridge.js.map +1 -0
  124. package/dist/history/turn-accumulator.js +427 -0
  125. package/dist/history/turn-accumulator.js.map +1 -0
  126. package/dist/index.d.ts.map +1 -0
  127. package/dist/index.js +7 -0
  128. package/dist/index.js.map +1 -0
  129. package/dist/ink-repl.d.ts.map +1 -0
  130. package/dist/ink-repl.js +4183 -0
  131. package/dist/ink-repl.js.map +1 -0
  132. package/dist/local-control-bootstrap.js +26 -0
  133. package/dist/local-control-bootstrap.js.map +1 -0
  134. package/dist/local-control-client.js +2 -0
  135. package/dist/local-control-client.js.map +1 -0
  136. package/dist/local-control-error-reporting.js +34 -0
  137. package/dist/local-control-error-reporting.js.map +1 -0
  138. package/dist/local-control-http-client.js +362 -0
  139. package/dist/local-control-http-client.js.map +1 -0
  140. package/dist/local-control-lazy-wrapper.js +363 -0
  141. package/dist/local-control-lazy-wrapper.js.map +1 -0
  142. package/dist/local-control-manager.js +146 -0
  143. package/dist/local-control-manager.js.map +1 -0
  144. package/dist/main.d.ts.map +1 -0
  145. package/dist/main.js +62 -0
  146. package/dist/main.js.map +1 -0
  147. package/dist/network-security.js +62 -0
  148. package/dist/network-security.js.map +1 -0
  149. package/dist/networking-server.js +38 -0
  150. package/dist/networking-server.js.map +1 -0
  151. package/dist/peer-identity.js +23 -0
  152. package/dist/peer-identity.js.map +1 -0
  153. package/dist/polling-subscription.js +34 -0
  154. package/dist/polling-subscription.js.map +1 -0
  155. package/dist/relaunch.d.ts +63 -0
  156. package/dist/relaunch.d.ts.map +1 -0
  157. package/dist/relaunch.js +617 -0
  158. package/dist/relaunch.js.map +1 -0
  159. package/dist/release-notes.js +35 -0
  160. package/dist/release-notes.js.map +1 -0
  161. package/dist/repl-cleanup.js +47 -0
  162. package/dist/repl-cleanup.js.map +1 -0
  163. package/dist/runtime/configure-bun-sqlite.js +3 -0
  164. package/dist/runtime/configure-bun-sqlite.js.map +1 -0
  165. package/dist/runtime/crash-handlers.js +111 -0
  166. package/dist/runtime/crash-handlers.js.map +1 -0
  167. package/dist/runtime/interactive-invocation.js +39 -0
  168. package/dist/runtime/interactive-invocation.js.map +1 -0
  169. package/dist/runtime/internal-mode.js +14 -0
  170. package/dist/runtime/internal-mode.js.map +1 -0
  171. package/dist/runtime/launch-spec.js +64 -0
  172. package/dist/runtime/launch-spec.js.map +1 -0
  173. package/dist/runtime/owner-lease.js +44 -0
  174. package/dist/runtime/owner-lease.js.map +1 -0
  175. package/dist/runtime/public-mode.js +20 -0
  176. package/dist/runtime/public-mode.js.map +1 -0
  177. package/dist/runtime/run-internal-mode.d.ts.map +1 -0
  178. package/dist/runtime/run-internal-mode.js +18 -0
  179. package/dist/runtime/run-internal-mode.js.map +1 -0
  180. package/dist/runtime/runtime-kind.js +32 -0
  181. package/dist/runtime/runtime-kind.js.map +1 -0
  182. package/dist/runtime/spawn-aria.js +38 -0
  183. package/dist/runtime/spawn-aria.js.map +1 -0
  184. package/dist/selectable-client.js +2 -0
  185. package/dist/selectable-client.js.map +1 -0
  186. package/dist/selectable-peer.js +2 -0
  187. package/dist/selectable-peer.js.map +1 -0
  188. package/dist/session.js +203 -0
  189. package/dist/session.js.map +1 -0
  190. package/dist/slash-commands.js +80 -0
  191. package/dist/slash-commands.js.map +1 -0
  192. package/dist/sounds.js +210 -0
  193. package/dist/sounds.js.map +1 -0
  194. package/dist/ui/App.js +526 -0
  195. package/dist/ui/App.js.map +1 -0
  196. package/dist/ui/components/AnthropicMethodPicker.js +6 -0
  197. package/dist/ui/components/AnthropicMethodPicker.js.map +1 -0
  198. package/dist/ui/components/ArionPrompt.js +15 -0
  199. package/dist/ui/components/ArionPrompt.js.map +1 -0
  200. package/dist/ui/components/AutocompleteDropdown.js +23 -0
  201. package/dist/ui/components/AutocompleteDropdown.js.map +1 -0
  202. package/dist/ui/components/AutonomySelector.js +55 -0
  203. package/dist/ui/components/AutonomySelector.js.map +1 -0
  204. package/dist/ui/components/Banner.js +98 -0
  205. package/dist/ui/components/Banner.js.map +1 -0
  206. package/dist/ui/components/ConversationHistory.js +175 -0
  207. package/dist/ui/components/ConversationHistory.js.map +1 -0
  208. package/dist/ui/components/CopilotDeviceLoginFlow.js +88 -0
  209. package/dist/ui/components/CopilotDeviceLoginFlow.js.map +1 -0
  210. package/dist/ui/components/CopilotSourcePicker.js +50 -0
  211. package/dist/ui/components/CopilotSourcePicker.js.map +1 -0
  212. package/dist/ui/components/Cost.js +10 -0
  213. package/dist/ui/components/Cost.js.map +1 -0
  214. package/dist/ui/components/CustomSelect/option-map.js +30 -0
  215. package/dist/ui/components/CustomSelect/option-map.js.map +1 -0
  216. package/dist/ui/components/CustomSelect/select-option.js +13 -0
  217. package/dist/ui/components/CustomSelect/select-option.js.map +1 -0
  218. package/dist/ui/components/CustomSelect/select.js +42 -0
  219. package/dist/ui/components/CustomSelect/select.js.map +1 -0
  220. package/dist/ui/components/CustomSelect/use-select-state.js +179 -0
  221. package/dist/ui/components/CustomSelect/use-select-state.js.map +1 -0
  222. package/dist/ui/components/CustomSelect/use-select.js +15 -0
  223. package/dist/ui/components/CustomSelect/use-select.js.map +1 -0
  224. package/dist/ui/components/ErrorDisplay.js +35 -0
  225. package/dist/ui/components/ErrorDisplay.js.map +1 -0
  226. package/dist/ui/components/FallbackToolUseRejectedMessage.js +7 -0
  227. package/dist/ui/components/FallbackToolUseRejectedMessage.js.map +1 -0
  228. package/dist/ui/components/FileEditToolUpdatedMessage.js +57 -0
  229. package/dist/ui/components/FileEditToolUpdatedMessage.js.map +1 -0
  230. package/dist/ui/components/HandoffMarker.js +18 -0
  231. package/dist/ui/components/HandoffMarker.js.map +1 -0
  232. package/dist/ui/components/HighlightedCode.js +21 -0
  233. package/dist/ui/components/HighlightedCode.js.map +1 -0
  234. package/dist/ui/components/InputArea.js +187 -0
  235. package/dist/ui/components/InputArea.js.map +1 -0
  236. package/dist/ui/components/Message.js +25 -0
  237. package/dist/ui/components/Message.js.map +1 -0
  238. package/dist/ui/components/OAuthLoginFlow.js +113 -0
  239. package/dist/ui/components/OAuthLoginFlow.js.map +1 -0
  240. package/dist/ui/components/OutputTruncation.js +35 -0
  241. package/dist/ui/components/OutputTruncation.js.map +1 -0
  242. package/dist/ui/components/PermissionPrompt.js +79 -0
  243. package/dist/ui/components/PermissionPrompt.js.map +1 -0
  244. package/dist/ui/components/PipelineTimingPanel.js +15 -0
  245. package/dist/ui/components/PipelineTimingPanel.js.map +1 -0
  246. package/dist/ui/components/ProviderMethodPicker.js +61 -0
  247. package/dist/ui/components/ProviderMethodPicker.js.map +1 -0
  248. package/dist/ui/components/ProviderPicker.js +63 -0
  249. package/dist/ui/components/ProviderPicker.js.map +1 -0
  250. package/dist/ui/components/RenderItemView.js +71 -0
  251. package/dist/ui/components/RenderItemView.js.map +1 -0
  252. package/dist/ui/components/Spinner.js +46 -0
  253. package/dist/ui/components/Spinner.js.map +1 -0
  254. package/dist/ui/components/StatusBar.js +95 -0
  255. package/dist/ui/components/StatusBar.js.map +1 -0
  256. package/dist/ui/components/StreamingIndicator.js +55 -0
  257. package/dist/ui/components/StreamingIndicator.js.map +1 -0
  258. package/dist/ui/components/StructuredDiff.js +168 -0
  259. package/dist/ui/components/StructuredDiff.js.map +1 -0
  260. package/dist/ui/components/TextInputOverlay.js +43 -0
  261. package/dist/ui/components/TextInputOverlay.js.map +1 -0
  262. package/dist/ui/components/ThinkingBlock.js +82 -0
  263. package/dist/ui/components/ThinkingBlock.js.map +1 -0
  264. package/dist/ui/components/ToolCost.js +17 -0
  265. package/dist/ui/components/ToolCost.js.map +1 -0
  266. package/dist/ui/components/ToolExecution.js +61 -0
  267. package/dist/ui/components/ToolExecution.js.map +1 -0
  268. package/dist/ui/components/ToolHeader.js +51 -0
  269. package/dist/ui/components/ToolHeader.js.map +1 -0
  270. package/dist/ui/components/ToolRenderLayoutContext.js +14 -0
  271. package/dist/ui/components/ToolRenderLayoutContext.js.map +1 -0
  272. package/dist/ui/components/ToolResultWrapper.js +6 -0
  273. package/dist/ui/components/ToolResultWrapper.js.map +1 -0
  274. package/dist/ui/components/ToolUseLoader.js +35 -0
  275. package/dist/ui/components/ToolUseLoader.js.map +1 -0
  276. package/dist/ui/components/TraceWaterfall.js +91 -0
  277. package/dist/ui/components/TraceWaterfall.js.map +1 -0
  278. package/dist/ui/components/index.js +33 -0
  279. package/dist/ui/components/index.js.map +1 -0
  280. package/dist/ui/components/messages/AssistantTextMessage.js +25 -0
  281. package/dist/ui/components/messages/AssistantTextMessage.js.map +1 -0
  282. package/dist/ui/components/messages/UserImageMessage.js +12 -0
  283. package/dist/ui/components/messages/UserImageMessage.js.map +1 -0
  284. package/dist/ui/components/messages/UserTextMessage.js +12 -0
  285. package/dist/ui/components/messages/UserTextMessage.js.map +1 -0
  286. package/dist/ui/components/overlays/ArionSelector.js +68 -0
  287. package/dist/ui/components/overlays/ArionSelector.js.map +1 -0
  288. package/dist/ui/components/overlays/ClientSelector.js +62 -0
  289. package/dist/ui/components/overlays/ClientSelector.js.map +1 -0
  290. package/dist/ui/components/overlays/CommandPalette.js +67 -0
  291. package/dist/ui/components/overlays/CommandPalette.js.map +1 -0
  292. package/dist/ui/components/overlays/DaemonControl.js +87 -0
  293. package/dist/ui/components/overlays/DaemonControl.js.map +1 -0
  294. package/dist/ui/components/overlays/InviteShareOverlay.js +15 -0
  295. package/dist/ui/components/overlays/InviteShareOverlay.js.map +1 -0
  296. package/dist/ui/components/overlays/JoinInviteOverlay.js +32 -0
  297. package/dist/ui/components/overlays/JoinInviteOverlay.js.map +1 -0
  298. package/dist/ui/components/overlays/MemoryBrowser.js +100 -0
  299. package/dist/ui/components/overlays/MemoryBrowser.js.map +1 -0
  300. package/dist/ui/components/overlays/MessageSelector.js +123 -0
  301. package/dist/ui/components/overlays/MessageSelector.js.map +1 -0
  302. package/dist/ui/components/overlays/ModelSelector.js +211 -0
  303. package/dist/ui/components/overlays/ModelSelector.js.map +1 -0
  304. package/dist/ui/components/overlays/PairRequestOverlay.js +42 -0
  305. package/dist/ui/components/overlays/PairRequestOverlay.js.map +1 -0
  306. package/dist/ui/components/overlays/PeerSelector.js +84 -0
  307. package/dist/ui/components/overlays/PeerSelector.js.map +1 -0
  308. package/dist/ui/components/overlays/SessionSelector.js +102 -0
  309. package/dist/ui/components/overlays/SessionSelector.js.map +1 -0
  310. package/dist/ui/components/overlays/SoundSelector.js +86 -0
  311. package/dist/ui/components/overlays/SoundSelector.js.map +1 -0
  312. package/dist/ui/components/overlays/ThemeSelector.js +139 -0
  313. package/dist/ui/components/overlays/ThemeSelector.js.map +1 -0
  314. package/dist/ui/components/overlays/index.js +15 -0
  315. package/dist/ui/components/overlays/index.js.map +1 -0
  316. package/dist/ui/components/permissions/BashPermissionRequest/BashPermissionRequest.js +53 -0
  317. package/dist/ui/components/permissions/BashPermissionRequest/BashPermissionRequest.js.map +1 -0
  318. package/dist/ui/components/permissions/FallbackPermissionRequest.js +56 -0
  319. package/dist/ui/components/permissions/FallbackPermissionRequest.js.map +1 -0
  320. package/dist/ui/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.js +76 -0
  321. package/dist/ui/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.js.map +1 -0
  322. package/dist/ui/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js +18 -0
  323. package/dist/ui/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js.map +1 -0
  324. package/dist/ui/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.js +64 -0
  325. package/dist/ui/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.js.map +1 -0
  326. package/dist/ui/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js +26 -0
  327. package/dist/ui/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js.map +1 -0
  328. package/dist/ui/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +141 -0
  329. package/dist/ui/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +1 -0
  330. package/dist/ui/components/permissions/PermissionRequest.js +70 -0
  331. package/dist/ui/components/permissions/PermissionRequest.js.map +1 -0
  332. package/dist/ui/components/permissions/PermissionRequestTitle.js +41 -0
  333. package/dist/ui/components/permissions/PermissionRequestTitle.js.map +1 -0
  334. package/dist/ui/components/permissions/hooks.js +10 -0
  335. package/dist/ui/components/permissions/hooks.js.map +1 -0
  336. package/dist/ui/components/permissions/toolUseOptions.js +68 -0
  337. package/dist/ui/components/permissions/toolUseOptions.js.map +1 -0
  338. package/dist/ui/components/permissions/utils.js +10 -0
  339. package/dist/ui/components/permissions/utils.js.map +1 -0
  340. package/dist/ui/components/text-input/Cursor.js +326 -0
  341. package/dist/ui/components/text-input/Cursor.js.map +1 -0
  342. package/dist/ui/components/text-input/TextInput.js +231 -0
  343. package/dist/ui/components/text-input/TextInput.js.map +1 -0
  344. package/dist/ui/components/text-input/imagePaste.js +28 -0
  345. package/dist/ui/components/text-input/imagePaste.js.map +1 -0
  346. package/dist/ui/components/text-input/index.js +6 -0
  347. package/dist/ui/components/text-input/index.js.map +1 -0
  348. package/dist/ui/components/text-input/useDoublePress.js +30 -0
  349. package/dist/ui/components/text-input/useDoublePress.js.map +1 -0
  350. package/dist/ui/components/text-input/useTextInput.js +245 -0
  351. package/dist/ui/components/text-input/useTextInput.js.map +1 -0
  352. package/dist/ui/components/tool-types.js +9 -0
  353. package/dist/ui/components/tool-types.js.map +1 -0
  354. package/dist/ui/constants/figures.js +4 -0
  355. package/dist/ui/constants/figures.js.map +1 -0
  356. package/dist/ui/constants/index.js +3 -0
  357. package/dist/ui/constants/index.js.map +1 -0
  358. package/dist/ui/display-mode.js +93 -0
  359. package/dist/ui/display-mode.js.map +1 -0
  360. package/dist/ui/display-policy.js +19 -0
  361. package/dist/ui/display-policy.js.map +1 -0
  362. package/dist/ui/hooks/index.js +6 -0
  363. package/dist/ui/hooks/index.js.map +1 -0
  364. package/dist/ui/hooks/useCommandAutocomplete.js +93 -0
  365. package/dist/ui/hooks/useCommandAutocomplete.js.map +1 -0
  366. package/dist/ui/hooks/useDoublePress.js +37 -0
  367. package/dist/ui/hooks/useDoublePress.js.map +1 -0
  368. package/dist/ui/hooks/useIndicatorState.js +55 -0
  369. package/dist/ui/hooks/useIndicatorState.js.map +1 -0
  370. package/dist/ui/hooks/useInterval.js +23 -0
  371. package/dist/ui/hooks/useInterval.js.map +1 -0
  372. package/dist/ui/hooks/useKeyboardShortcuts.js +127 -0
  373. package/dist/ui/hooks/useKeyboardShortcuts.js.map +1 -0
  374. package/dist/ui/hooks/useTerminalSize.js +55 -0
  375. package/dist/ui/hooks/useTerminalSize.js.map +1 -0
  376. package/dist/ui/hooks/useUnifiedMessages.js +117 -0
  377. package/dist/ui/hooks/useUnifiedMessages.js.map +1 -0
  378. package/dist/ui/indicator-state.js +44 -0
  379. package/dist/ui/indicator-state.js.map +1 -0
  380. package/dist/ui/markdown/highlight.js +44 -0
  381. package/dist/ui/markdown/highlight.js.map +1 -0
  382. package/dist/ui/markdown/index.js +1460 -0
  383. package/dist/ui/markdown/index.js.map +1 -0
  384. package/dist/ui/markdown/tokenizer.js +24 -0
  385. package/dist/ui/markdown/tokenizer.js.map +1 -0
  386. package/dist/ui/render-item.js +5 -0
  387. package/dist/ui/render-item.js.map +1 -0
  388. package/dist/ui/screens/REPL.js +119 -0
  389. package/dist/ui/screens/REPL.js.map +1 -0
  390. package/dist/ui/screens/approval-lifecycle.js +38 -0
  391. package/dist/ui/screens/approval-lifecycle.js.map +1 -0
  392. package/dist/ui/status-line.js +72 -0
  393. package/dist/ui/status-line.js.map +1 -0
  394. package/dist/ui/theme/index.js +51 -0
  395. package/dist/ui/theme/index.js.map +1 -0
  396. package/dist/ui/theme/themes/claude-dark-daltonized.js +51 -0
  397. package/dist/ui/theme/themes/claude-dark-daltonized.js.map +1 -0
  398. package/dist/ui/theme/themes/claude-dark.js +50 -0
  399. package/dist/ui/theme/themes/claude-dark.js.map +1 -0
  400. package/dist/ui/theme/themes/claude-light-daltonized.js +51 -0
  401. package/dist/ui/theme/themes/claude-light-daltonized.js.map +1 -0
  402. package/dist/ui/theme/themes/claude-light.js +50 -0
  403. package/dist/ui/theme/themes/claude-light.js.map +1 -0
  404. package/dist/ui/theme/themes/dark-accessible.js +18 -0
  405. package/dist/ui/theme/themes/dark-accessible.js.map +1 -0
  406. package/dist/ui/theme/themes/dark.js +49 -0
  407. package/dist/ui/theme/themes/dark.js.map +1 -0
  408. package/dist/ui/theme/themes/light-accessible.js +18 -0
  409. package/dist/ui/theme/themes/light-accessible.js.map +1 -0
  410. package/dist/ui/theme/themes/light.js +49 -0
  411. package/dist/ui/theme/themes/light.js.map +1 -0
  412. package/dist/ui/theme/types.js +3 -0
  413. package/dist/ui/theme/types.js.map +1 -0
  414. package/dist/ui/theme.js +142 -0
  415. package/dist/ui/theme.js.map +1 -0
  416. package/dist/ui/to-render-items.js +145 -0
  417. package/dist/ui/to-render-items.js.map +1 -0
  418. package/dist/ui/tools/AgentTool/index.js +30 -0
  419. package/dist/ui/tools/AgentTool/index.js.map +1 -0
  420. package/dist/ui/tools/ArchitectTool/index.js +31 -0
  421. package/dist/ui/tools/ArchitectTool/index.js.map +1 -0
  422. package/dist/ui/tools/AskUserTool/index.js +46 -0
  423. package/dist/ui/tools/AskUserTool/index.js.map +1 -0
  424. package/dist/ui/tools/BashTool/BashToolResultMessage.js +11 -0
  425. package/dist/ui/tools/BashTool/BashToolResultMessage.js.map +1 -0
  426. package/dist/ui/tools/BashTool/OutputLine.js +21 -0
  427. package/dist/ui/tools/BashTool/OutputLine.js.map +1 -0
  428. package/dist/ui/tools/BashTool/index.js +91 -0
  429. package/dist/ui/tools/BashTool/index.js.map +1 -0
  430. package/dist/ui/tools/BrowseTool/index.js +43 -0
  431. package/dist/ui/tools/BrowseTool/index.js.map +1 -0
  432. package/dist/ui/tools/BrowserTool/index.js +47 -0
  433. package/dist/ui/tools/BrowserTool/index.js.map +1 -0
  434. package/dist/ui/tools/CbmTool/index.js +188 -0
  435. package/dist/ui/tools/CbmTool/index.js.map +1 -0
  436. package/dist/ui/tools/CheckDelegationTool/index.js +46 -0
  437. package/dist/ui/tools/CheckDelegationTool/index.js.map +1 -0
  438. package/dist/ui/tools/CheckMessagesTool/index.js +85 -0
  439. package/dist/ui/tools/CheckMessagesTool/index.js.map +1 -0
  440. package/dist/ui/tools/CreateQuipTool/index.js +30 -0
  441. package/dist/ui/tools/CreateQuipTool/index.js.map +1 -0
  442. package/dist/ui/tools/CreateSkillTool/index.js +22 -0
  443. package/dist/ui/tools/CreateSkillTool/index.js.map +1 -0
  444. package/dist/ui/tools/CreateToolTool/index.js +31 -0
  445. package/dist/ui/tools/CreateToolTool/index.js.map +1 -0
  446. package/dist/ui/tools/DelegateRemoteTool/index.js +42 -0
  447. package/dist/ui/tools/DelegateRemoteTool/index.js.map +1 -0
  448. package/dist/ui/tools/DeployTool/index.js +47 -0
  449. package/dist/ui/tools/DeployTool/index.js.map +1 -0
  450. package/dist/ui/tools/FffTool/index.js +103 -0
  451. package/dist/ui/tools/FffTool/index.js.map +1 -0
  452. package/dist/ui/tools/FileEditTool/index.js +67 -0
  453. package/dist/ui/tools/FileEditTool/index.js.map +1 -0
  454. package/dist/ui/tools/FileReadTool/index.js +68 -0
  455. package/dist/ui/tools/FileReadTool/index.js.map +1 -0
  456. package/dist/ui/tools/FileWriteTool/index.js +61 -0
  457. package/dist/ui/tools/FileWriteTool/index.js.map +1 -0
  458. package/dist/ui/tools/ForkTool/index.js +47 -0
  459. package/dist/ui/tools/ForkTool/index.js.map +1 -0
  460. package/dist/ui/tools/FrgTool/index.js +96 -0
  461. package/dist/ui/tools/FrgTool/index.js.map +1 -0
  462. package/dist/ui/tools/GetThreadTool/index.js +39 -0
  463. package/dist/ui/tools/GetThreadTool/index.js.map +1 -0
  464. package/dist/ui/tools/GlobTool/index.js +50 -0
  465. package/dist/ui/tools/GlobTool/index.js.map +1 -0
  466. package/dist/ui/tools/GrepTool/index.js +84 -0
  467. package/dist/ui/tools/GrepTool/index.js.map +1 -0
  468. package/dist/ui/tools/HatchArionTool/index.js +36 -0
  469. package/dist/ui/tools/HatchArionTool/index.js.map +1 -0
  470. package/dist/ui/tools/LearnSkillTool/index.js +22 -0
  471. package/dist/ui/tools/LearnSkillTool/index.js.map +1 -0
  472. package/dist/ui/tools/LearnTool/index.js +43 -0
  473. package/dist/ui/tools/LearnTool/index.js.map +1 -0
  474. package/dist/ui/tools/LearnToolTool/index.js +22 -0
  475. package/dist/ui/tools/LearnToolTool/index.js.map +1 -0
  476. package/dist/ui/tools/ListClientsTool/index.js +39 -0
  477. package/dist/ui/tools/ListClientsTool/index.js.map +1 -0
  478. package/dist/ui/tools/LspTool/index.js +261 -0
  479. package/dist/ui/tools/LspTool/index.js.map +1 -0
  480. package/dist/ui/tools/MCPTool/index.js +33 -0
  481. package/dist/ui/tools/MCPTool/index.js.map +1 -0
  482. package/dist/ui/tools/ManageNetworkTool/index.js +53 -0
  483. package/dist/ui/tools/ManageNetworkTool/index.js.map +1 -0
  484. package/dist/ui/tools/MemoryReadTool/index.js +64 -0
  485. package/dist/ui/tools/MemoryReadTool/index.js.map +1 -0
  486. package/dist/ui/tools/MemoryWriteTool/index.js +20 -0
  487. package/dist/ui/tools/MemoryWriteTool/index.js.map +1 -0
  488. package/dist/ui/tools/NotebookEditTool/index.js +33 -0
  489. package/dist/ui/tools/NotebookEditTool/index.js.map +1 -0
  490. package/dist/ui/tools/NotebookReadTool/index.js +25 -0
  491. package/dist/ui/tools/NotebookReadTool/index.js.map +1 -0
  492. package/dist/ui/tools/OutlookReadTool/index.js +66 -0
  493. package/dist/ui/tools/OutlookReadTool/index.js.map +1 -0
  494. package/dist/ui/tools/OutlookReplyTool/index.js +49 -0
  495. package/dist/ui/tools/OutlookReplyTool/index.js.map +1 -0
  496. package/dist/ui/tools/OutlookSendTool/index.js +49 -0
  497. package/dist/ui/tools/OutlookSendTool/index.js.map +1 -0
  498. package/dist/ui/tools/PauseDelegationTool/index.js +35 -0
  499. package/dist/ui/tools/PauseDelegationTool/index.js.map +1 -0
  500. package/dist/ui/tools/ProbeTool/index.js +121 -0
  501. package/dist/ui/tools/ProbeTool/index.js.map +1 -0
  502. package/dist/ui/tools/ProcessTool/index.js +66 -0
  503. package/dist/ui/tools/ProcessTool/index.js.map +1 -0
  504. package/dist/ui/tools/QuestListTool/index.js +46 -0
  505. package/dist/ui/tools/QuestListTool/index.js.map +1 -0
  506. package/dist/ui/tools/QuestReportTool/index.js +49 -0
  507. package/dist/ui/tools/QuestReportTool/index.js.map +1 -0
  508. package/dist/ui/tools/QuestUpdateTool/index.js +87 -0
  509. package/dist/ui/tools/QuestUpdateTool/index.js.map +1 -0
  510. package/dist/ui/tools/QuipCommentTool/index.js +69 -0
  511. package/dist/ui/tools/QuipCommentTool/index.js.map +1 -0
  512. package/dist/ui/tools/QuipReadTool/index.js +71 -0
  513. package/dist/ui/tools/QuipReadTool/index.js.map +1 -0
  514. package/dist/ui/tools/RestArionTool/index.js +32 -0
  515. package/dist/ui/tools/RestArionTool/index.js.map +1 -0
  516. package/dist/ui/tools/RestartTool/index.js +35 -0
  517. package/dist/ui/tools/RestartTool/index.js.map +1 -0
  518. package/dist/ui/tools/ResumeDelegationTool/index.js +35 -0
  519. package/dist/ui/tools/ResumeDelegationTool/index.js.map +1 -0
  520. package/dist/ui/tools/RetireArionTool/index.js +32 -0
  521. package/dist/ui/tools/RetireArionTool/index.js.map +1 -0
  522. package/dist/ui/tools/RgTool/index.js +73 -0
  523. package/dist/ui/tools/RgTool/index.js.map +1 -0
  524. package/dist/ui/tools/SearchKnowledgeTool/index.js +43 -0
  525. package/dist/ui/tools/SearchKnowledgeTool/index.js.map +1 -0
  526. package/dist/ui/tools/SearchMessagesTool/index.js +43 -0
  527. package/dist/ui/tools/SearchMessagesTool/index.js.map +1 -0
  528. package/dist/ui/tools/SelfDiagnoseTool/index.js +61 -0
  529. package/dist/ui/tools/SelfDiagnoseTool/index.js.map +1 -0
  530. package/dist/ui/tools/SendMessageTool/index.js +45 -0
  531. package/dist/ui/tools/SendMessageTool/index.js.map +1 -0
  532. package/dist/ui/tools/SerenaTool/index.js +124 -0
  533. package/dist/ui/tools/SerenaTool/index.js.map +1 -0
  534. package/dist/ui/tools/SessionHistoryTool/index.js +52 -0
  535. package/dist/ui/tools/SessionHistoryTool/index.js.map +1 -0
  536. package/dist/ui/tools/SgTool/index.js +80 -0
  537. package/dist/ui/tools/SgTool/index.js.map +1 -0
  538. package/dist/ui/tools/SlackReactTool/index.js +41 -0
  539. package/dist/ui/tools/SlackReactTool/index.js.map +1 -0
  540. package/dist/ui/tools/SlackReadTool/index.js +48 -0
  541. package/dist/ui/tools/SlackReadTool/index.js.map +1 -0
  542. package/dist/ui/tools/SlackSendTool/index.js +45 -0
  543. package/dist/ui/tools/SlackSendTool/index.js.map +1 -0
  544. package/dist/ui/tools/SpawnWorkerTool/index.js +33 -0
  545. package/dist/ui/tools/SpawnWorkerTool/index.js.map +1 -0
  546. package/dist/ui/tools/StickerRequestTool/index.js +19 -0
  547. package/dist/ui/tools/StickerRequestTool/index.js.map +1 -0
  548. package/dist/ui/tools/ThinkTool/index.js +17 -0
  549. package/dist/ui/tools/ThinkTool/index.js.map +1 -0
  550. package/dist/ui/tools/UgTool/index.js +108 -0
  551. package/dist/ui/tools/UgTool/index.js.map +1 -0
  552. package/dist/ui/tools/UseSkillTool/index.js +22 -0
  553. package/dist/ui/tools/UseSkillTool/index.js.map +1 -0
  554. package/dist/ui/tools/WakeArionTool/index.js +32 -0
  555. package/dist/ui/tools/WakeArionTool/index.js.map +1 -0
  556. package/dist/ui/tools/WebFetchTool/index.js +56 -0
  557. package/dist/ui/tools/WebFetchTool/index.js.map +1 -0
  558. package/dist/ui/tools/WebSearchTool/index.js +44 -0
  559. package/dist/ui/tools/WebSearchTool/index.js.map +1 -0
  560. package/dist/ui/tools/lsTool/index.js +58 -0
  561. package/dist/ui/tools/lsTool/index.js.map +1 -0
  562. package/dist/ui/tools/registry.js +197 -0
  563. package/dist/ui/tools/registry.js.map +1 -0
  564. package/dist/ui/tools/tool-renderer.js +11 -0
  565. package/dist/ui/tools/tool-renderer.js.map +1 -0
  566. package/dist/ui/tools/truncation.js +35 -0
  567. package/dist/ui/tools/truncation.js.map +1 -0
  568. package/dist/ui/types/anthropic.js +4 -0
  569. package/dist/ui/types/anthropic.js.map +1 -0
  570. package/dist/ui/types/index.js +2 -0
  571. package/dist/ui/types/index.js.map +1 -0
  572. package/dist/ui/types/message.js +3 -0
  573. package/dist/ui/types/message.js.map +1 -0
  574. package/dist/ui/types/tool.js +4 -0
  575. package/dist/ui/types/tool.js.map +1 -0
  576. package/dist/ui/utils/array.js +4 -0
  577. package/dist/ui/utils/array.js.map +1 -0
  578. package/dist/ui/utils/cursor.js +131 -0
  579. package/dist/ui/utils/cursor.js.map +1 -0
  580. package/dist/ui/utils/diff.js +120 -0
  581. package/dist/ui/utils/diff.js.map +1 -0
  582. package/dist/ui/utils/format.js +42 -0
  583. package/dist/ui/utils/format.js.map +1 -0
  584. package/dist/ui/utils/fuzzy.js +59 -0
  585. package/dist/ui/utils/fuzzy.js.map +1 -0
  586. package/dist/ui/utils/index.js +11 -0
  587. package/dist/ui/utils/index.js.map +1 -0
  588. package/dist/ui/utils/keys.js +8 -0
  589. package/dist/ui/utils/keys.js.map +1 -0
  590. package/dist/ui/utils/patch.js +17 -0
  591. package/dist/ui/utils/patch.js.map +1 -0
  592. package/dist/ui/utils/risk.js +114 -0
  593. package/dist/ui/utils/risk.js.map +1 -0
  594. package/dist/ui/utils/terminal-image.js +70 -0
  595. package/dist/ui/utils/terminal-image.js.map +1 -0
  596. package/dist/ui/utils/validation.js +48 -0
  597. package/dist/ui/utils/validation.js.map +1 -0
  598. package/dist/ui/verb-pairs.js +248 -0
  599. package/dist/ui/verb-pairs.js.map +1 -0
  600. package/dist/ui.js +131 -0
  601. package/dist/ui.js.map +1 -0
  602. package/package.json +77 -15
  603. package/src/entrypoints/command-mode.ts +5 -0
  604. package/src/entrypoints/daemon.ts +54 -0
  605. package/src/entrypoints/headless-stdio.ts +27 -0
  606. package/src/entrypoints/interactive.ts +112 -0
  607. package/src/main.ts +72 -0
  608. package/src/runtime/configure-bun-sqlite.ts +3 -0
  609. package/src/runtime/crash-handlers.ts +128 -0
  610. package/src/runtime/interactive-invocation.test.ts +42 -0
  611. package/src/runtime/interactive-invocation.ts +51 -0
  612. package/src/runtime/internal-mode.test.ts +19 -0
  613. package/src/runtime/internal-mode.ts +24 -0
  614. package/src/runtime/launch-spec.test.ts +26 -0
  615. package/src/runtime/launch-spec.ts +84 -0
  616. package/src/runtime/owner-lease.ts +52 -0
  617. package/src/runtime/public-mode.test.ts +18 -0
  618. package/src/runtime/public-mode.ts +19 -0
  619. package/src/runtime/run-internal-mode.ts +19 -0
  620. package/src/runtime/runtime-kind.test.ts +23 -0
  621. package/src/runtime/runtime-kind.ts +41 -0
  622. package/src/runtime/spawn-aria.ts +62 -0
@@ -0,0 +1,1108 @@
1
+ /**
2
+ * Slash command handler for /login — authenticate with providers.
3
+ *
4
+ * Supports three result modes:
5
+ * - PickerResult: `/login` with no args → return provider list for interactive picker
6
+ * - DirectResult: `/login bedrock`, `/login anthropic <key>` → immediate result
7
+ * - OAuthFlowResult: `/login anthropic` (no key) → trigger OAuth flow component
8
+ */
9
+ import { ensureAuthProfileStore, syncExternalCliCredentials, isProfileInCooldown, upsertAuthProfile, updateAuthProfileStoreWithLockSync, refreshBedrockSsoToken, loginBedrockSso, listProfilesForProvider, loginWithGitHubCopilotToken, readClaudeCodeCredentialsCached, readCodexCredentialsCached, readGeminiCredentialsCached, normalizeProviderId, OPENAI_CODEX_OAUTH_PROFILE_ID, } from "@aria-cli/auth";
10
+ import { spawnSync } from "node:child_process";
11
+ import { loadConfig, saveConfig, persistAwsSelectorHintsFromEnv } from "../config.js";
12
+ function readGhAuthToken() {
13
+ try {
14
+ const result = spawnSync("gh", ["auth", "token", "-h", "github.com"], {
15
+ encoding: "utf8",
16
+ timeout: 5000,
17
+ });
18
+ if (result.error) {
19
+ return { error: result.error.message };
20
+ }
21
+ if (result.status !== 0) {
22
+ const stderr = (result.stderr || "").trim();
23
+ const stdout = (result.stdout || "").trim();
24
+ return { error: stderr || stdout || `gh auth token exited with status ${result.status}` };
25
+ }
26
+ const token = (result.stdout || "").trim();
27
+ if (token.length < 8) {
28
+ return { error: "gh auth token returned an empty/short token" };
29
+ }
30
+ return { token };
31
+ }
32
+ catch (error) {
33
+ return { error: error instanceof Error ? error.message : String(error) };
34
+ }
35
+ }
36
+ function readGhUsernames(host = "github.com") {
37
+ try {
38
+ const result = spawnSync("gh", ["auth", "status", "-h", host], {
39
+ encoding: "utf8",
40
+ timeout: 5000,
41
+ });
42
+ const text = `${result.stdout || ""}\n${result.stderr || ""}`;
43
+ const names = new Set();
44
+ for (const line of text.split(/\r?\n/)) {
45
+ const m = line.match(/Logged in to .* account\s+([^\s]+)/i);
46
+ if (m?.[1]) {
47
+ names.add(m[1]);
48
+ }
49
+ }
50
+ return [...names];
51
+ }
52
+ catch {
53
+ return [];
54
+ }
55
+ }
56
+ function readGhTokenForUser(user, host = "github.com") {
57
+ try {
58
+ const result = spawnSync("gh", ["auth", "token", "-h", host, "-u", user], {
59
+ encoding: "utf8",
60
+ timeout: 5000,
61
+ });
62
+ if (result.error) {
63
+ return { error: result.error.message };
64
+ }
65
+ if (result.status !== 0) {
66
+ return { error: (result.stderr || result.stdout || "").trim() || "gh token failed" };
67
+ }
68
+ const token = (result.stdout || "").trim();
69
+ if (token.length < 8) {
70
+ return { error: "empty/short token" };
71
+ }
72
+ return { token };
73
+ }
74
+ catch (error) {
75
+ return { error: error instanceof Error ? error.message : String(error) };
76
+ }
77
+ }
78
+ function readCopilotLastLoggedInUser() {
79
+ try {
80
+ const configPath = `${process.env.HOME || ""}/.copilot/config.json`;
81
+ const result = spawnSync("node", [
82
+ "-e",
83
+ `const fs=require('fs');const p=${JSON.stringify(configPath)};if(!fs.existsSync(p)){process.exit(0);}const j=JSON.parse(fs.readFileSync(p,'utf8'));const login=j?.last_logged_in_user?.login||j?.logged_in_users?.[0]?.login||'';if(login)process.stdout.write(login);`,
84
+ ], {
85
+ encoding: "utf8",
86
+ timeout: 5000,
87
+ });
88
+ const login = (result.stdout || "").trim();
89
+ return login ? { login } : {};
90
+ }
91
+ catch (error) {
92
+ return { error: error instanceof Error ? error.message : String(error) };
93
+ }
94
+ }
95
+ function parseCopilotLoginArgs(raw) {
96
+ const text = raw?.trim() ?? "";
97
+ if (!text) {
98
+ return { useGhToken: true, autoSelectSource: true };
99
+ }
100
+ const parts = text.split(/\s+/).filter(Boolean);
101
+ let token;
102
+ let profileLabel;
103
+ let useGhToken = true;
104
+ let autoSelectSource = false;
105
+ const takeValue = (index) => {
106
+ const value = parts[index + 1];
107
+ return value && !value.startsWith("--") ? value : undefined;
108
+ };
109
+ for (let i = 0; i < parts.length; i += 1) {
110
+ const part = parts[i];
111
+ if (part === "--profile" || part === "--label") {
112
+ const value = takeValue(i);
113
+ if (value) {
114
+ profileLabel = value;
115
+ i += 1;
116
+ }
117
+ continue;
118
+ }
119
+ if (part.startsWith("--profile=") || part.startsWith("--label=")) {
120
+ profileLabel = part.split("=", 2)[1]?.trim() || profileLabel;
121
+ continue;
122
+ }
123
+ if (part === "--source") {
124
+ const value = takeValue(i)?.toLowerCase();
125
+ if (value === "device") {
126
+ useGhToken = false;
127
+ }
128
+ else if (value === "auto") {
129
+ autoSelectSource = true;
130
+ }
131
+ i += value ? 1 : 0;
132
+ continue;
133
+ }
134
+ if (part.startsWith("--source=")) {
135
+ const value = part.split("=", 2)[1]?.toLowerCase();
136
+ if (value === "device") {
137
+ useGhToken = false;
138
+ }
139
+ else if (value === "auto") {
140
+ autoSelectSource = true;
141
+ }
142
+ continue;
143
+ }
144
+ if (!part.startsWith("--") && !token) {
145
+ token = part;
146
+ useGhToken = false;
147
+ }
148
+ }
149
+ if (token && token.length > 0) {
150
+ useGhToken = false;
151
+ }
152
+ return { token, profileLabel, useGhToken, autoSelectSource };
153
+ }
154
+ function sanitizeProfileLabel(input) {
155
+ const raw = (input || "").trim();
156
+ if (!raw)
157
+ return undefined;
158
+ return (raw
159
+ .toLowerCase()
160
+ .replace(/[^a-z0-9._-]+/g, "-")
161
+ .replace(/^-+|-+$/g, "") || undefined);
162
+ }
163
+ function buildCopilotSourceOptions() {
164
+ const options = [];
165
+ const seen = new Set();
166
+ // Check GitHub token env vars (GH_TOKEN, GITHUB_TOKEN, COPILOT_GITHUB_TOKEN)
167
+ const envTokenVars = ["GH_TOKEN", "GITHUB_TOKEN", "COPILOT_GITHUB_TOKEN"];
168
+ for (const varName of envTokenVars) {
169
+ const token = process.env[varName]?.trim();
170
+ if (token && token.length >= 8) {
171
+ const key = `env:${varName}`;
172
+ if (!seen.has(key)) {
173
+ options.push({
174
+ id: key,
175
+ label: `Using ${varName} from environment`,
176
+ source: "env",
177
+ token,
178
+ status: "connected",
179
+ });
180
+ seen.add(key);
181
+ }
182
+ // Only show the first env var that has a token — they're likely the same value
183
+ break;
184
+ }
185
+ }
186
+ const ghUsers = readGhUsernames("github.com");
187
+ for (const user of ghUsers) {
188
+ const token = readGhTokenForUser(user, "github.com").token;
189
+ const label = `GitHub CLI account: ${user}`;
190
+ const key = `gh:${user}`;
191
+ if (!seen.has(key)) {
192
+ options.push({
193
+ id: key,
194
+ label,
195
+ source: "gh",
196
+ login: user,
197
+ token,
198
+ profileLabel: sanitizeProfileLabel(user),
199
+ status: token ? "connected" : "none",
200
+ });
201
+ seen.add(key);
202
+ }
203
+ }
204
+ // Check existing Copilot auth profiles in the store — these already have
205
+ // working tokens and don't need device flow re-authentication.
206
+ const store = ensureAuthProfileStore();
207
+ syncExternalCliCredentials(store);
208
+ const copilotProfiles = listProfilesForProvider(store, "github-copilot");
209
+ for (const profileId of copilotProfiles) {
210
+ const profile = store.profiles[profileId];
211
+ if (!profile)
212
+ continue;
213
+ // Extract the login name from the profile ID (e.g. "github-copilot:hole_axoncorp" → "hole_axoncorp")
214
+ const login = profileId.split(":").slice(1).join(":") || profileId;
215
+ const key = `profile:${login}`;
216
+ if (seen.has(key))
217
+ continue;
218
+ // For OAuth profiles, the refresh token is the original GitHub token
219
+ // that can be used for Copilot token exchange via loginWithGitHubCopilotToken.
220
+ const token = profile.type === "oauth" && profile.refresh ? profile.refresh : undefined;
221
+ const isFresh = profile.type === "oauth" && Date.now() < profile.expires;
222
+ options.push({
223
+ id: key,
224
+ label: `Copilot profile: ${login}`,
225
+ source: "copilot",
226
+ login,
227
+ token,
228
+ profileLabel: sanitizeProfileLabel(login),
229
+ status: isFresh || token ? "connected" : "none",
230
+ });
231
+ seen.add(key);
232
+ }
233
+ const copilot = readCopilotLastLoggedInUser();
234
+ if (copilot.login) {
235
+ const key = `copilot:${copilot.login}`;
236
+ // Only add if not already covered by an auth profile above
237
+ if (!seen.has(key) && !seen.has(`profile:${copilot.login}`)) {
238
+ options.push({
239
+ id: key,
240
+ label: `Copilot CLI last login: ${copilot.login}`,
241
+ source: "copilot",
242
+ login: copilot.login,
243
+ profileLabel: sanitizeProfileLabel(copilot.login),
244
+ status: "connected",
245
+ });
246
+ seen.add(key);
247
+ }
248
+ }
249
+ options.push({
250
+ id: "device:new",
251
+ label: "Sign in with a new GitHub account (device flow)",
252
+ source: "device",
253
+ status: "none",
254
+ });
255
+ return options;
256
+ }
257
+ // ---------------------------------------------------------------------------
258
+ // Anthropic method picker — 3-method login flow + import + setup-token
259
+ // ---------------------------------------------------------------------------
260
+ function buildAnthropicMethodOptions() {
261
+ const options = [];
262
+ const config = loadConfig();
263
+ if (persistAwsSelectorHintsFromEnv(config)) {
264
+ saveConfig(config);
265
+ }
266
+ const configuredAwsProfile = config.awsProfile?.trim();
267
+ // 0. Check for ANTHROPIC_API_KEY in environment
268
+ const envKey = process.env.ANTHROPIC_API_KEY?.trim();
269
+ if (envKey && envKey.length > 8) {
270
+ const looksValid = envKey.startsWith("sk-ant-api");
271
+ options.push({
272
+ id: "env-key",
273
+ label: "Using ANTHROPIC_API_KEY from environment",
274
+ description: looksValid ? "API key detected" : "Key format unrecognized",
275
+ method: "env-key",
276
+ status: looksValid ? "connected" : "none",
277
+ });
278
+ }
279
+ // 1. Check existing Anthropic profiles in the auth store
280
+ const store = ensureAuthProfileStore();
281
+ syncExternalCliCredentials(store);
282
+ const anthropicProfiles = listProfilesForProvider(store, "anthropic");
283
+ for (const profileId of anthropicProfiles) {
284
+ const profile = store.profiles[profileId];
285
+ if (!profile)
286
+ continue;
287
+ const isFresh = (profile.type === "oauth" || profile.type === "token") &&
288
+ "expires" in profile &&
289
+ typeof profile.expires === "number" &&
290
+ profile.expires > Date.now();
291
+ options.push({
292
+ id: `profile:${profileId}`,
293
+ label: `Saved profile: ${profileId}`,
294
+ description: isFresh ? "Credentials active" : "Credentials expired — will refresh on use",
295
+ method: "api-key", // existing profiles don't need a new login method
296
+ status: isFresh ? "connected" : "available",
297
+ });
298
+ }
299
+ // 2. Check if Claude Code CLI credentials exist
300
+ const claudeCred = readClaudeCodeCredentialsCached();
301
+ if (claudeCred) {
302
+ const isFresh = claudeCred.expires > Date.now();
303
+ options.push({
304
+ id: "claude-cli",
305
+ label: "Import from Claude Code CLI",
306
+ description: isFresh
307
+ ? "Use existing Claude Code credentials from keychain"
308
+ : "Credentials expired, will refresh",
309
+ method: "claude-cli",
310
+ status: isFresh ? "connected" : "available",
311
+ });
312
+ }
313
+ // 3. Claude subscription (OAuth via claude.ai)
314
+ options.push({
315
+ id: "subscription",
316
+ label: "Claude account with subscription",
317
+ description: "Pro, Max, Team, or Enterprise",
318
+ method: "subscription",
319
+ status: resolveProviderStatus("anthropic") === "connected" ? "connected" : "none",
320
+ });
321
+ // 4. Console account (API key)
322
+ options.push({
323
+ id: "console",
324
+ label: "Anthropic Console account",
325
+ description: "API usage billing",
326
+ method: "console",
327
+ status: "none",
328
+ });
329
+ // 5. Setup token (from `claude setup-token`)
330
+ options.push({
331
+ id: "setup-token",
332
+ label: "Paste setup-token",
333
+ description: "From `claude setup-token` or admin provisioning",
334
+ method: "setup-token",
335
+ status: "none",
336
+ });
337
+ // 6. Bedrock (3rd-party platform) — always shown with appropriate status
338
+ {
339
+ const bedrockStatus = resolveProviderStatus("bedrock");
340
+ const hasAwsProfile = !!configuredAwsProfile;
341
+ options.push({
342
+ id: "bedrock",
343
+ label: "3rd-party platform",
344
+ description: hasAwsProfile
345
+ ? `Amazon Bedrock (profile=${configuredAwsProfile})`
346
+ : "Amazon Bedrock — configure daemon-owned awsProfile/region selectors",
347
+ method: "bedrock",
348
+ status: bedrockStatus === "connected" ? "connected" : hasAwsProfile ? "available" : "none",
349
+ });
350
+ }
351
+ return options;
352
+ }
353
+ export async function handleAnthropicMethodSelection(methodId) {
354
+ switch (methodId) {
355
+ case "subscription":
356
+ return { mode: "oauth", provider: "anthropic" };
357
+ case "console":
358
+ case "api-key":
359
+ return { mode: "anthropic_key_input", provider: "anthropic" };
360
+ case "setup-token":
361
+ return { mode: "anthropic_setup_token", provider: "anthropic" };
362
+ case "env-key": {
363
+ const key = process.env.ANTHROPIC_API_KEY?.trim();
364
+ if (!key) {
365
+ return {
366
+ mode: "direct",
367
+ result: { success: false, message: "ANTHROPIC_API_KEY not set in environment" },
368
+ };
369
+ }
370
+ upsertAuthProfile({
371
+ profileId: "anthropic:env",
372
+ credential: { type: "api_key", provider: "anthropic", key },
373
+ });
374
+ return {
375
+ mode: "direct",
376
+ result: { success: true, message: "Saved ANTHROPIC_API_KEY from environment" },
377
+ };
378
+ }
379
+ case "claude-cli": {
380
+ const cred = readClaudeCodeCredentialsCached();
381
+ if (!cred) {
382
+ return {
383
+ mode: "direct",
384
+ result: {
385
+ success: false,
386
+ message: "No Claude Code credentials found. Run `claude login` first.",
387
+ },
388
+ };
389
+ }
390
+ if (cred.type === "oauth") {
391
+ upsertAuthProfile({
392
+ profileId: "anthropic:claude-cli",
393
+ credential: {
394
+ type: "oauth",
395
+ provider: "anthropic",
396
+ access: cred.access,
397
+ refresh: cred.refresh,
398
+ expires: cred.expires,
399
+ },
400
+ });
401
+ return {
402
+ mode: "direct",
403
+ result: { success: true, message: "Imported Claude Code OAuth credentials" },
404
+ };
405
+ }
406
+ if (cred.type === "token") {
407
+ upsertAuthProfile({
408
+ profileId: "anthropic:claude-cli",
409
+ credential: {
410
+ type: "token",
411
+ provider: "anthropic",
412
+ token: cred.token,
413
+ expires: cred.expires,
414
+ },
415
+ });
416
+ return {
417
+ mode: "direct",
418
+ result: { success: true, message: "Imported Claude Code token" },
419
+ };
420
+ }
421
+ return {
422
+ mode: "direct",
423
+ result: { success: false, message: "Unknown Claude Code credential type" },
424
+ };
425
+ }
426
+ case "bedrock":
427
+ return handleBedrockLogin();
428
+ default: {
429
+ if (methodId.startsWith("profile:")) {
430
+ return {
431
+ mode: "direct",
432
+ result: {
433
+ success: true,
434
+ message: `Selected profile: ${methodId.replace("profile:", "")}`,
435
+ },
436
+ };
437
+ }
438
+ return {
439
+ mode: "direct",
440
+ result: { success: false, message: `Unknown method: ${methodId}` },
441
+ };
442
+ }
443
+ }
444
+ }
445
+ // ---------------------------------------------------------------------------
446
+ // OpenAI method picker — env key + profiles + Codex import + paste key
447
+ // ---------------------------------------------------------------------------
448
+ function buildOpenAIMethodOptions() {
449
+ const options = [];
450
+ // 0. Check for OPENAI_API_KEY in environment
451
+ const envKey = process.env.OPENAI_API_KEY?.trim();
452
+ if (envKey && envKey.length > 8) {
453
+ const looksValid = envKey.startsWith("sk-");
454
+ options.push({
455
+ id: "env-key",
456
+ label: "Using OPENAI_API_KEY from environment",
457
+ description: looksValid ? "API key detected" : "Key format unrecognized",
458
+ method: "env-key",
459
+ status: looksValid ? "connected" : "none",
460
+ });
461
+ }
462
+ // 1. Check existing OpenAI profiles in the auth store
463
+ const store = ensureAuthProfileStore();
464
+ syncExternalCliCredentials(store);
465
+ const seenProfiles = new Set();
466
+ for (const providerKey of ["openai", "openai-codex"]) {
467
+ const profiles = listProfilesForProvider(store, providerKey);
468
+ for (const profileId of profiles) {
469
+ if (seenProfiles.has(profileId))
470
+ continue;
471
+ seenProfiles.add(profileId);
472
+ const profile = store.profiles[profileId];
473
+ if (!profile)
474
+ continue;
475
+ const isFresh = (profile.type === "oauth" || profile.type === "token") &&
476
+ "expires" in profile &&
477
+ typeof profile.expires === "number" &&
478
+ profile.expires > Date.now();
479
+ options.push({
480
+ id: `profile:${profileId}`,
481
+ label: `Saved profile: ${profileId}`,
482
+ description: isFresh ? "Credentials active" : "Credentials expired — will refresh on use",
483
+ method: "profile",
484
+ status: isFresh ? "connected" : "available",
485
+ });
486
+ }
487
+ }
488
+ // 2. Check if Codex CLI credentials exist
489
+ const codexCred = readCodexCredentialsCached();
490
+ if (codexCred) {
491
+ const isFresh = codexCred.expires > Date.now();
492
+ options.push({
493
+ id: "codex-import",
494
+ label: "Import from Codex CLI",
495
+ description: isFresh ? "Use existing Codex credentials" : "Credentials expired, will refresh",
496
+ method: "codex-import",
497
+ status: isFresh ? "connected" : "available",
498
+ });
499
+ }
500
+ // 3. Paste API key option
501
+ options.push({
502
+ id: "api-key",
503
+ label: "Paste API key",
504
+ description: "Enter your OpenAI sk-* API key",
505
+ method: "api-key",
506
+ status: "none",
507
+ });
508
+ return options;
509
+ }
510
+ export async function handleOpenAIMethodSelection(methodId) {
511
+ switch (methodId) {
512
+ case "api-key":
513
+ return { mode: "openai_key_input", provider: "openai" };
514
+ case "env-key": {
515
+ const key = process.env.OPENAI_API_KEY?.trim();
516
+ if (!key) {
517
+ return {
518
+ mode: "direct",
519
+ result: { success: false, message: "OPENAI_API_KEY not set in environment" },
520
+ };
521
+ }
522
+ upsertAuthProfile({
523
+ profileId: "openai:env",
524
+ credential: { type: "api_key", provider: "openai", key },
525
+ });
526
+ return {
527
+ mode: "direct",
528
+ result: { success: true, message: "Saved OPENAI_API_KEY from environment" },
529
+ };
530
+ }
531
+ case "codex-import": {
532
+ const cred = readCodexCredentialsCached();
533
+ if (!cred) {
534
+ return {
535
+ mode: "direct",
536
+ result: {
537
+ success: false,
538
+ message: "No Codex CLI credentials found. Run `codex auth` first.",
539
+ },
540
+ };
541
+ }
542
+ upsertAuthProfile({
543
+ profileId: OPENAI_CODEX_OAUTH_PROFILE_ID,
544
+ credential: {
545
+ type: "oauth",
546
+ provider: "openai",
547
+ access: cred.access,
548
+ refresh: cred.refresh,
549
+ expires: cred.expires,
550
+ },
551
+ });
552
+ return {
553
+ mode: "direct",
554
+ result: { success: true, message: "Imported Codex CLI OAuth credentials" },
555
+ };
556
+ }
557
+ default: {
558
+ if (methodId.startsWith("profile:")) {
559
+ return {
560
+ mode: "direct",
561
+ result: {
562
+ success: true,
563
+ message: `Selected profile: ${methodId.replace("profile:", "")}`,
564
+ },
565
+ };
566
+ }
567
+ return {
568
+ mode: "direct",
569
+ result: { success: false, message: `Unknown method: ${methodId}` },
570
+ };
571
+ }
572
+ }
573
+ }
574
+ // ---------------------------------------------------------------------------
575
+ // Google method picker — env key + profiles + Gemini import + paste key + OAuth
576
+ // ---------------------------------------------------------------------------
577
+ function buildGoogleMethodOptions() {
578
+ const options = [];
579
+ // 0. Check for GOOGLE_API_KEY or GEMINI_API_KEY in environment
580
+ const envKey = (process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY)?.trim();
581
+ if (envKey && envKey.length > 8) {
582
+ const looksValid = envKey.startsWith("AIza");
583
+ options.push({
584
+ id: "env-key",
585
+ label: `Using ${process.env.GOOGLE_API_KEY ? "GOOGLE_API_KEY" : "GEMINI_API_KEY"} from environment`,
586
+ description: looksValid ? "API key detected" : "Key format unrecognized",
587
+ method: "env-key",
588
+ status: looksValid ? "connected" : "none",
589
+ });
590
+ }
591
+ // 1. Check existing Google profiles in the auth store
592
+ const store = ensureAuthProfileStore();
593
+ syncExternalCliCredentials(store);
594
+ const googleProfiles = listProfilesForProvider(store, "google");
595
+ for (const profileId of googleProfiles) {
596
+ const profile = store.profiles[profileId];
597
+ if (!profile)
598
+ continue;
599
+ const isFresh = (profile.type === "oauth" || profile.type === "token") &&
600
+ "expires" in profile &&
601
+ typeof profile.expires === "number" &&
602
+ profile.expires > Date.now();
603
+ options.push({
604
+ id: `profile:${profileId}`,
605
+ label: `Saved profile: ${profileId}`,
606
+ description: isFresh ? "Credentials active" : "Credentials expired — will refresh on use",
607
+ method: "profile",
608
+ status: isFresh ? "connected" : "available",
609
+ });
610
+ }
611
+ // 2. Check if Gemini CLI credentials exist
612
+ const geminiCred = readGeminiCredentialsCached();
613
+ if (geminiCred) {
614
+ const isFresh = geminiCred.expires > Date.now();
615
+ options.push({
616
+ id: "gemini-import",
617
+ label: "Import from Gemini CLI",
618
+ description: isFresh
619
+ ? "Use existing Gemini CLI credentials"
620
+ : "Credentials expired, will refresh",
621
+ method: "gemini-import",
622
+ status: isFresh ? "connected" : "available",
623
+ });
624
+ }
625
+ // 3. Paste API key option
626
+ options.push({
627
+ id: "api-key",
628
+ label: "Paste API key",
629
+ description: "Enter your Google AIza* API key",
630
+ method: "api-key",
631
+ status: "none",
632
+ });
633
+ // 4. Gemini CLI OAuth option
634
+ options.push({
635
+ id: "oauth",
636
+ label: "Gemini CLI OAuth",
637
+ description: "Sign in via browser-based OAuth flow",
638
+ method: "oauth",
639
+ status: "none",
640
+ });
641
+ return options;
642
+ }
643
+ export async function handleGoogleMethodSelection(methodId) {
644
+ switch (methodId) {
645
+ case "api-key":
646
+ return { mode: "google_key_input", provider: "google" };
647
+ case "oauth":
648
+ return { mode: "oauth", provider: "google" };
649
+ case "env-key": {
650
+ const key = (process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY)?.trim();
651
+ if (!key) {
652
+ return {
653
+ mode: "direct",
654
+ result: {
655
+ success: false,
656
+ message: "GOOGLE_API_KEY / GEMINI_API_KEY not set in environment",
657
+ },
658
+ };
659
+ }
660
+ upsertAuthProfile({
661
+ profileId: "google:env",
662
+ credential: { type: "api_key", provider: "google", key },
663
+ });
664
+ return {
665
+ mode: "direct",
666
+ result: { success: true, message: "Saved Google API key from environment" },
667
+ };
668
+ }
669
+ case "gemini-import": {
670
+ const cred = readGeminiCredentialsCached();
671
+ if (!cred) {
672
+ return {
673
+ mode: "direct",
674
+ result: {
675
+ success: false,
676
+ message: "No Gemini CLI credentials found. Run `gemini auth` first.",
677
+ },
678
+ };
679
+ }
680
+ upsertAuthProfile({
681
+ profileId: "google:gemini-cli",
682
+ credential: {
683
+ type: "oauth",
684
+ provider: "google",
685
+ access: cred.access,
686
+ refresh: cred.refresh,
687
+ expires: cred.expires,
688
+ },
689
+ });
690
+ return {
691
+ mode: "direct",
692
+ result: { success: true, message: "Imported Gemini CLI OAuth credentials" },
693
+ };
694
+ }
695
+ default: {
696
+ if (methodId.startsWith("profile:")) {
697
+ return {
698
+ mode: "direct",
699
+ result: {
700
+ success: true,
701
+ message: `Selected profile: ${methodId.replace("profile:", "")}`,
702
+ },
703
+ };
704
+ }
705
+ return {
706
+ mode: "direct",
707
+ result: { success: false, message: `Unknown method: ${methodId}` },
708
+ };
709
+ }
710
+ }
711
+ }
712
+ // ---------------------------------------------------------------------------
713
+ // Provider metadata
714
+ // ---------------------------------------------------------------------------
715
+ const SUPPORTED_PROVIDERS = ["bedrock", "anthropic", "google", "openai", "github-copilot"];
716
+ const PROVIDER_LABELS = {
717
+ bedrock: "Bedrock (AWS SSO)",
718
+ anthropic: "Anthropic",
719
+ google: "Google (Gemini)",
720
+ openai: "OpenAI",
721
+ "github-copilot": "GitHub Copilot",
722
+ };
723
+ function isSupportedProvider(name) {
724
+ return SUPPORTED_PROVIDERS.includes(name);
725
+ }
726
+ // ---------------------------------------------------------------------------
727
+ // Provider status resolution
728
+ // ---------------------------------------------------------------------------
729
+ /** Env vars that indicate a provider is available without stored profiles. */
730
+ const PROVIDER_ENV_VARS = {
731
+ anthropic: ["ANTHROPIC_API_KEY"],
732
+ openai: ["OPENAI_API_KEY"],
733
+ google: ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
734
+ "github-copilot": ["GH_TOKEN", "GITHUB_TOKEN", "COPILOT_GITHUB_TOKEN"],
735
+ bedrock: [],
736
+ };
737
+ function resolveProviderStatus(provider) {
738
+ const store = updateAuthProfileStoreWithLockSync({
739
+ updater: (freshStore) => syncExternalCliCredentials(freshStore),
740
+ }) ?? ensureAuthProfileStore();
741
+ const normalized = normalizeProviderId(provider);
742
+ const profileIds = listProfilesForProvider(store, normalized);
743
+ // Check if any profile is active (not expired, not in cooldown)
744
+ for (const id of profileIds) {
745
+ const cred = store.profiles[id];
746
+ if (!cred)
747
+ continue;
748
+ if (isProfileInCooldown(store, id))
749
+ continue;
750
+ // API key profiles are always active if they have a key
751
+ if (cred.type === "api_key" && cred.key?.trim())
752
+ return "connected";
753
+ if (cred.type === "oauth" && "expires" in cred) {
754
+ const expires = cred.expires;
755
+ if (expires && expires < Date.now())
756
+ continue; // expired
757
+ return "connected";
758
+ }
759
+ if (cred.type === "token") {
760
+ const expires = cred.expires;
761
+ if (!expires || Date.now() < expires)
762
+ return "connected";
763
+ continue; // expired
764
+ }
765
+ // Unknown type with no expiry — treat as active
766
+ return "connected";
767
+ }
768
+ // Check environment variables
769
+ const vars = PROVIDER_ENV_VARS[normalized] ?? [];
770
+ for (const v of vars) {
771
+ if (process.env[v]?.trim())
772
+ return "connected";
773
+ }
774
+ // Profiles exist but none are active → expired; otherwise → none
775
+ return profileIds.length > 0 ? "expired" : "none";
776
+ }
777
+ // ---------------------------------------------------------------------------
778
+ // getProviderOptions — build the picker list
779
+ // ---------------------------------------------------------------------------
780
+ export function getProviderOptions() {
781
+ return SUPPORTED_PROVIDERS.map((id) => {
782
+ const status = resolveProviderStatus(id);
783
+ const store = ensureAuthProfileStore();
784
+ const profileIds = listProfilesForProvider(store, id);
785
+ // Try to find an email from any profile
786
+ let email;
787
+ for (const pid of profileIds) {
788
+ const cred = store.profiles[pid];
789
+ if (cred?.email) {
790
+ email = cred.email;
791
+ break;
792
+ }
793
+ }
794
+ return {
795
+ id,
796
+ label: PROVIDER_LABELS[id],
797
+ status,
798
+ ...(email ? { email } : {}),
799
+ };
800
+ });
801
+ }
802
+ // ---------------------------------------------------------------------------
803
+ // Bedrock SSO login — tries silent refresh first, then interactive
804
+ // ---------------------------------------------------------------------------
805
+ async function handleBedrockLogin(profile) {
806
+ const config = loadConfig();
807
+ const selectedProfile = profile?.trim() || config.awsProfile?.trim();
808
+ const selectedRegion = config.awsRegion?.trim();
809
+ const selector = {
810
+ awsProfile: selectedProfile,
811
+ awsRegion: selectedRegion,
812
+ awsConfigFile: config.awsConfigFile?.trim(),
813
+ awsSharedCredentialsFile: config.awsSharedCredentialsFile?.trim(),
814
+ };
815
+ if (!selectedProfile) {
816
+ return {
817
+ mode: "direct",
818
+ result: {
819
+ success: false,
820
+ message: "Bedrock is not configured. Set daemon-owned awsProfile (and ideally awsRegion) selectors before logging in.",
821
+ },
822
+ };
823
+ }
824
+ // Step 1: silent refresh
825
+ const silentOk = await refreshBedrockSsoToken(selector);
826
+ if (silentOk) {
827
+ return {
828
+ mode: "direct",
829
+ result: { success: true, message: "Bedrock SSO token refreshed (silent)" },
830
+ };
831
+ }
832
+ // Step 2: interactive aws sso login
833
+ const loginOk = await loginBedrockSso(selector);
834
+ if (loginOk) {
835
+ return {
836
+ mode: "direct",
837
+ result: {
838
+ success: true,
839
+ message: `Bedrock SSO login succeeded — credentials refreshed${selectedRegion ? ` (${selectedProfile} @ ${selectedRegion})` : ` (${selectedProfile})`}`,
840
+ },
841
+ };
842
+ }
843
+ return {
844
+ mode: "direct",
845
+ result: {
846
+ success: false,
847
+ message: [
848
+ "Bedrock SSO login failed.",
849
+ "The daemon resolves Bedrock auth from its configured AWS profile/region selectors and AWS shared config/SSO cache.",
850
+ "Try running manually: aws sso login --profile " + selectedProfile,
851
+ ].join("\n"),
852
+ },
853
+ };
854
+ }
855
+ // ---------------------------------------------------------------------------
856
+ // API key login — save directly
857
+ // ---------------------------------------------------------------------------
858
+ function handleApiKeyLogin(provider, apiKey) {
859
+ if (apiKey.length < 8) {
860
+ return {
861
+ mode: "direct",
862
+ result: { success: false, message: "API key too short (minimum 8 characters)" },
863
+ };
864
+ }
865
+ const profileId = `${provider}:manual`;
866
+ upsertAuthProfile({
867
+ profileId,
868
+ credential: { type: "api_key", provider, key: apiKey },
869
+ });
870
+ return {
871
+ mode: "direct",
872
+ result: { success: true, message: `Saved ${provider} API key (profile: ${profileId})` },
873
+ };
874
+ }
875
+ function handleAnthropicSetupTokenLogin(token) {
876
+ if (token.length < 8) {
877
+ return {
878
+ mode: "direct",
879
+ result: { success: false, message: "Setup token too short (minimum 8 characters)" },
880
+ };
881
+ }
882
+ const profileId = "anthropic:setup-token";
883
+ upsertAuthProfile({
884
+ profileId,
885
+ credential: { type: "api_key", provider: "anthropic", key: token },
886
+ });
887
+ return {
888
+ mode: "direct",
889
+ result: { success: true, message: `Saved Anthropic setup token (profile: ${profileId})` },
890
+ };
891
+ }
892
+ // ---------------------------------------------------------------------------
893
+ // loginProvider — handle login for a specific provider
894
+ // ---------------------------------------------------------------------------
895
+ export async function loginProvider(provider, args) {
896
+ if (!isSupportedProvider(provider)) {
897
+ return {
898
+ mode: "direct",
899
+ result: {
900
+ success: false,
901
+ message: `Unknown provider "${provider}". Supported: ${SUPPORTED_PROVIDERS.join(", ")}`,
902
+ },
903
+ };
904
+ }
905
+ // Bedrock: always SSO flow
906
+ if (provider === "bedrock") {
907
+ const trimmedArgs = args?.trim();
908
+ if (trimmedArgs) {
909
+ const parts = trimmedArgs.split(/\s+/);
910
+ const nextConfig = loadConfig();
911
+ let mutated = false;
912
+ const candidateProfile = parts[0]?.trim();
913
+ if (candidateProfile) {
914
+ nextConfig.awsProfile = candidateProfile;
915
+ mutated = true;
916
+ }
917
+ const candidateRegion = parts[1]?.trim();
918
+ if (candidateRegion) {
919
+ nextConfig.awsRegion = candidateRegion;
920
+ mutated = true;
921
+ }
922
+ if (persistAwsSelectorHintsFromEnv(nextConfig)) {
923
+ mutated = true;
924
+ }
925
+ if (mutated) {
926
+ saveConfig(nextConfig);
927
+ }
928
+ }
929
+ return handleBedrockLogin();
930
+ }
931
+ // GitHub Copilot: token shortcut or interactive device-code flow
932
+ if (provider === "github-copilot") {
933
+ const parsed = parseCopilotLoginArgs(args);
934
+ if (!parsed.token && !parsed.profileLabel && parsed.autoSelectSource) {
935
+ const options = buildCopilotSourceOptions();
936
+ return {
937
+ mode: "copilot_source_picker",
938
+ provider: "github-copilot",
939
+ options,
940
+ };
941
+ }
942
+ if (parsed.token) {
943
+ const result = await loginWithGitHubCopilotToken({
944
+ githubToken: parsed.token,
945
+ profileLabel: parsed.profileLabel,
946
+ });
947
+ return {
948
+ mode: "direct",
949
+ result: {
950
+ success: result.success,
951
+ message: result.message,
952
+ },
953
+ };
954
+ }
955
+ // No explicit token provided: best-effort import from GitHub CLI auth.
956
+ if (parsed.useGhToken) {
957
+ const gh = readGhAuthToken();
958
+ if (gh.token) {
959
+ const result = await loginWithGitHubCopilotToken({
960
+ githubToken: gh.token,
961
+ profileLabel: parsed.profileLabel,
962
+ });
963
+ if (result.success) {
964
+ return {
965
+ mode: "direct",
966
+ result: {
967
+ success: true,
968
+ message: `${result.message} (imported from gh auth token)`,
969
+ },
970
+ };
971
+ }
972
+ return {
973
+ mode: "copilot_device",
974
+ provider: "github-copilot",
975
+ profileLabel: parsed.profileLabel,
976
+ message: `gh auth token import failed: ${result.message}\nFalling back to interactive device login...`,
977
+ };
978
+ }
979
+ return {
980
+ mode: "copilot_device",
981
+ provider: "github-copilot",
982
+ profileLabel: parsed.profileLabel,
983
+ ...(gh.error ? { message: `Could not read gh auth token: ${gh.error}` } : {}),
984
+ };
985
+ }
986
+ return {
987
+ mode: "copilot_device",
988
+ provider: "github-copilot",
989
+ profileLabel: parsed.profileLabel,
990
+ };
991
+ }
992
+ // Anthropic: 3-method picker or --method dispatch
993
+ if (provider === "anthropic") {
994
+ const keyArg = args?.trim();
995
+ if (keyArg?.startsWith("--setup-token")) {
996
+ const token = keyArg.replace(/^--setup-token\s*/, "").trim();
997
+ return handleAnthropicSetupTokenLogin(token);
998
+ }
999
+ // `/login anthropic --method <method>` — handle specific method
1000
+ if (keyArg?.startsWith("--method")) {
1001
+ const methodId = keyArg.replace(/^--method\s*/, "").trim();
1002
+ return handleAnthropicMethodSelection(methodId);
1003
+ }
1004
+ // `/login anthropic <api-key>` — direct API key (preserve existing behavior)
1005
+ if (keyArg) {
1006
+ return handleApiKeyLogin(provider, keyArg);
1007
+ }
1008
+ // `/login anthropic` with no args → show method picker
1009
+ const options = buildAnthropicMethodOptions();
1010
+ return {
1011
+ mode: "anthropic_method_picker",
1012
+ provider: "anthropic",
1013
+ options,
1014
+ };
1015
+ }
1016
+ // OpenAI: method picker or direct key
1017
+ if (provider === "openai") {
1018
+ const keyArg = args?.trim();
1019
+ if (keyArg?.startsWith("--method")) {
1020
+ const methodId = keyArg.replace(/^--method\s*/, "").trim();
1021
+ return handleOpenAIMethodSelection(methodId);
1022
+ }
1023
+ if (keyArg) {
1024
+ return handleApiKeyLogin(provider, keyArg);
1025
+ }
1026
+ const options = buildOpenAIMethodOptions();
1027
+ return {
1028
+ mode: "openai_method_picker",
1029
+ provider: "openai",
1030
+ options,
1031
+ };
1032
+ }
1033
+ // Google: method picker or direct key
1034
+ if (provider === "google") {
1035
+ const keyArg = args?.trim();
1036
+ if (keyArg?.startsWith("--method")) {
1037
+ const methodId = keyArg.replace(/^--method\s*/, "").trim();
1038
+ return handleGoogleMethodSelection(methodId);
1039
+ }
1040
+ if (keyArg) {
1041
+ return handleApiKeyLogin(provider, keyArg);
1042
+ }
1043
+ const options = buildGoogleMethodOptions();
1044
+ return {
1045
+ mode: "google_method_picker",
1046
+ provider: "google",
1047
+ options,
1048
+ };
1049
+ }
1050
+ // Fallback: direct key or OAuth
1051
+ const keyArg = args?.trim();
1052
+ if (keyArg) {
1053
+ return handleApiKeyLogin(provider, keyArg);
1054
+ }
1055
+ return { mode: "oauth", provider };
1056
+ }
1057
+ // ---------------------------------------------------------------------------
1058
+ // handleLoginCommand — entry point from REPL command dispatch
1059
+ // ---------------------------------------------------------------------------
1060
+ export async function handleLoginCommand(args) {
1061
+ const parts = args.trim().split(/\s+/);
1062
+ const providerArg = parts[0]?.toLowerCase() || "";
1063
+ const keyArg = parts.slice(1).join(" ").trim();
1064
+ // /login with no args → show interactive picker
1065
+ if (!providerArg) {
1066
+ return { mode: "picker", providers: getProviderOptions() };
1067
+ }
1068
+ if (providerArg === "github-copilot" && keyArg.startsWith("--from ")) {
1069
+ const sourceId = keyArg.slice("--from ".length).trim();
1070
+ const options = buildCopilotSourceOptions();
1071
+ const selected = options.find((o) => o.id === sourceId);
1072
+ if (!selected) {
1073
+ return {
1074
+ mode: "direct",
1075
+ result: { success: false, message: `Unknown Copilot source: ${sourceId}` },
1076
+ };
1077
+ }
1078
+ if (selected.source === "device") {
1079
+ return {
1080
+ mode: "copilot_device",
1081
+ provider: "github-copilot",
1082
+ profileLabel: selected.profileLabel,
1083
+ };
1084
+ }
1085
+ if (selected.token) {
1086
+ const result = await loginWithGitHubCopilotToken({
1087
+ githubToken: selected.token,
1088
+ profileLabel: selected.profileLabel,
1089
+ });
1090
+ return {
1091
+ mode: "direct",
1092
+ result: {
1093
+ success: result.success,
1094
+ message: result.message,
1095
+ },
1096
+ };
1097
+ }
1098
+ if (selected.login) {
1099
+ return {
1100
+ mode: "copilot_device",
1101
+ provider: "github-copilot",
1102
+ profileLabel: sanitizeProfileLabel(selected.login),
1103
+ };
1104
+ }
1105
+ }
1106
+ return loginProvider(providerArg, keyArg || undefined);
1107
+ }
1108
+ //# sourceMappingURL=login-handler.js.map