@aria-cli/cli 1.0.50 → 1.0.51

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 (319) hide show
  1. package/bin/aria.mjs +1 -1
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/attached-local-control-client.js +826 -0
  4. package/dist/bootstrap-local-control-client.js +2 -0
  5. package/dist/capability-aware-method-proxy.js +42 -0
  6. package/dist/cli-context.js +160 -0
  7. package/dist/commands/arions.js +174 -0
  8. package/dist/commands/auth.js +123 -0
  9. package/dist/commands/daemon.js +245 -0
  10. package/dist/commands/definitions.js +176 -0
  11. package/dist/commands/index.js +74 -0
  12. package/dist/commands/login-handler.js +1108 -0
  13. package/dist/commands/logout-handler.js +92 -0
  14. package/dist/commands/memory-handlers.js +89 -0
  15. package/dist/commands/pairing.js +60 -0
  16. package/dist/commands/runtime-cutover-reset-command.js +12 -0
  17. package/dist/commands/runtime-cutover-reset.js +265 -0
  18. package/dist/commands/terminal-setup.js +84 -0
  19. package/dist/config/aria-config.js +238 -0
  20. package/dist/config/index.js +3 -0
  21. package/dist/config/loader.js +97 -0
  22. package/dist/config.js +142 -0
  23. package/dist/daemon-info.js +10 -0
  24. package/dist/ensure-daemon.js +128 -0
  25. package/dist/entrypoints/command-mode.js +5 -0
  26. package/dist/entrypoints/daemon.js +50 -0
  27. package/dist/entrypoints/headless-stdio.js +25 -0
  28. package/dist/entrypoints/interactive.js +80 -0
  29. package/dist/event-loop-watchdog.js +73 -0
  30. package/dist/headless/auth-orchestrator.js +508 -0
  31. package/dist/headless/auth-service.js +43 -0
  32. package/dist/headless/bootstrap-fast-path.js +112 -0
  33. package/dist/headless/call-command.js +143 -0
  34. package/dist/headless/daemon-service.js +318 -0
  35. package/dist/headless/hook-actions.js +235 -0
  36. package/dist/headless/hook-service.js +42 -0
  37. package/dist/headless/kernel-services.js +216 -0
  38. package/dist/headless/kernel.js +785 -0
  39. package/dist/headless/operations/arion.js +119 -0
  40. package/dist/headless/operations/auth.js +45 -0
  41. package/dist/headless/operations/client.js +31 -0
  42. package/dist/headless/operations/config.js +69 -0
  43. package/dist/headless/operations/daemon.js +47 -0
  44. package/dist/headless/operations/hook.js +56 -0
  45. package/dist/headless/operations/index.js +11 -0
  46. package/dist/headless/operations/memory.js +102 -0
  47. package/dist/headless/operations/message.js +279 -0
  48. package/dist/headless/operations/model.js +100 -0
  49. package/dist/headless/operations/peer.js +56 -0
  50. package/dist/headless/operations/run.js +24 -0
  51. package/dist/headless/operations/session.js +90 -0
  52. package/dist/headless/operations/system.js +19 -0
  53. package/dist/headless/operations/utils.js +35 -0
  54. package/dist/headless/run-orchestrator.js +703 -0
  55. package/dist/headless/stdio-server.js +439 -0
  56. package/dist/history/SessionHistory.js +8 -0
  57. package/dist/history/SessionHistoryClient.js +186 -0
  58. package/dist/history/conversation-message.js +112 -0
  59. package/dist/history/index.js +8 -0
  60. package/dist/history/jsonl-replay.js +154 -0
  61. package/dist/history/repair-tool-pairing.js +84 -0
  62. package/dist/history/stall-phase-bridge.js +11 -0
  63. package/dist/history/turn-accumulator.js +427 -0
  64. package/dist/index.js +7 -0
  65. package/dist/ink-repl.js +4183 -0
  66. package/dist/local-control-bootstrap.js +26 -0
  67. package/dist/local-control-client.js +2 -0
  68. package/dist/local-control-error-reporting.js +34 -0
  69. package/dist/local-control-http-client.js +362 -0
  70. package/dist/local-control-lazy-wrapper.js +363 -0
  71. package/dist/local-control-manager.js +146 -0
  72. package/dist/main.js +38 -0
  73. package/dist/network-security.js +62 -0
  74. package/dist/networking-server.js +38 -0
  75. package/dist/peer-identity.js +23 -0
  76. package/dist/polling-subscription.js +34 -0
  77. package/dist/relaunch.js +588 -0
  78. package/dist/release-notes.js +35 -0
  79. package/dist/repl-cleanup.js +47 -0
  80. package/dist/runtime/configure-bun-sqlite.js +3 -0
  81. package/dist/runtime/crash-handlers.js +111 -0
  82. package/dist/runtime/interactive-invocation.js +39 -0
  83. package/dist/runtime/internal-mode.js +14 -0
  84. package/dist/runtime/launch-spec.js +64 -0
  85. package/dist/runtime/owner-lease.js +44 -0
  86. package/dist/runtime/public-mode.js +20 -0
  87. package/dist/runtime/run-internal-mode.js +18 -0
  88. package/dist/runtime/runtime-kind.js +32 -0
  89. package/dist/runtime/spawn-aria.js +38 -0
  90. package/dist/selectable-client.js +2 -0
  91. package/dist/selectable-peer.js +2 -0
  92. package/dist/session.js +203 -0
  93. package/dist/slash-commands.js +80 -0
  94. package/dist/sounds.js +210 -0
  95. package/dist/ui/App.js +526 -0
  96. package/dist/ui/components/AnthropicMethodPicker.js +6 -0
  97. package/dist/ui/components/ArionPrompt.js +15 -0
  98. package/dist/ui/components/AutocompleteDropdown.js +23 -0
  99. package/dist/ui/components/AutonomySelector.js +55 -0
  100. package/dist/ui/components/Banner.js +98 -0
  101. package/dist/ui/components/ConversationHistory.js +175 -0
  102. package/dist/ui/components/CopilotDeviceLoginFlow.js +88 -0
  103. package/dist/ui/components/CopilotSourcePicker.js +50 -0
  104. package/dist/ui/components/Cost.js +10 -0
  105. package/dist/ui/components/CustomSelect/option-map.js +30 -0
  106. package/dist/ui/components/CustomSelect/select-option.js +13 -0
  107. package/dist/ui/components/CustomSelect/select.js +42 -0
  108. package/dist/ui/components/CustomSelect/use-select-state.js +179 -0
  109. package/dist/ui/components/CustomSelect/use-select.js +15 -0
  110. package/dist/ui/components/ErrorDisplay.js +35 -0
  111. package/dist/ui/components/FallbackToolUseRejectedMessage.js +7 -0
  112. package/dist/ui/components/FileEditToolUpdatedMessage.js +57 -0
  113. package/dist/ui/components/HandoffMarker.js +18 -0
  114. package/dist/ui/components/HighlightedCode.js +21 -0
  115. package/dist/ui/components/InputArea.js +187 -0
  116. package/dist/ui/components/Message.js +25 -0
  117. package/dist/ui/components/OAuthLoginFlow.js +113 -0
  118. package/dist/ui/components/OutputTruncation.js +35 -0
  119. package/dist/ui/components/PermissionPrompt.js +79 -0
  120. package/dist/ui/components/PipelineTimingPanel.js +15 -0
  121. package/dist/ui/components/ProviderMethodPicker.js +61 -0
  122. package/dist/ui/components/ProviderPicker.js +63 -0
  123. package/dist/ui/components/RenderItemView.js +71 -0
  124. package/dist/ui/components/Spinner.js +46 -0
  125. package/dist/ui/components/StatusBar.js +95 -0
  126. package/dist/ui/components/StreamingIndicator.js +55 -0
  127. package/dist/ui/components/StructuredDiff.js +168 -0
  128. package/dist/ui/components/TextInputOverlay.js +43 -0
  129. package/dist/ui/components/ThinkingBlock.js +82 -0
  130. package/dist/ui/components/ToolCost.js +17 -0
  131. package/dist/ui/components/ToolExecution.js +61 -0
  132. package/dist/ui/components/ToolHeader.js +51 -0
  133. package/dist/ui/components/ToolRenderLayoutContext.js +14 -0
  134. package/dist/ui/components/ToolResultWrapper.js +6 -0
  135. package/dist/ui/components/ToolUseLoader.js +35 -0
  136. package/dist/ui/components/TraceWaterfall.js +91 -0
  137. package/dist/ui/components/index.js +33 -0
  138. package/dist/ui/components/messages/AssistantTextMessage.js +25 -0
  139. package/dist/ui/components/messages/UserImageMessage.js +12 -0
  140. package/dist/ui/components/messages/UserTextMessage.js +12 -0
  141. package/dist/ui/components/overlays/ArionSelector.js +68 -0
  142. package/dist/ui/components/overlays/ClientSelector.js +62 -0
  143. package/dist/ui/components/overlays/CommandPalette.js +67 -0
  144. package/dist/ui/components/overlays/DaemonControl.js +87 -0
  145. package/dist/ui/components/overlays/InviteShareOverlay.js +15 -0
  146. package/dist/ui/components/overlays/JoinInviteOverlay.js +32 -0
  147. package/dist/ui/components/overlays/MemoryBrowser.js +100 -0
  148. package/dist/ui/components/overlays/MessageSelector.js +123 -0
  149. package/dist/ui/components/overlays/ModelSelector.js +211 -0
  150. package/dist/ui/components/overlays/PairRequestOverlay.js +42 -0
  151. package/dist/ui/components/overlays/PeerSelector.js +84 -0
  152. package/dist/ui/components/overlays/SessionSelector.js +102 -0
  153. package/dist/ui/components/overlays/SoundSelector.js +86 -0
  154. package/dist/ui/components/overlays/ThemeSelector.js +139 -0
  155. package/dist/ui/components/overlays/index.js +15 -0
  156. package/dist/ui/components/permissions/BashPermissionRequest/BashPermissionRequest.js +53 -0
  157. package/dist/ui/components/permissions/FallbackPermissionRequest.js +56 -0
  158. package/dist/ui/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.js +76 -0
  159. package/dist/ui/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js +18 -0
  160. package/dist/ui/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.js +64 -0
  161. package/dist/ui/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js +26 -0
  162. package/dist/ui/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +141 -0
  163. package/dist/ui/components/permissions/PermissionRequest.js +70 -0
  164. package/dist/ui/components/permissions/PermissionRequestTitle.js +41 -0
  165. package/dist/ui/components/permissions/hooks.js +10 -0
  166. package/dist/ui/components/permissions/toolUseOptions.js +68 -0
  167. package/dist/ui/components/permissions/utils.js +10 -0
  168. package/dist/ui/components/text-input/Cursor.js +326 -0
  169. package/dist/ui/components/text-input/TextInput.js +231 -0
  170. package/dist/ui/components/text-input/imagePaste.js +28 -0
  171. package/dist/ui/components/text-input/index.js +6 -0
  172. package/dist/ui/components/text-input/useDoublePress.js +30 -0
  173. package/dist/ui/components/text-input/useTextInput.js +245 -0
  174. package/dist/ui/components/tool-types.js +9 -0
  175. package/dist/ui/constants/figures.js +4 -0
  176. package/dist/ui/constants/index.js +3 -0
  177. package/dist/ui/display-mode.js +93 -0
  178. package/dist/ui/display-policy.js +19 -0
  179. package/dist/ui/hooks/index.js +6 -0
  180. package/dist/ui/hooks/useCommandAutocomplete.js +93 -0
  181. package/dist/ui/hooks/useDoublePress.js +37 -0
  182. package/dist/ui/hooks/useIndicatorState.js +55 -0
  183. package/dist/ui/hooks/useInterval.js +23 -0
  184. package/dist/ui/hooks/useKeyboardShortcuts.js +127 -0
  185. package/dist/ui/hooks/useTerminalSize.js +55 -0
  186. package/dist/ui/hooks/useUnifiedMessages.js +117 -0
  187. package/dist/ui/indicator-state.js +44 -0
  188. package/dist/ui/markdown/highlight.js +44 -0
  189. package/dist/ui/markdown/index.js +1460 -0
  190. package/dist/ui/markdown/tokenizer.js +24 -0
  191. package/dist/ui/render-item.js +5 -0
  192. package/dist/ui/screens/REPL.js +119 -0
  193. package/dist/ui/screens/approval-lifecycle.js +38 -0
  194. package/dist/ui/status-line.js +72 -0
  195. package/dist/ui/theme/index.js +51 -0
  196. package/dist/ui/theme/themes/claude-dark-daltonized.js +51 -0
  197. package/dist/ui/theme/themes/claude-dark.js +50 -0
  198. package/dist/ui/theme/themes/claude-light-daltonized.js +51 -0
  199. package/dist/ui/theme/themes/claude-light.js +50 -0
  200. package/dist/ui/theme/themes/dark-accessible.js +18 -0
  201. package/dist/ui/theme/themes/dark.js +49 -0
  202. package/dist/ui/theme/themes/light-accessible.js +18 -0
  203. package/dist/ui/theme/themes/light.js +49 -0
  204. package/dist/ui/theme/types.js +3 -0
  205. package/dist/ui/theme.js +142 -0
  206. package/dist/ui/to-render-items.js +145 -0
  207. package/dist/ui/tools/AgentTool/index.js +30 -0
  208. package/dist/ui/tools/ArchitectTool/index.js +31 -0
  209. package/dist/ui/tools/AskUserTool/index.js +46 -0
  210. package/dist/ui/tools/BashTool/BashToolResultMessage.js +11 -0
  211. package/dist/ui/tools/BashTool/OutputLine.js +21 -0
  212. package/dist/ui/tools/BashTool/index.js +91 -0
  213. package/dist/ui/tools/BrowseTool/index.js +43 -0
  214. package/dist/ui/tools/BrowserTool/index.js +47 -0
  215. package/dist/ui/tools/CbmTool/index.js +188 -0
  216. package/dist/ui/tools/CheckDelegationTool/index.js +46 -0
  217. package/dist/ui/tools/CheckMessagesTool/index.js +85 -0
  218. package/dist/ui/tools/CreateQuipTool/index.js +30 -0
  219. package/dist/ui/tools/CreateSkillTool/index.js +22 -0
  220. package/dist/ui/tools/CreateToolTool/index.js +31 -0
  221. package/dist/ui/tools/DelegateRemoteTool/index.js +42 -0
  222. package/dist/ui/tools/DeployTool/index.js +47 -0
  223. package/dist/ui/tools/FffTool/index.js +103 -0
  224. package/dist/ui/tools/FileEditTool/index.js +67 -0
  225. package/dist/ui/tools/FileReadTool/index.js +68 -0
  226. package/dist/ui/tools/FileWriteTool/index.js +61 -0
  227. package/dist/ui/tools/ForkTool/index.js +47 -0
  228. package/dist/ui/tools/FrgTool/index.js +96 -0
  229. package/dist/ui/tools/GetThreadTool/index.js +39 -0
  230. package/dist/ui/tools/GlobTool/index.js +50 -0
  231. package/dist/ui/tools/GrepTool/index.js +84 -0
  232. package/dist/ui/tools/HatchArionTool/index.js +36 -0
  233. package/dist/ui/tools/LearnSkillTool/index.js +22 -0
  234. package/dist/ui/tools/LearnTool/index.js +43 -0
  235. package/dist/ui/tools/LearnToolTool/index.js +22 -0
  236. package/dist/ui/tools/ListClientsTool/index.js +39 -0
  237. package/dist/ui/tools/LspTool/index.js +261 -0
  238. package/dist/ui/tools/MCPTool/index.js +33 -0
  239. package/dist/ui/tools/ManageNetworkTool/index.js +53 -0
  240. package/dist/ui/tools/MemoryReadTool/index.js +64 -0
  241. package/dist/ui/tools/MemoryWriteTool/index.js +20 -0
  242. package/dist/ui/tools/NotebookEditTool/index.js +33 -0
  243. package/dist/ui/tools/NotebookReadTool/index.js +25 -0
  244. package/dist/ui/tools/OutlookReadTool/index.js +66 -0
  245. package/dist/ui/tools/OutlookReplyTool/index.js +49 -0
  246. package/dist/ui/tools/OutlookSendTool/index.js +49 -0
  247. package/dist/ui/tools/PauseDelegationTool/index.js +35 -0
  248. package/dist/ui/tools/ProbeTool/index.js +121 -0
  249. package/dist/ui/tools/ProcessTool/index.js +66 -0
  250. package/dist/ui/tools/QuestListTool/index.js +46 -0
  251. package/dist/ui/tools/QuestReportTool/index.js +49 -0
  252. package/dist/ui/tools/QuestUpdateTool/index.js +87 -0
  253. package/dist/ui/tools/QuipCommentTool/index.js +69 -0
  254. package/dist/ui/tools/QuipReadTool/index.js +71 -0
  255. package/dist/ui/tools/RestArionTool/index.js +32 -0
  256. package/dist/ui/tools/RestartTool/index.js +35 -0
  257. package/dist/ui/tools/ResumeDelegationTool/index.js +35 -0
  258. package/dist/ui/tools/RetireArionTool/index.js +32 -0
  259. package/dist/ui/tools/RgTool/index.js +73 -0
  260. package/dist/ui/tools/SearchKnowledgeTool/index.js +43 -0
  261. package/dist/ui/tools/SearchMessagesTool/index.js +43 -0
  262. package/dist/ui/tools/SelfDiagnoseTool/index.js +61 -0
  263. package/dist/ui/tools/SendMessageTool/index.js +45 -0
  264. package/dist/ui/tools/SerenaTool/index.js +124 -0
  265. package/dist/ui/tools/SessionHistoryTool/index.js +52 -0
  266. package/dist/ui/tools/SgTool/index.js +80 -0
  267. package/dist/ui/tools/SlackReactTool/index.js +41 -0
  268. package/dist/ui/tools/SlackReadTool/index.js +48 -0
  269. package/dist/ui/tools/SlackSendTool/index.js +45 -0
  270. package/dist/ui/tools/SpawnWorkerTool/index.js +33 -0
  271. package/dist/ui/tools/StickerRequestTool/index.js +19 -0
  272. package/dist/ui/tools/ThinkTool/index.js +17 -0
  273. package/dist/ui/tools/UgTool/index.js +108 -0
  274. package/dist/ui/tools/UseSkillTool/index.js +22 -0
  275. package/dist/ui/tools/WakeArionTool/index.js +32 -0
  276. package/dist/ui/tools/WebFetchTool/index.js +56 -0
  277. package/dist/ui/tools/WebSearchTool/index.js +44 -0
  278. package/dist/ui/tools/lsTool/index.js +58 -0
  279. package/dist/ui/tools/registry.js +197 -0
  280. package/dist/ui/tools/tool-renderer.js +11 -0
  281. package/dist/ui/tools/truncation.js +35 -0
  282. package/dist/ui/types/anthropic.js +4 -0
  283. package/dist/ui/types/index.js +2 -0
  284. package/dist/ui/types/message.js +3 -0
  285. package/dist/ui/types/tool.js +4 -0
  286. package/dist/ui/utils/array.js +4 -0
  287. package/dist/ui/utils/cursor.js +131 -0
  288. package/dist/ui/utils/diff.js +120 -0
  289. package/dist/ui/utils/format.js +42 -0
  290. package/dist/ui/utils/fuzzy.js +59 -0
  291. package/dist/ui/utils/index.js +11 -0
  292. package/dist/ui/utils/keys.js +8 -0
  293. package/dist/ui/utils/patch.js +17 -0
  294. package/dist/ui/utils/risk.js +114 -0
  295. package/dist/ui/utils/terminal-image.js +70 -0
  296. package/dist/ui/utils/validation.js +48 -0
  297. package/dist/ui/verb-pairs.js +248 -0
  298. package/dist/ui.js +131 -0
  299. package/package.json +73 -14
  300. package/src/entrypoints/command-mode.ts +5 -0
  301. package/src/entrypoints/daemon.ts +54 -0
  302. package/src/entrypoints/headless-stdio.ts +27 -0
  303. package/src/entrypoints/interactive.ts +112 -0
  304. package/src/main.ts +44 -0
  305. package/src/runtime/configure-bun-sqlite.ts +3 -0
  306. package/src/runtime/crash-handlers.ts +128 -0
  307. package/src/runtime/interactive-invocation.test.ts +42 -0
  308. package/src/runtime/interactive-invocation.ts +51 -0
  309. package/src/runtime/internal-mode.test.ts +19 -0
  310. package/src/runtime/internal-mode.ts +24 -0
  311. package/src/runtime/launch-spec.test.ts +26 -0
  312. package/src/runtime/launch-spec.ts +84 -0
  313. package/src/runtime/owner-lease.ts +52 -0
  314. package/src/runtime/public-mode.test.ts +18 -0
  315. package/src/runtime/public-mode.ts +19 -0
  316. package/src/runtime/run-internal-mode.ts +19 -0
  317. package/src/runtime/runtime-kind.test.ts +23 -0
  318. package/src/runtime/runtime-kind.ts +41 -0
  319. package/src/runtime/spawn-aria.ts +62 -0
@@ -0,0 +1,139 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useState, useMemo } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import { isEscapeInput } from "../../utils/keys.js";
5
+ import { getTheme, getAvailableThemes, getThemeDefinition, setTheme } from "../../theme/index.js";
6
+ const CATEGORY_LABELS = {
7
+ standard: "Standard",
8
+ claude: "Claude",
9
+ accessible: "Accessible",
10
+ };
11
+ const CATEGORY_ORDER = ["standard", "claude", "accessible"];
12
+ /** Classify a theme into a UI category. Exported for testing. */
13
+ export function categorize(name) {
14
+ // Daltonized/accessible variants are accessibility themes regardless of prefix
15
+ if (name.includes("daltonized") || name.includes("accessible"))
16
+ return "accessible";
17
+ if (name.startsWith("claude-"))
18
+ return "claude";
19
+ return "standard";
20
+ }
21
+ /** Derive light/dark from the theme's actual text color brightness, not the name. */
22
+ function isLightTheme(def) {
23
+ const hex = def.colors.text.replace("#", "");
24
+ const r = parseInt(hex.slice(0, 2), 16);
25
+ const g = parseInt(hex.slice(2, 4), 16);
26
+ const b = parseInt(hex.slice(4, 6), 16);
27
+ return (r * 299 + g * 587 + b * 114) / 1000 < 128;
28
+ }
29
+ function buildThemeOptions(currentName) {
30
+ return getAvailableThemes().map((name) => {
31
+ const def = getThemeDefinition(name);
32
+ return {
33
+ name,
34
+ displayName: def.displayName,
35
+ isCurrent: name === currentName,
36
+ isLight: isLightTheme(def),
37
+ category: categorize(name),
38
+ };
39
+ });
40
+ }
41
+ /**
42
+ * Code sample rendered with actual theme colors (not cli-highlight, which
43
+ * uses its own hardcoded palette and looks identical across themes).
44
+ * Each token is colored with the theme's semantic colors so users can
45
+ * see real differences between themes.
46
+ */
47
+ function CodePreview({ theme }) {
48
+ const c = theme.colors;
49
+ // Map semantic roles to theme colors:
50
+ // primary = keywords, info = strings, success = types, textMuted = comments, text = identifiers
51
+ const kw = c.primary; // keywords: async, function, const, if, throw, return
52
+ const str = c.info; // strings and template literals
53
+ const typ = c.success; // types: string, Promise, User
54
+ const cmt = c.textMuted; // comments
55
+ const id = c.text; // identifiers, operators, punctuation
56
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: cmt, children: "// fetch a user by ID" }), _jsxs(Box, { children: [_jsx(Text, { color: kw, children: "async function " }), _jsx(Text, { color: id, children: "fetchUser" }), _jsx(Text, { color: id, children: "(" }), _jsx(Text, { color: id, children: "id" }), _jsx(Text, { color: id, children: ": " }), _jsx(Text, { color: typ, children: "string" }), _jsx(Text, { color: id, children: ") {" })] }), _jsxs(Box, { children: [_jsx(Text, { color: id, children: " " }), _jsx(Text, { color: kw, children: "const " }), _jsx(Text, { color: id, children: "res = " }), _jsx(Text, { color: kw, children: "await " }), _jsx(Text, { color: id, children: "fetch(" }), _jsx(Text, { color: str, children: "`/api/users/${" }), _jsx(Text, { color: id, children: "id" }), _jsx(Text, { color: str, children: "}`" }), _jsx(Text, { color: id, children: ")" })] }), _jsxs(Box, { children: [_jsx(Text, { color: id, children: " " }), _jsx(Text, { color: kw, children: "if " }), _jsx(Text, { color: id, children: "(!res.ok) " }), _jsx(Text, { color: kw, children: "throw new " }), _jsx(Text, { color: typ, children: "Error" }), _jsx(Text, { color: id, children: "(" }), _jsx(Text, { color: str, children: "`HTTP ${" }), _jsx(Text, { color: id, children: "res.status" }), _jsx(Text, { color: str, children: "}`" }), _jsx(Text, { color: id, children: ")" })] }), _jsxs(Box, { children: [_jsx(Text, { color: id, children: " " }), _jsx(Text, { color: kw, children: "return " }), _jsx(Text, { color: id, children: "res.json() " }), _jsx(Text, { color: kw, children: "as " }), _jsx(Text, { color: typ, children: "Promise" }), _jsx(Text, { color: id, children: "<" }), _jsx(Text, { color: typ, children: "User" }), _jsx(Text, { color: id, children: ">" })] }), _jsx(Text, { color: id, children: "}" })] }));
57
+ }
58
+ /** Live preview showing theme-colored code + UI elements. */
59
+ function ThemePreview({ theme }) {
60
+ const c = theme.colors;
61
+ const s = theme.symbols;
62
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: c.secondary, paddingX: 1, children: [_jsxs(Text, { bold: true, color: c.primary, children: [s.prompt, " ", theme.displayName] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(CodePreview, { theme: theme }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: c.success, children: [s.success, " Tests passed (3/3)"] }), _jsxs(Text, { color: c.error, children: [s.error, " Error: connection refused"] }), _jsxs(Text, { color: c.warning, children: [s.warning, " Deprecated API call"] }), _jsx(Box, { children: _jsx(Text, { color: c.diffAdded, children: "+ const data = await fetch(url);" }) }), _jsx(Box, { children: _jsx(Text, { color: c.diffRemoved, children: "- const data = http.get(url);" }) }), _jsxs(Text, { color: c.textMuted, children: [s.info, " 1.2k tokens ", s.bullet, " $0.01 ", s.bullet, " 0.8s"] })] })] }));
63
+ }
64
+ export function ThemeSelector({ onSelect, onCancel }) {
65
+ const originalThemeName = useMemo(() => getTheme().name, []);
66
+ const allOptions = useMemo(() => buildThemeOptions(originalThemeName), [originalThemeName]);
67
+ const { items, selectableIndices } = useMemo(() => {
68
+ const items = [];
69
+ const selectableIndices = [];
70
+ const groups = new Map();
71
+ for (const opt of allOptions) {
72
+ const group = groups.get(opt.category) ?? [];
73
+ group.push(opt);
74
+ groups.set(opt.category, group);
75
+ }
76
+ for (const cat of CATEGORY_ORDER) {
77
+ const groupOptions = groups.get(cat);
78
+ if (!groupOptions?.length)
79
+ continue;
80
+ items.push({ type: "header", label: CATEGORY_LABELS[cat] ?? cat });
81
+ for (const opt of groupOptions) {
82
+ selectableIndices.push(items.length);
83
+ items.push({ type: "theme", option: opt });
84
+ }
85
+ }
86
+ return { items, selectableIndices };
87
+ }, [allOptions]);
88
+ const currentIdx = selectableIndices.findIndex((itemIdx) => {
89
+ const item = items[itemIdx];
90
+ return item?.type === "theme" && item.option.isCurrent;
91
+ });
92
+ const [selectedIndex, setSelectedIndex] = useState(currentIdx >= 0 ? currentIdx : 0);
93
+ const safeIndex = selectableIndices.length > 0 ? Math.min(selectedIndex, selectableIndices.length - 1) : 0;
94
+ // Live preview: apply theme SYNCHRONOUSLY during render so getTheme()
95
+ // returns the previewed theme in this same render pass.
96
+ const previewedItem = items[selectableIndices[safeIndex]];
97
+ const previewedThemeName = previewedItem?.type === "theme" ? previewedItem.option.name : null;
98
+ if (previewedThemeName) {
99
+ setTheme(previewedThemeName);
100
+ }
101
+ const handleCancel = React.useCallback(() => {
102
+ setTheme(originalThemeName);
103
+ onCancel();
104
+ }, [originalThemeName, onCancel]);
105
+ const isRawModeSupported = process.stdin.isTTY ?? false;
106
+ useInput((input, key) => {
107
+ if (isEscapeInput(input, key)) {
108
+ handleCancel();
109
+ return;
110
+ }
111
+ if (key.return && selectableIndices.length > 0) {
112
+ const itemIdx = selectableIndices[safeIndex];
113
+ const item = items[itemIdx];
114
+ if (item.type === "theme") {
115
+ onSelect({ name: item.option.name, displayName: item.option.displayName });
116
+ }
117
+ return;
118
+ }
119
+ if (key.upArrow) {
120
+ setSelectedIndex((i) => Math.max(0, i - 1));
121
+ return;
122
+ }
123
+ if (key.downArrow) {
124
+ setSelectedIndex((i) => Math.min(selectableIndices.length - 1, i + 1));
125
+ return;
126
+ }
127
+ }, { isActive: isRawModeSupported });
128
+ // Read the live-previewed theme — all colors below reflect the highlighted theme
129
+ const theme = getTheme();
130
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.colors.primary, paddingX: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.primary, children: "Theme" }), _jsxs(Text, { color: theme.colors.textMuted, children: [" ", theme.symbols.arrow, " select a color theme"] })] }), _jsxs(Box, { children: [_jsx(Box, { flexDirection: "column", width: 38, children: items.map((item, i) => {
131
+ if (item.type === "header") {
132
+ return (_jsx(Box, { marginTop: i > 0 ? 1 : 0, children: _jsx(Text, { bold: true, color: theme.colors.textMuted, children: item.label }) }, `header-${item.label}`));
133
+ }
134
+ const isHighlighted = selectableIndices[safeIndex] === i;
135
+ const { option } = item;
136
+ return (_jsx(Box, { children: _jsxs(Text, { inverse: isHighlighted, color: isHighlighted ? theme.colors.primary : theme.colors.text, children: [option.isCurrent ? "\u25cf" : "\u25cb", " ", option.displayName] }) }, option.name));
137
+ }) }), _jsx(Box, { flexDirection: "column", flexGrow: 1, marginLeft: 2, children: _jsx(ThemePreview, { theme: theme }) })] }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.colors.textMuted, children: ["\u2191\u2193", " navigate ", "\u23ce", " select esc cancel"] }) })] }));
138
+ }
139
+ //# sourceMappingURL=ThemeSelector.js.map
@@ -0,0 +1,15 @@
1
+ export { CommandPalette } from "./CommandPalette.js";
2
+ export { ArionSelector, } from "./ArionSelector.js";
3
+ export { ModelSelector } from "./ModelSelector.js";
4
+ export { MemoryBrowser, } from "./MemoryBrowser.js";
5
+ export { SessionSelector } from "./SessionSelector.js";
6
+ export { MessageSelector } from "./MessageSelector.js";
7
+ export { ThemeSelector, categorize as categorizeTheme, } from "./ThemeSelector.js";
8
+ export { PeerSelector } from "./PeerSelector.js";
9
+ export { ClientSelector } from "./ClientSelector.js";
10
+ export { InviteShareOverlay } from "./InviteShareOverlay.js";
11
+ export { JoinInviteOverlay } from "./JoinInviteOverlay.js";
12
+ export { PairRequestOverlay, } from "./PairRequestOverlay.js";
13
+ export { SoundSelector } from "./SoundSelector.js";
14
+ export { DaemonControl, } from "./DaemonControl.js";
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Changes:
3
+ // - BashTool.inputSchema.parse → direct cast (tool.inputSchema.parse)
4
+ // - BashTool.renderToolUseMessage → tool.renderToolUseMessage
5
+ // - savePermission → onAllow("permanent") directly
6
+ // - logUnaryPermissionEvent → no-op (analytics removed)
7
+ // - Select from CustomSelect
8
+ // - getTheme → ARIA's theme
9
+ import { Box, Text } from "ink";
10
+ import { useMemo } from "react";
11
+ import { usePermissionRequestLogging } from "../hooks.js";
12
+ import { getTheme } from "../../../theme/index.js";
13
+ import { toolUseConfirmGetPrefix } from "../PermissionRequest.js";
14
+ import { PermissionRequestTitle } from "../PermissionRequestTitle.js";
15
+ import { Select } from "../../CustomSelect/select.js";
16
+ import { toolUseOptions } from "../toolUseOptions.js";
17
+ export function BashPermissionRequest({ toolUseConfirm, onDone }) {
18
+ const theme = getTheme();
19
+ // Parse the command from input using the tool's own schema
20
+ const { command } = toolUseConfirm.tool.inputSchema.parse(toolUseConfirm.input);
21
+ const unaryEvent = useMemo(() => ({ completion_type: "tool_use_single", language_name: "none" }), []);
22
+ usePermissionRequestLogging(toolUseConfirm, unaryEvent);
23
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.colors.primary, marginTop: 1, paddingLeft: 1, paddingRight: 1, paddingBottom: 1, children: [_jsx(PermissionRequestTitle, { title: "Bash command", riskScore: toolUseConfirm.riskScore }), _jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsx(Text, { children: toolUseConfirm.tool.renderToolUseMessage({ command }, { verbose: false }) }), _jsx(Text, { color: theme.colors.textMuted, children: toolUseConfirm.description })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Do you want to proceed?" }), _jsx(Select, { options: toolUseOptions({ toolUseConfirm, command }), onChange: (newValue) => {
24
+ switch (newValue) {
25
+ case "yes":
26
+ toolUseConfirm.onAllow("temporary");
27
+ onDone();
28
+ break;
29
+ case "yes-dont-ask-again-prefix": {
30
+ const prefix = toolUseConfirmGetPrefix(toolUseConfirm);
31
+ if (prefix !== null) {
32
+ toolUseConfirm.onAllow("permanent");
33
+ }
34
+ else {
35
+ // Prefix unexpectedly null — fall back to temporary allow
36
+ // so the modal doesn't get stuck.
37
+ toolUseConfirm.onAllow("temporary");
38
+ }
39
+ onDone();
40
+ break;
41
+ }
42
+ case "yes-dont-ask-again-full":
43
+ toolUseConfirm.onAllow("permanent");
44
+ onDone();
45
+ break;
46
+ case "no":
47
+ toolUseConfirm.onReject();
48
+ onDone();
49
+ break;
50
+ }
51
+ } })] })] }));
52
+ }
53
+ //# sourceMappingURL=BashPermissionRequest.js.map
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Changes:
3
+ // - Removed logUnaryEvent, env, savePermission, usePermissionRequestLogging calls (analytics/persistence)
4
+ // - getTheme → ARIA's theme
5
+ // - Select from @inkjs/ui → CustomSelect
6
+ // - getCwd → process.cwd()
7
+ import { Box, Text } from "ink";
8
+ import { useMemo } from "react";
9
+ import { getTheme } from "../../theme/index.js";
10
+ import { PermissionRequestTitle, textColorForRiskScore } from "./PermissionRequestTitle.js";
11
+ import { usePermissionRequestLogging } from "./hooks.js";
12
+ import chalk from "chalk";
13
+ import { Select } from "../CustomSelect/select.js";
14
+ export function FallbackPermissionRequest({ toolUseConfirm, onDone, verbose, }) {
15
+ const theme = getTheme();
16
+ // TODO: Avoid these special cases
17
+ const originalUserFacingName = toolUseConfirm.tool.userFacingName(toolUseConfirm.input);
18
+ const userFacingName = originalUserFacingName.endsWith(" (MCP)")
19
+ ? originalUserFacingName.slice(0, -6)
20
+ : originalUserFacingName;
21
+ const unaryEvent = useMemo(() => ({
22
+ completion_type: "tool_use_single",
23
+ language_name: "none",
24
+ }), []);
25
+ usePermissionRequestLogging(toolUseConfirm, unaryEvent);
26
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: textColorForRiskScore(toolUseConfirm.riskScore), marginTop: 1, paddingLeft: 1, paddingRight: 1, paddingBottom: 1, children: [_jsx(PermissionRequestTitle, { title: "Tool use", riskScore: toolUseConfirm.riskScore }), _jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Text, { children: [userFacingName, "(", toolUseConfirm.tool.renderToolUseMessage(toolUseConfirm.input, { verbose }), ")", originalUserFacingName.endsWith(" (MCP)") ? (_jsx(Text, { color: theme.colors.textMuted, children: " (MCP)" })) : ("")] }), _jsx(Text, { color: theme.colors.textMuted, children: toolUseConfirm.description })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Do you want to proceed?" }), _jsx(Select, { options: [
27
+ {
28
+ label: "Yes",
29
+ value: "yes",
30
+ },
31
+ {
32
+ label: `Yes, and don't ask again for ${chalk.bold(userFacingName)} commands in ${chalk.bold(process.cwd())}`,
33
+ value: "yes-dont-ask-again",
34
+ },
35
+ {
36
+ label: `No, and provide instructions (${chalk.bold.hex(getTheme().colors.warning)("esc")})`,
37
+ value: "no",
38
+ },
39
+ ], onChange: (newValue) => {
40
+ switch (newValue) {
41
+ case "yes":
42
+ toolUseConfirm.onAllow("temporary");
43
+ onDone();
44
+ break;
45
+ case "yes-dont-ask-again":
46
+ toolUseConfirm.onAllow("permanent");
47
+ onDone();
48
+ break;
49
+ case "no":
50
+ toolUseConfirm.onReject();
51
+ onDone();
52
+ break;
53
+ }
54
+ } })] })] }));
55
+ }
56
+ //# sourceMappingURL=FallbackPermissionRequest.js.map
@@ -0,0 +1,76 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Changes:
3
+ // - Select from @inkjs/ui → CustomSelect
4
+ // - usePermissionRequestLogging → no-op stub
5
+ // - savePermission → onAllow("permanent") directly
6
+ // - logUnaryEvent, env → removed (analytics)
7
+ // - pathInOriginalCwd → inline check
8
+ // - useTerminalSize → from ARIA hooks
9
+ // - getTheme → ARIA's theme
10
+ import { Box, Text } from "ink";
11
+ import { useMemo } from "react";
12
+ import { basename, extname, isAbsolute, resolve } from "path";
13
+ import { getTheme } from "../../../theme/index.js";
14
+ import { PermissionRequestTitle, textColorForRiskScore } from "../PermissionRequestTitle.js";
15
+ import { usePermissionRequestLogging } from "../hooks.js";
16
+ import { FileEditToolDiff } from "./FileEditToolDiff.js";
17
+ import { useTerminalSize } from "../../../hooks/useTerminalSize.js";
18
+ import chalk from "chalk";
19
+ import { Select } from "../../CustomSelect/select.js";
20
+ function pathInOriginalCwd(path) {
21
+ const absolutePath = isAbsolute(path) ? resolve(path) : resolve(process.cwd(), path);
22
+ return absolutePath.startsWith(resolve(process.cwd()));
23
+ }
24
+ function getOptions(path) {
25
+ // Only show don't ask again option for edits in original working directory
26
+ const showDontAskAgainOptions = pathInOriginalCwd(path)
27
+ ? [
28
+ {
29
+ label: "Yes, and don't ask again this session",
30
+ value: "yes-dont-ask-again",
31
+ },
32
+ ]
33
+ : [];
34
+ return [
35
+ {
36
+ label: "Yes",
37
+ value: "yes",
38
+ },
39
+ ...showDontAskAgainOptions,
40
+ {
41
+ label: `No, and provide instructions (${chalk.bold.hex(getTheme().colors.warning)("esc")})`,
42
+ value: "no",
43
+ },
44
+ ];
45
+ }
46
+ export function FileEditPermissionRequest({ toolUseConfirm, onDone, verbose, }) {
47
+ const { columns } = useTerminalSize();
48
+ const { file_path, new_string, old_string } = toolUseConfirm.input;
49
+ const unaryEvent = useMemo(() => ({
50
+ completion_type: "str_replace_single",
51
+ language_name: extractLanguageName(file_path),
52
+ }), [file_path]);
53
+ usePermissionRequestLogging(toolUseConfirm, unaryEvent);
54
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: textColorForRiskScore(toolUseConfirm.riskScore), marginTop: 1, paddingLeft: 1, paddingRight: 1, paddingBottom: 1, children: [_jsx(PermissionRequestTitle, { title: "Edit file", riskScore: toolUseConfirm.riskScore }), _jsx(FileEditToolDiff, { file_path: file_path, new_string: new_string, old_string: old_string, verbose: verbose, width: columns - 12 }), _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: ["Do you want to make this edit to ", _jsx(Text, { bold: true, children: basename(file_path) }), "?"] }), _jsx(Select, { options: getOptions(file_path), onChange: (newValue) => {
55
+ switch (newValue) {
56
+ case "yes":
57
+ toolUseConfirm.onAllow("temporary");
58
+ onDone();
59
+ break;
60
+ case "yes-dont-ask-again":
61
+ toolUseConfirm.onAllow("permanent");
62
+ onDone();
63
+ break;
64
+ case "no":
65
+ toolUseConfirm.onReject();
66
+ onDone();
67
+ break;
68
+ }
69
+ } })] })] }));
70
+ }
71
+ // Simplified: highlight.js lookup was only used for analytics logging (now a no-op)
72
+ function extractLanguageName(file_path) {
73
+ const ext = extname(file_path);
74
+ return ext ? ext.slice(1) : "unknown";
75
+ }
76
+ //# sourceMappingURL=FileEditPermissionRequest.js.map
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { existsSync, readFileSync } from "fs";
3
+ import { useMemo } from "react";
4
+ import { StructuredDiff } from "../../StructuredDiff.js";
5
+ import { Box, Text } from "ink";
6
+ import { getTheme } from "../../../theme/index.js";
7
+ import { relative } from "path";
8
+ import { generateDiff } from "../../../utils/diff.js";
9
+ export function FileEditToolDiff({ file_path, new_string, old_string, verbose, useBorder = true, width, }) {
10
+ const file = useMemo(() => (existsSync(file_path) ? readFileSync(file_path, "utf8") : ""), [file_path]);
11
+ // Generate a FileDiff for ARIA's StructuredDiff component
12
+ const fileDiff = useMemo(() => {
13
+ const newContents = file.replace(old_string, new_string);
14
+ return generateDiff(file_path, file, newContents);
15
+ }, [file_path, file, old_string, new_string]);
16
+ return (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { borderColor: getTheme().colors.secondary, borderStyle: useBorder ? "round" : undefined, flexDirection: "column", paddingX: 1, children: [_jsx(Box, { paddingBottom: 1, children: _jsx(Text, { bold: true, children: verbose ? file_path : relative(process.cwd(), file_path) }) }), _jsx(StructuredDiff, { diff: fileDiff, dim: false, width: width, showHeader: false })] }) }));
17
+ }
18
+ //# sourceMappingURL=FileEditToolDiff.js.map
@@ -0,0 +1,64 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Changes:
3
+ // - Select from @inkjs/ui → CustomSelect
4
+ // - usePermissionRequestLogging → no-op stub
5
+ // - savePermission → onAllow("permanent") directly
6
+ // - logUnaryEvent, env → removed (analytics)
7
+ // - useTerminalSize → from ARIA hooks
8
+ // - getTheme → ARIA's theme
9
+ import { Box, Text } from "ink";
10
+ import { useMemo } from "react";
11
+ import { basename, extname } from "path";
12
+ import { getTheme } from "../../../theme/index.js";
13
+ import { PermissionRequestTitle, textColorForRiskScore } from "../PermissionRequestTitle.js";
14
+ import { existsSync } from "fs";
15
+ import chalk from "chalk";
16
+ import { usePermissionRequestLogging } from "../hooks.js";
17
+ import { FileWriteToolDiff } from "./FileWriteToolDiff.js";
18
+ import { useTerminalSize } from "../../../hooks/useTerminalSize.js";
19
+ import { Select } from "../../CustomSelect/select.js";
20
+ export function FileWritePermissionRequest({ toolUseConfirm, onDone, verbose, }) {
21
+ const { file_path, content } = toolUseConfirm.input;
22
+ const fileExists = useMemo(() => existsSync(file_path), [file_path]);
23
+ const unaryEvent = useMemo(() => ({
24
+ completion_type: "write_file_single",
25
+ language_name: extractLanguageName(file_path),
26
+ }), [file_path]);
27
+ const { columns } = useTerminalSize();
28
+ usePermissionRequestLogging(toolUseConfirm, unaryEvent);
29
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: textColorForRiskScore(toolUseConfirm.riskScore), marginTop: 1, paddingLeft: 1, paddingRight: 1, paddingBottom: 1, children: [_jsx(PermissionRequestTitle, { title: `${fileExists ? "Edit" : "Create"} file`, riskScore: toolUseConfirm.riskScore }), _jsx(Box, { flexDirection: "column", children: _jsx(FileWriteToolDiff, { file_path: file_path, content: content, verbose: verbose, width: columns - 12 }) }), _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: ["Do you want to ", fileExists ? "make this edit to" : "create", " ", _jsx(Text, { bold: true, children: basename(file_path) }), "?"] }), _jsx(Select, { options: [
30
+ {
31
+ label: "Yes",
32
+ value: "yes",
33
+ },
34
+ {
35
+ label: "Yes, and don't ask again this session",
36
+ value: "yes-dont-ask-again",
37
+ },
38
+ {
39
+ label: `No, and provide instructions (${chalk.bold.hex(getTheme().colors.warning)("esc")})`,
40
+ value: "no",
41
+ },
42
+ ], onChange: (newValue) => {
43
+ switch (newValue) {
44
+ case "yes":
45
+ toolUseConfirm.onAllow("temporary");
46
+ onDone();
47
+ break;
48
+ case "yes-dont-ask-again":
49
+ toolUseConfirm.onAllow("permanent");
50
+ onDone();
51
+ break;
52
+ case "no":
53
+ toolUseConfirm.onReject();
54
+ onDone();
55
+ break;
56
+ }
57
+ } })] })] }));
58
+ }
59
+ // Simplified: highlight.js lookup was only used for analytics logging (now a no-op)
60
+ function extractLanguageName(file_path) {
61
+ const ext = extname(file_path);
62
+ return ext ? ext.slice(1) : "unknown";
63
+ }
64
+ //# sourceMappingURL=FileWritePermissionRequest.js.map
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { existsSync, readFileSync } from "fs";
3
+ import { useMemo } from "react";
4
+ import { StructuredDiff } from "../../StructuredDiff.js";
5
+ import { Box, Text } from "ink";
6
+ import { getTheme } from "../../../theme/index.js";
7
+ import { extname, relative } from "path";
8
+ import { HighlightedCode } from "../../HighlightedCode.js";
9
+ import { generateDiff } from "../../../utils/diff.js";
10
+ export function FileWriteToolDiff({ file_path, content, verbose, width }) {
11
+ const fileExists = useMemo(() => existsSync(file_path), [file_path]);
12
+ const oldContent = useMemo(() => {
13
+ if (!fileExists) {
14
+ return "";
15
+ }
16
+ return readFileSync(file_path, "utf8");
17
+ }, [file_path, fileExists]);
18
+ const fileDiff = useMemo(() => {
19
+ if (!fileExists) {
20
+ return null;
21
+ }
22
+ return generateDiff(file_path, oldContent, content);
23
+ }, [fileExists, file_path, oldContent, content]);
24
+ return (_jsxs(Box, { borderColor: getTheme().colors.secondary, borderStyle: "round", flexDirection: "column", paddingX: 1, children: [_jsx(Box, { paddingBottom: 1, children: _jsx(Text, { bold: true, children: verbose ? file_path : relative(process.cwd(), file_path) }) }), fileDiff ? (_jsx(StructuredDiff, { diff: fileDiff, dim: false, width: width, showHeader: false })) : (_jsx(HighlightedCode, { code: content || "(No content)", language: extname(file_path).slice(1) }))] }));
25
+ }
26
+ //# sourceMappingURL=FileWriteToolDiff.js.map
@@ -0,0 +1,141 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Changes:
3
+ // - Tool references → name-based dispatch via ToolUseConfirm.tool.name
4
+ // - pathInOriginalCwd, toAbsolutePath, grantWritePermissionForOriginalDir → inline stubs
5
+ // - getCwd → process.cwd()
6
+ // - logUnaryEvent, env → removed (analytics)
7
+ // - usePermissionRequestLogging → no-op stub from hooks.ts
8
+ // - Select from @inkjs/ui → CustomSelect
9
+ // - getTheme → ARIA's theme
10
+ import { Box, Text } from "ink";
11
+ import { useMemo } from "react";
12
+ import { getTheme } from "../../../theme/index.js";
13
+ import { PermissionRequestTitle, textColorForRiskScore } from "../PermissionRequestTitle.js";
14
+ import chalk from "chalk";
15
+ import { usePermissionRequestLogging } from "../hooks.js";
16
+ import { FallbackPermissionRequest } from "../FallbackPermissionRequest.js";
17
+ import { Select } from "../../CustomSelect/select.js";
18
+ import { isAbsolute, resolve } from "path";
19
+ // -- Inline stubs for filesystem permissions --
20
+ function toAbsolutePath(path) {
21
+ return isAbsolute(path) ? resolve(path) : resolve(process.cwd(), path);
22
+ }
23
+ function pathInOriginalCwd(path) {
24
+ const absolutePath = toAbsolutePath(path);
25
+ return absolutePath.startsWith(toAbsolutePath(process.cwd()));
26
+ }
27
+ // In-memory write permission grant (session-scoped)
28
+ let writePermissionGranted = false;
29
+ function grantWritePermissionForOriginalDir() {
30
+ writePermissionGranted = true;
31
+ }
32
+ // Export for testing
33
+ export { writePermissionGranted };
34
+ // -- Tool name sets for path arg detection --
35
+ const FILE_PATH_TOOLS = new Set([
36
+ "Edit",
37
+ "file_edit",
38
+ "str_replace_editor",
39
+ "Write",
40
+ "file_write",
41
+ "create_file",
42
+ "Read",
43
+ "file_read",
44
+ "read_file",
45
+ ]);
46
+ const PATH_TOOLS = new Set(["Glob", "glob", "Grep", "grep", "LS", "ls"]);
47
+ const NOTEBOOK_PATH_TOOLS = new Set([
48
+ "NotebookEdit",
49
+ "notebook_edit",
50
+ "NotebookRead",
51
+ "notebook_read",
52
+ ]);
53
+ const MULTI_FILE_TOOLS = new Set(["Glob", "glob", "Grep", "grep", "LS", "ls"]);
54
+ function pathArgNameForToolUse(toolUseConfirm) {
55
+ const name = toolUseConfirm.tool.name;
56
+ if (FILE_PATH_TOOLS.has(name))
57
+ return "file_path";
58
+ if (PATH_TOOLS.has(name))
59
+ return "path";
60
+ if (NOTEBOOK_PATH_TOOLS.has(name))
61
+ return "notebook_path";
62
+ return null;
63
+ }
64
+ function isMultiFile(toolUseConfirm) {
65
+ return MULTI_FILE_TOOLS.has(toolUseConfirm.tool.name);
66
+ }
67
+ function pathFromToolUse(toolUseConfirm) {
68
+ const pathArgName = pathArgNameForToolUse(toolUseConfirm);
69
+ const input = toolUseConfirm.input;
70
+ if (pathArgName && pathArgName in input) {
71
+ if (typeof input[pathArgName] === "string") {
72
+ return toAbsolutePath(input[pathArgName]);
73
+ }
74
+ else {
75
+ return toAbsolutePath(process.cwd());
76
+ }
77
+ }
78
+ return null;
79
+ }
80
+ export function FilesystemPermissionRequest({ toolUseConfirm, onDone, verbose, }) {
81
+ const path = pathFromToolUse(toolUseConfirm);
82
+ if (!path) {
83
+ // Fall back to generic permission request if no path is found
84
+ return (_jsx(FallbackPermissionRequest, { toolUseConfirm: toolUseConfirm, onDone: onDone, verbose: verbose }));
85
+ }
86
+ return (_jsx(FilesystemPermissionRequestImpl, { toolUseConfirm: toolUseConfirm, path: path, onDone: onDone, verbose: verbose }));
87
+ }
88
+ function getDontAskAgainOptions(toolUseConfirm, path) {
89
+ if (toolUseConfirm.tool.isReadOnly()) {
90
+ // "Always allow" is not an option for read-only tools,
91
+ // because they always have write permission in the project directory.
92
+ return [];
93
+ }
94
+ // Only show don't ask again option for edits in original working directory
95
+ return pathInOriginalCwd(path)
96
+ ? [
97
+ {
98
+ label: "Yes, and don't ask again for file edits this session",
99
+ value: "yes-dont-ask-again",
100
+ },
101
+ ]
102
+ : [];
103
+ }
104
+ function FilesystemPermissionRequestImpl({ toolUseConfirm, path, onDone, verbose, }) {
105
+ const userFacingName = toolUseConfirm.tool.userFacingName(toolUseConfirm.input);
106
+ const userFacingReadOrWrite = toolUseConfirm.tool.isReadOnly() ? "Read" : "Edit";
107
+ const title = `${userFacingReadOrWrite} ${isMultiFile(toolUseConfirm) ? "files" : "file"}`;
108
+ const unaryEvent = useMemo(() => ({
109
+ completion_type: "tool_use_single",
110
+ language_name: "none",
111
+ }), []);
112
+ usePermissionRequestLogging(toolUseConfirm, unaryEvent);
113
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: textColorForRiskScore(toolUseConfirm.riskScore), marginTop: 1, paddingLeft: 1, paddingRight: 1, paddingBottom: 1, children: [_jsx(PermissionRequestTitle, { title: title, riskScore: toolUseConfirm.riskScore }), _jsx(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: _jsxs(Text, { children: [userFacingName, "(", toolUseConfirm.tool.renderToolUseMessage(toolUseConfirm.input, { verbose }), ")"] }) }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Do you want to proceed?" }), _jsx(Select, { options: [
114
+ {
115
+ label: "Yes",
116
+ value: "yes",
117
+ },
118
+ ...getDontAskAgainOptions(toolUseConfirm, path),
119
+ {
120
+ label: `No, and provide instructions (${chalk.bold.hex(getTheme().colors.warning)("esc")})`,
121
+ value: "no",
122
+ },
123
+ ], onChange: (newValue) => {
124
+ switch (newValue) {
125
+ case "yes":
126
+ toolUseConfirm.onAllow("temporary");
127
+ onDone();
128
+ break;
129
+ case "yes-dont-ask-again":
130
+ grantWritePermissionForOriginalDir();
131
+ toolUseConfirm.onAllow("permanent");
132
+ onDone();
133
+ break;
134
+ case "no":
135
+ toolUseConfirm.onReject();
136
+ onDone();
137
+ break;
138
+ }
139
+ } })] })] }));
140
+ }
141
+ //# sourceMappingURL=FilesystemPermissionRequest.js.map