arc402-cli 0.9.19 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/README.md +41 -2
  2. package/dist/abis.d.ts +1 -0
  3. package/dist/abis.d.ts.map +1 -1
  4. package/dist/abis.js +45 -14
  5. package/dist/abis.js.map +1 -1
  6. package/dist/bundler.d.ts +1 -1
  7. package/dist/bundler.d.ts.map +1 -1
  8. package/dist/bundler.js +61 -27
  9. package/dist/bundler.js.map +1 -1
  10. package/dist/client.d.ts +1 -1
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +9 -5
  13. package/dist/client.js.map +1 -1
  14. package/dist/coinbase-smart-wallet.js +4 -1
  15. package/dist/coinbase-smart-wallet.js.map +1 -1
  16. package/dist/commands/accept.js +28 -25
  17. package/dist/commands/accept.js.map +1 -1
  18. package/dist/commands/agent-handshake.js +18 -15
  19. package/dist/commands/agent-handshake.js.map +1 -1
  20. package/dist/commands/agent.js +104 -98
  21. package/dist/commands/agent.js.map +1 -1
  22. package/dist/commands/agreements.js +98 -62
  23. package/dist/commands/agreements.js.map +1 -1
  24. package/dist/commands/arbitrator.js +81 -45
  25. package/dist/commands/arbitrator.js.map +1 -1
  26. package/dist/commands/arena-handshake.d.ts.map +1 -1
  27. package/dist/commands/arena-handshake.js +35 -53
  28. package/dist/commands/arena-handshake.js.map +1 -1
  29. package/dist/commands/arena.js +18 -12
  30. package/dist/commands/arena.js.map +1 -1
  31. package/dist/commands/backup.js +36 -30
  32. package/dist/commands/backup.js.map +1 -1
  33. package/dist/commands/cancel.js +18 -15
  34. package/dist/commands/cancel.js.map +1 -1
  35. package/dist/commands/channel.js +81 -45
  36. package/dist/commands/channel.js.map +1 -1
  37. package/dist/commands/coldstart.js +34 -31
  38. package/dist/commands/coldstart.js.map +1 -1
  39. package/dist/commands/compute.d.ts +14 -0
  40. package/dist/commands/compute.d.ts.map +1 -0
  41. package/dist/commands/compute.js +466 -0
  42. package/dist/commands/compute.js.map +1 -0
  43. package/dist/commands/config.js +30 -24
  44. package/dist/commands/config.js.map +1 -1
  45. package/dist/commands/contract-interaction.js +15 -12
  46. package/dist/commands/contract-interaction.js.map +1 -1
  47. package/dist/commands/daemon.d.ts.map +1 -1
  48. package/dist/commands/daemon.js +135 -98
  49. package/dist/commands/daemon.js.map +1 -1
  50. package/dist/commands/deliver.js +76 -37
  51. package/dist/commands/deliver.js.map +1 -1
  52. package/dist/commands/discover.js +27 -24
  53. package/dist/commands/discover.js.map +1 -1
  54. package/dist/commands/dispute.js +110 -104
  55. package/dist/commands/dispute.js.map +1 -1
  56. package/dist/commands/doctor.js +55 -16
  57. package/dist/commands/doctor.js.map +1 -1
  58. package/dist/commands/endpoint.js +95 -56
  59. package/dist/commands/endpoint.js.map +1 -1
  60. package/dist/commands/feed.js +18 -11
  61. package/dist/commands/feed.js.map +1 -1
  62. package/dist/commands/hire.js +40 -37
  63. package/dist/commands/hire.js.map +1 -1
  64. package/dist/commands/migrate.js +33 -30
  65. package/dist/commands/migrate.js.map +1 -1
  66. package/dist/commands/negotiate.d.ts.map +1 -1
  67. package/dist/commands/negotiate.js +36 -34
  68. package/dist/commands/negotiate.js.map +1 -1
  69. package/dist/commands/openshell.js +104 -68
  70. package/dist/commands/openshell.js.map +1 -1
  71. package/dist/commands/owner.js +20 -17
  72. package/dist/commands/owner.js.map +1 -1
  73. package/dist/commands/policy.js +43 -41
  74. package/dist/commands/policy.js.map +1 -1
  75. package/dist/commands/relay.d.ts.map +1 -1
  76. package/dist/commands/relay.js +51 -18
  77. package/dist/commands/relay.js.map +1 -1
  78. package/dist/commands/remediate.js +23 -20
  79. package/dist/commands/remediate.js.map +1 -1
  80. package/dist/commands/reputation.js +27 -25
  81. package/dist/commands/reputation.js.map +1 -1
  82. package/dist/commands/setup.js +104 -65
  83. package/dist/commands/setup.js.map +1 -1
  84. package/dist/commands/trust.js +20 -17
  85. package/dist/commands/trust.js.map +1 -1
  86. package/dist/commands/verify.js +21 -18
  87. package/dist/commands/verify.js.map +1 -1
  88. package/dist/commands/wallet.d.ts.map +1 -1
  89. package/dist/commands/wallet.js +645 -679
  90. package/dist/commands/wallet.js.map +1 -1
  91. package/dist/commands/watch.js +36 -33
  92. package/dist/commands/watch.js.map +1 -1
  93. package/dist/commands/watchtower.js +73 -37
  94. package/dist/commands/watchtower.js.map +1 -1
  95. package/dist/commands/workroom.d.ts.map +1 -1
  96. package/dist/commands/workroom.js +282 -143
  97. package/dist/commands/workroom.js.map +1 -1
  98. package/dist/config.d.ts +3 -0
  99. package/dist/config.d.ts.map +1 -1
  100. package/dist/config.js +71 -22
  101. package/dist/config.js.map +1 -1
  102. package/dist/daemon/compute-metering.d.ts +61 -0
  103. package/dist/daemon/compute-metering.d.ts.map +1 -0
  104. package/dist/daemon/compute-metering.js +299 -0
  105. package/dist/daemon/compute-metering.js.map +1 -0
  106. package/dist/daemon/compute-session.d.ts +100 -0
  107. package/dist/daemon/compute-session.d.ts.map +1 -0
  108. package/dist/daemon/compute-session.js +231 -0
  109. package/dist/daemon/compute-session.js.map +1 -0
  110. package/dist/daemon/config.d.ts +19 -1
  111. package/dist/daemon/config.d.ts.map +1 -1
  112. package/dist/daemon/config.js +90 -16
  113. package/dist/daemon/config.js.map +1 -1
  114. package/dist/daemon/credentials.d.ts +24 -0
  115. package/dist/daemon/credentials.d.ts.map +1 -0
  116. package/dist/daemon/credentials.js +80 -0
  117. package/dist/daemon/credentials.js.map +1 -0
  118. package/dist/daemon/delivery-client.d.ts +35 -0
  119. package/dist/daemon/delivery-client.d.ts.map +1 -0
  120. package/dist/daemon/delivery-client.js +231 -0
  121. package/dist/daemon/delivery-client.js.map +1 -0
  122. package/dist/daemon/file-delivery.d.ts +98 -0
  123. package/dist/daemon/file-delivery.d.ts.map +1 -0
  124. package/dist/daemon/file-delivery.js +461 -0
  125. package/dist/daemon/file-delivery.js.map +1 -0
  126. package/dist/daemon/hire-listener.d.ts +3 -3
  127. package/dist/daemon/hire-listener.d.ts.map +1 -1
  128. package/dist/daemon/hire-listener.js +47 -13
  129. package/dist/daemon/hire-listener.js.map +1 -1
  130. package/dist/daemon/index.d.ts +2 -1
  131. package/dist/daemon/index.d.ts.map +1 -1
  132. package/dist/daemon/index.js +526 -53
  133. package/dist/daemon/index.js.map +1 -1
  134. package/dist/daemon/job-lifecycle.d.ts +1 -1
  135. package/dist/daemon/job-lifecycle.d.ts.map +1 -1
  136. package/dist/daemon/job-lifecycle.js +51 -11
  137. package/dist/daemon/job-lifecycle.js.map +1 -1
  138. package/dist/daemon/notify.d.ts +1 -1
  139. package/dist/daemon/notify.d.ts.map +1 -1
  140. package/dist/daemon/notify.js +53 -19
  141. package/dist/daemon/notify.js.map +1 -1
  142. package/dist/daemon/token-metering.js +47 -8
  143. package/dist/daemon/token-metering.js.map +1 -1
  144. package/dist/daemon/userops.d.ts +2 -2
  145. package/dist/daemon/userops.d.ts.map +1 -1
  146. package/dist/daemon/userops.js +27 -23
  147. package/dist/daemon/userops.js.map +1 -1
  148. package/dist/daemon/wallet-monitor.d.ts +1 -1
  149. package/dist/daemon/wallet-monitor.d.ts.map +1 -1
  150. package/dist/daemon/wallet-monitor.js +12 -8
  151. package/dist/daemon/wallet-monitor.js.map +1 -1
  152. package/dist/daemon/worker-executor.d.ts +71 -0
  153. package/dist/daemon/worker-executor.d.ts.map +1 -0
  154. package/dist/daemon/worker-executor.js +382 -0
  155. package/dist/daemon/worker-executor.js.map +1 -0
  156. package/dist/drain-v4.js +64 -26
  157. package/dist/drain-v4.js.map +1 -1
  158. package/dist/endpoint-config.js +63 -20
  159. package/dist/endpoint-config.js.map +1 -1
  160. package/dist/endpoint-notify.d.ts.map +1 -1
  161. package/dist/endpoint-notify.js +49 -15
  162. package/dist/endpoint-notify.js.map +1 -1
  163. package/dist/index.js +50 -18
  164. package/dist/index.js.map +1 -1
  165. package/dist/openshell-runtime.d.ts.map +1 -1
  166. package/dist/openshell-runtime.js +82 -38
  167. package/dist/openshell-runtime.js.map +1 -1
  168. package/dist/program.d.ts.map +1 -1
  169. package/dist/program.js +85 -78
  170. package/dist/program.js.map +1 -1
  171. package/dist/repl.js +31 -25
  172. package/dist/repl.js.map +1 -1
  173. package/dist/signing.js +6 -3
  174. package/dist/signing.js.map +1 -1
  175. package/dist/telegram-notify.js +40 -3
  176. package/dist/telegram-notify.js.map +1 -1
  177. package/dist/tui/App.d.ts.map +1 -1
  178. package/dist/tui/App.js +56 -89
  179. package/dist/tui/App.js.map +1 -1
  180. package/dist/tui/Footer.js +7 -4
  181. package/dist/tui/Footer.js.map +1 -1
  182. package/dist/tui/Header.d.ts +1 -1
  183. package/dist/tui/Header.d.ts.map +1 -1
  184. package/dist/tui/Header.js +14 -9
  185. package/dist/tui/Header.js.map +1 -1
  186. package/dist/tui/InputLine.d.ts +2 -1
  187. package/dist/tui/InputLine.d.ts.map +1 -1
  188. package/dist/tui/InputLine.js +47 -97
  189. package/dist/tui/InputLine.js.map +1 -1
  190. package/dist/tui/Viewport.d.ts +1 -2
  191. package/dist/tui/Viewport.d.ts.map +1 -1
  192. package/dist/tui/Viewport.js +26 -6
  193. package/dist/tui/Viewport.js.map +1 -1
  194. package/dist/tui/WalletConnectPairing.js +19 -16
  195. package/dist/tui/WalletConnectPairing.js.map +1 -1
  196. package/dist/tui/components/Button.js +9 -6
  197. package/dist/tui/components/Button.js.map +1 -1
  198. package/dist/tui/components/CeremonyView.js +8 -5
  199. package/dist/tui/components/CeremonyView.js.map +1 -1
  200. package/dist/tui/components/CompletionDropdown.js +9 -6
  201. package/dist/tui/components/CompletionDropdown.js.map +1 -1
  202. package/dist/tui/components/ConfirmPrompt.js +8 -5
  203. package/dist/tui/components/ConfirmPrompt.js.map +1 -1
  204. package/dist/tui/components/CustomTextInput.js +14 -11
  205. package/dist/tui/components/CustomTextInput.js.map +1 -1
  206. package/dist/tui/components/InteractiveTable.js +12 -9
  207. package/dist/tui/components/InteractiveTable.js.map +1 -1
  208. package/dist/tui/components/StepSpinner.js +13 -10
  209. package/dist/tui/components/StepSpinner.js.map +1 -1
  210. package/dist/tui/components/Toast.js +12 -8
  211. package/dist/tui/components/Toast.js.map +1 -1
  212. package/dist/tui/index.d.ts.map +1 -1
  213. package/dist/tui/index.js +21 -28
  214. package/dist/tui/index.js.map +1 -1
  215. package/dist/tui/useChat.js +19 -13
  216. package/dist/tui/useChat.js.map +1 -1
  217. package/dist/tui/useCommand.d.ts +2 -3
  218. package/dist/tui/useCommand.d.ts.map +1 -1
  219. package/dist/tui/useCommand.js +24 -100
  220. package/dist/tui/useCommand.js.map +1 -1
  221. package/dist/tui/useNotifications.js +8 -5
  222. package/dist/tui/useNotifications.js.map +1 -1
  223. package/dist/tui/useScroll.d.ts.map +1 -1
  224. package/dist/tui/useScroll.js +12 -15
  225. package/dist/tui/useScroll.js.map +1 -1
  226. package/dist/ui/banner.d.ts +0 -12
  227. package/dist/ui/banner.d.ts.map +1 -1
  228. package/dist/ui/banner.js +19 -35
  229. package/dist/ui/banner.js.map +1 -1
  230. package/dist/ui/colors.js +19 -13
  231. package/dist/ui/colors.js.map +1 -1
  232. package/dist/ui/format.js +14 -6
  233. package/dist/ui/format.js.map +1 -1
  234. package/dist/ui/qr-render.js +11 -4
  235. package/dist/ui/qr-render.js.map +1 -1
  236. package/dist/ui/rpc-fallback.js +11 -6
  237. package/dist/ui/rpc-fallback.js.map +1 -1
  238. package/dist/ui/spinner.js +12 -6
  239. package/dist/ui/spinner.js.map +1 -1
  240. package/dist/ui/tree.js +6 -3
  241. package/dist/ui/tree.js.map +1 -1
  242. package/dist/utils/format.js +41 -27
  243. package/dist/utils/format.js.map +1 -1
  244. package/dist/utils/hash.js +42 -4
  245. package/dist/utils/hash.js.map +1 -1
  246. package/dist/utils/time.js +6 -2
  247. package/dist/utils/time.js.map +1 -1
  248. package/dist/wallet-router.d.ts +1 -1
  249. package/dist/wallet-router.d.ts.map +1 -1
  250. package/dist/wallet-router.js +19 -12
  251. package/dist/wallet-router.js.map +1 -1
  252. package/dist/walletconnect-session.d.ts +1 -1
  253. package/dist/walletconnect-session.d.ts.map +1 -1
  254. package/dist/walletconnect-session.js +11 -6
  255. package/dist/walletconnect-session.js.map +1 -1
  256. package/dist/walletconnect.d.ts +5 -6
  257. package/dist/walletconnect.d.ts.map +1 -1
  258. package/dist/walletconnect.js +35 -32
  259. package/dist/walletconnect.js.map +1 -1
  260. package/package.json +11 -10
  261. package/INK6-UX-SPEC.md +0 -446
  262. package/MIGRATION-SPEC.md +0 -108
  263. package/TUI-SPEC.md +0 -214
  264. package/scripts/authorize-machine-key.ts +0 -43
  265. package/scripts/drain-wallet.ts +0 -149
  266. package/scripts/execute-spend-only.ts +0 -81
  267. package/scripts/register-agent-userop.ts +0 -186
  268. package/src/abis.ts +0 -187
  269. package/src/bundler.ts +0 -235
  270. package/src/client.ts +0 -36
  271. package/src/coinbase-smart-wallet.ts +0 -51
  272. package/src/commands/accept.ts +0 -64
  273. package/src/commands/agent-handshake.ts +0 -72
  274. package/src/commands/agent.ts +0 -691
  275. package/src/commands/agreements.ts +0 -350
  276. package/src/commands/arbitrator.ts +0 -180
  277. package/src/commands/arena-handshake.ts +0 -274
  278. package/src/commands/arena.ts +0 -122
  279. package/src/commands/backup.ts +0 -117
  280. package/src/commands/cancel.ts +0 -35
  281. package/src/commands/channel.ts +0 -218
  282. package/src/commands/coldstart.ts +0 -165
  283. package/src/commands/config.ts +0 -68
  284. package/src/commands/contract-interaction.ts +0 -166
  285. package/src/commands/daemon.ts +0 -1054
  286. package/src/commands/deliver.ts +0 -148
  287. package/src/commands/discover.ts +0 -350
  288. package/src/commands/dispute.ts +0 -375
  289. package/src/commands/doctor.ts +0 -172
  290. package/src/commands/endpoint.ts +0 -620
  291. package/src/commands/feed.ts +0 -229
  292. package/src/commands/hire.ts +0 -245
  293. package/src/commands/migrate.ts +0 -177
  294. package/src/commands/negotiate.ts +0 -272
  295. package/src/commands/openshell.ts +0 -1055
  296. package/src/commands/owner.ts +0 -35
  297. package/src/commands/policy.ts +0 -263
  298. package/src/commands/relay.ts +0 -277
  299. package/src/commands/remediate.ts +0 -24
  300. package/src/commands/reputation.ts +0 -79
  301. package/src/commands/setup.ts +0 -343
  302. package/src/commands/trust.ts +0 -27
  303. package/src/commands/verify.ts +0 -91
  304. package/src/commands/wallet.ts +0 -3548
  305. package/src/commands/watch.ts +0 -220
  306. package/src/commands/watchtower.ts +0 -248
  307. package/src/commands/workroom.ts +0 -963
  308. package/src/config.ts +0 -220
  309. package/src/daemon/config.ts +0 -344
  310. package/src/daemon/hire-listener.ts +0 -226
  311. package/src/daemon/index.ts +0 -1089
  312. package/src/daemon/job-lifecycle.ts +0 -215
  313. package/src/daemon/notify.ts +0 -297
  314. package/src/daemon/token-metering.ts +0 -183
  315. package/src/daemon/userops.ts +0 -119
  316. package/src/daemon/wallet-monitor.ts +0 -90
  317. package/src/drain-v4.ts +0 -159
  318. package/src/endpoint-config.ts +0 -83
  319. package/src/endpoint-notify.ts +0 -134
  320. package/src/index.ts +0 -74
  321. package/src/openshell-runtime.ts +0 -281
  322. package/src/program.ts +0 -88
  323. package/src/repl.ts +0 -178
  324. package/src/signing.ts +0 -28
  325. package/src/telegram-notify.ts +0 -88
  326. package/src/tui/App.tsx +0 -263
  327. package/src/tui/Footer.tsx +0 -18
  328. package/src/tui/Header.tsx +0 -45
  329. package/src/tui/InputLine.tsx +0 -243
  330. package/src/tui/Viewport.tsx +0 -51
  331. package/src/tui/WalletConnectPairing.tsx +0 -114
  332. package/src/tui/components/Button.tsx +0 -38
  333. package/src/tui/components/CeremonyView.tsx +0 -39
  334. package/src/tui/components/CompletionDropdown.tsx +0 -56
  335. package/src/tui/components/ConfirmPrompt.tsx +0 -36
  336. package/src/tui/components/CustomTextInput.tsx +0 -132
  337. package/src/tui/components/InteractiveTable.tsx +0 -106
  338. package/src/tui/components/StepSpinner.tsx +0 -84
  339. package/src/tui/components/Toast.tsx +0 -59
  340. package/src/tui/index.tsx +0 -90
  341. package/src/tui/useChat.ts +0 -103
  342. package/src/tui/useCommand.ts +0 -238
  343. package/src/tui/useNotifications.ts +0 -28
  344. package/src/tui/useScroll.ts +0 -69
  345. package/src/ui/banner.ts +0 -78
  346. package/src/ui/colors.ts +0 -30
  347. package/src/ui/format.ts +0 -78
  348. package/src/ui/qr-render.ts +0 -92
  349. package/src/ui/rpc-fallback.ts +0 -59
  350. package/src/ui/spinner.ts +0 -56
  351. package/src/ui/tree.ts +0 -16
  352. package/src/utils/format.ts +0 -48
  353. package/src/utils/hash.ts +0 -5
  354. package/src/utils/time.ts +0 -15
  355. package/src/wallet-router.ts +0 -178
  356. package/src/walletconnect-session.ts +0 -27
  357. package/src/walletconnect.ts +0 -309
  358. package/test/time.test.js +0 -11
  359. package/tsconfig.json +0 -33
package/src/tui/index.tsx DELETED
@@ -1,90 +0,0 @@
1
- import React from "react";
2
- import { render } from "ink";
3
- import { App } from "./App.js";
4
- import fs from "node:fs";
5
- import path from "node:path";
6
- import os from "node:os";
7
- import { createRequire } from "node:module";
8
-
9
- const pkg = createRequire(import.meta.url)("../../package.json") as { version: string };
10
-
11
- const CONFIG_PATH = path.join(os.homedir(), ".arc402", "config.json");
12
-
13
- interface Config {
14
- network?: string;
15
- walletContractAddress?: string;
16
- rpcUrl?: string;
17
- }
18
-
19
- async function loadConfig(): Promise<Config> {
20
- if (!fs.existsSync(CONFIG_PATH)) return {};
21
- try {
22
- return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8")) as Config;
23
- } catch {
24
- return {};
25
- }
26
- }
27
-
28
- async function getBalance(
29
- rpcUrl: string,
30
- address: string
31
- ): Promise<string | undefined> {
32
- try {
33
- const ethersLib = await import("ethers");
34
- const provider = new ethersLib.ethers.JsonRpcProvider(rpcUrl);
35
- const bal = await Promise.race([
36
- provider.getBalance(address),
37
- new Promise<never>((_, r) =>
38
- setTimeout(() => r(new Error("timeout")), 2000)
39
- ),
40
- ]);
41
- return `${parseFloat(ethersLib.ethers.formatEther(bal)).toFixed(4)} ETH`;
42
- } catch {
43
- return undefined;
44
- }
45
- }
46
-
47
- export async function launchTUI(): Promise<void> {
48
- const config = await loadConfig();
49
-
50
- let walletDisplay: string | undefined;
51
- if (config.walletContractAddress) {
52
- const w = config.walletContractAddress;
53
- walletDisplay = `${w.slice(0, 6)}...${w.slice(-4)}`;
54
- }
55
-
56
- let balance: string | undefined;
57
- if (config.rpcUrl && config.walletContractAddress) {
58
- balance = await getBalance(config.rpcUrl, config.walletContractAddress);
59
- }
60
-
61
- // Enter alternate screen buffer (full-screen mode)
62
- process.stdout.write("\x1b[?1049h");
63
- // Hide cursor initially — Ink manages it
64
- process.stdout.write("\x1b[?25l");
65
-
66
- const restore = () => {
67
- process.stdout.write("\x1b[?25h"); // show cursor
68
- process.stdout.write("\x1b[?1049l"); // leave alternate buffer
69
- };
70
-
71
- // Ensure restore on unexpected exit
72
- process.on("exit", restore);
73
- process.on("SIGINT", restore);
74
- process.on("SIGTERM", restore);
75
-
76
- const { waitUntilExit } = render(
77
- <App
78
- version={pkg.version}
79
- network={config.network}
80
- wallet={walletDisplay}
81
- balance={balance}
82
- />,
83
- { exitOnCtrlC: true }
84
- );
85
-
86
- await waitUntilExit();
87
-
88
- // Clean restore
89
- restore();
90
- }
@@ -1,103 +0,0 @@
1
- import { useState, useCallback } from "react";
2
- import chalk from "chalk";
3
- import { c } from "../ui/colors.js";
4
-
5
- interface UseChatResult {
6
- send: (message: string, onLine: (line: string) => void) => Promise<void>;
7
- isSending: boolean;
8
- }
9
-
10
- /**
11
- * Sends messages to the OpenClaw gateway and streams responses
12
- * line-by-line into the viewport buffer via onLine callback.
13
- */
14
- export function useChat(): UseChatResult {
15
- const [isSending, setIsSending] = useState(false);
16
-
17
- const send = useCallback(
18
- async (message: string, onLine: (line: string) => void): Promise<void> => {
19
- setIsSending(true);
20
- const trimmed = message.trim().slice(0, 10000);
21
-
22
- // Show thinking placeholder
23
- onLine(chalk.dim(" ◈ ") + chalk.dim("thinking..."));
24
-
25
- let res: Response;
26
- try {
27
- res = await fetch("http://localhost:19000/api/agent", {
28
- method: "POST",
29
- headers: { "Content-Type": "application/json" },
30
- body: JSON.stringify({ message: trimmed, session: "arc402-tui" }),
31
- signal: AbortSignal.timeout(30000),
32
- });
33
- } catch (err: unknown) {
34
- const msg = err instanceof Error ? err.message : String(err);
35
- const isDown =
36
- msg.includes("ECONNREFUSED") ||
37
- msg.includes("fetch failed") ||
38
- msg.includes("ENOTFOUND") ||
39
- msg.includes("UND_ERR_SOCKET");
40
- if (isDown) {
41
- onLine(
42
- " " +
43
- chalk.yellow("⚠") +
44
- " " +
45
- chalk.dim("OpenClaw gateway not running. Start with: ") +
46
- chalk.white("openclaw gateway start")
47
- );
48
- } else {
49
- onLine(` ${c.failure} ${chalk.red(msg)}`);
50
- }
51
- setIsSending(false);
52
- return;
53
- }
54
-
55
- if (!res.body) {
56
- onLine(chalk.dim(" ◈ ") + chalk.white("(empty response)"));
57
- setIsSending(false);
58
- return;
59
- }
60
-
61
- const flushLine = (line: string): void => {
62
- // Unwrap SSE data lines
63
- if (line.startsWith("data: ")) {
64
- line = line.slice(6);
65
- if (line === "[DONE]") return;
66
- try {
67
- const j = JSON.parse(line) as {
68
- text?: string;
69
- content?: string;
70
- delta?: { text?: string };
71
- };
72
- line = j.text ?? j.content ?? j.delta?.text ?? line;
73
- } catch {
74
- /* use raw */
75
- }
76
- }
77
- if (line.trim()) {
78
- onLine(chalk.dim(" ◈ ") + chalk.white(line));
79
- }
80
- };
81
-
82
- const reader = res.body.getReader();
83
- const decoder = new TextDecoder();
84
- let buffer = "";
85
-
86
- while (true) {
87
- const { done, value } = await reader.read();
88
- if (done) break;
89
- buffer += decoder.decode(value, { stream: true });
90
- const lines = buffer.split("\n");
91
- buffer = lines.pop() ?? "";
92
- for (const line of lines) flushLine(line);
93
- }
94
-
95
- if (buffer.trim()) flushLine(buffer);
96
-
97
- setIsSending(false);
98
- },
99
- []
100
- );
101
-
102
- return { send, isSending };
103
- }
@@ -1,238 +0,0 @@
1
- import { useState, useCallback } from "react";
2
- import { spawn } from "node:child_process";
3
- import { createProgram } from "../program.js";
4
- import chalk from "chalk";
5
- import { c } from "../ui/colors.js";
6
-
7
- const INTERACTIVE_COMMANDS = new Set([
8
- "wallet deploy",
9
- "wallet set-guardian",
10
- "wallet unfreeze",
11
- "wallet authorize-machine-key",
12
- "wallet revoke-machine-key",
13
- "wallet set-passkey",
14
- "wallet set-interceptor",
15
- "wallet set-velocity-limit",
16
- "wallet upgrade-registry",
17
- "wallet execute-registry-upgrade",
18
- "wallet cancel-registry-upgrade",
19
- "wallet register-policy",
20
- "wallet whitelist-contract",
21
- "wallet governance setup",
22
- "wallet policy set-limit",
23
- "wallet policy set-daily-limit",
24
- "wallet policy set",
25
- "wallet import",
26
- "config init",
27
- ]);
28
-
29
- function isInteractiveCommand(input: string): boolean {
30
- const trimmed = input.trim();
31
- for (const cmd of INTERACTIVE_COMMANDS) {
32
- if (trimmed === cmd || trimmed.startsWith(cmd + " ")) {
33
- return true;
34
- }
35
- }
36
- return false;
37
- }
38
-
39
- interface UseCommandResult {
40
- execute: (input: string, onLine: (line: string) => void) => Promise<void>;
41
- isRunning: boolean;
42
- }
43
-
44
- /**
45
- * Dispatches parsed commands to the commander program.
46
- * Interactive commands (WalletConnect, prompts) spawn a child process
47
- * because Ink holds stdin in raw mode.
48
- * Non-interactive commands run in-process with stdout monkey-patching.
49
- */
50
- export function useCommand(): UseCommandResult {
51
- const [isRunning, setIsRunning] = useState(false);
52
-
53
- const executeInteractive = useCallback(
54
- (input: string, onLine: (line: string) => void): Promise<void> => {
55
- return new Promise((resolve) => {
56
- const tokens = parseTokens(input);
57
-
58
- const child = spawn(process.execPath, [process.argv[1], ...tokens], {
59
- stdio: ["inherit", "pipe", "pipe"],
60
- env: { ...process.env, ARC402_NO_TUI: "1", ARC402_CHILD: "1", FORCE_COLOR: "1" },
61
- cwd: process.cwd(),
62
- });
63
-
64
- let stdoutRemainder = "";
65
- let stderrRemainder = "";
66
-
67
- child.stdout?.on("data", (chunk: Buffer) => {
68
- stdoutRemainder += chunk.toString("utf8");
69
- const lines = stdoutRemainder.split("\n");
70
- stdoutRemainder = lines.pop() ?? "";
71
- for (const line of lines) onLine(line.replace(/\r$/, ""));
72
- });
73
-
74
- child.stderr?.on("data", (chunk: Buffer) => {
75
- stderrRemainder += chunk.toString("utf8");
76
- const lines = stderrRemainder.split("\n");
77
- stderrRemainder = lines.pop() ?? "";
78
- for (const line of lines) onLine(line.replace(/\r$/, ""));
79
- });
80
-
81
- child.on("close", (code) => {
82
- if (stdoutRemainder.trim()) onLine(stdoutRemainder);
83
- if (stderrRemainder.trim()) onLine(stderrRemainder);
84
- if (code !== 0 && code !== null) {
85
- onLine(` ${c.failure} ${chalk.red(`Command exited with code ${code}`)}`);
86
- }
87
- resolve();
88
- });
89
-
90
- child.on("error", (err) => {
91
- onLine(` ${c.failure} ${chalk.red(`Failed to spawn: ${err.message}`)}`);
92
- resolve();
93
- });
94
- });
95
- },
96
- []
97
- );
98
-
99
- const executeInProcess = useCallback(
100
- async (input: string, onLine: (line: string) => void): Promise<void> => {
101
- // Capture stdout/stderr
102
- const originalStdoutWrite = process.stdout.write.bind(process.stdout);
103
- const originalStderrWrite = process.stderr.write.bind(process.stderr);
104
-
105
- let captureBuffer = "";
106
-
107
- const flushBuffer = (): void => {
108
- if (!captureBuffer) return;
109
- const lines = captureBuffer.split("\n");
110
- captureBuffer = lines.pop() ?? "";
111
- for (const line of lines) {
112
- onLine(line);
113
- }
114
- };
115
-
116
- const capturedWrite = (
117
- chunk: string | Uint8Array,
118
- encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),
119
- cb?: (err?: Error | null) => void
120
- ): boolean => {
121
- const str =
122
- typeof chunk === "string"
123
- ? chunk
124
- : Buffer.from(chunk).toString("utf8");
125
- captureBuffer += str;
126
- flushBuffer();
127
- const callback =
128
- typeof encodingOrCb === "function" ? encodingOrCb : cb;
129
- if (callback) callback();
130
- return true;
131
- };
132
-
133
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
134
- (process.stdout as any).write = capturedWrite;
135
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
- (process.stderr as any).write = capturedWrite;
137
-
138
- try {
139
- const tokens = parseTokens(input);
140
- const prog = createProgram();
141
- prog.exitOverride();
142
- prog.configureOutput({
143
- writeOut: (str: string) => process.stdout.write(str),
144
- writeErr: (str: string) => process.stderr.write(str),
145
- });
146
-
147
- await prog.parseAsync(["node", "arc402", ...tokens]);
148
- } catch (err) {
149
- const e = err as { code?: string; message?: string };
150
- if (
151
- e.code === "commander.helpDisplayed" ||
152
- e.code === "commander.version" ||
153
- e.code === "commander.executeSubCommandAsync"
154
- ) {
155
- // already written or normal exit — no-op
156
- } else if (e.code === "commander.unknownCommand") {
157
- const tokens = parseTokens(input);
158
- onLine(
159
- ` ${c.failure} ${chalk.red(`Unknown command: ${chalk.white(tokens[0])}`)} `
160
- );
161
- onLine(chalk.dim(" Type 'help' for available commands"));
162
- } else if (e.code?.startsWith("commander.")) {
163
- onLine(` ${c.failure} ${chalk.red(e.message ?? String(err))}`);
164
- } else {
165
- onLine(` ${c.failure} ${chalk.red(e.message ?? String(err))}`);
166
- }
167
- } finally {
168
- // Flush remaining buffer
169
- if (captureBuffer.trim()) {
170
- onLine(captureBuffer);
171
- captureBuffer = "";
172
- }
173
-
174
- // Restore original write functions
175
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
176
- (process.stdout as any).write = originalStdoutWrite;
177
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
178
- (process.stderr as any).write = originalStderrWrite;
179
- }
180
- },
181
- []
182
- );
183
-
184
- const execute = useCallback(
185
- async (input: string, onLine: (line: string) => void): Promise<void> => {
186
- setIsRunning(true);
187
- try {
188
- if (isInteractiveCommand(input)) {
189
- await executeInteractive(input, onLine);
190
- } else {
191
- await executeInProcess(input, onLine);
192
- }
193
- } finally {
194
- setIsRunning(false);
195
- }
196
- },
197
- [executeInteractive, executeInProcess]
198
- );
199
-
200
- return { execute, isRunning };
201
- }
202
-
203
- // Shell-style tokenizer
204
- function parseTokens(input: string): string[] {
205
- const tokens: string[] = [];
206
- let current = "";
207
- let inQuote = false;
208
- let quoteChar = "";
209
- let escape = false;
210
- for (const ch of input) {
211
- if (escape) {
212
- current += ch;
213
- escape = false;
214
- continue;
215
- }
216
- if (inQuote) {
217
- if (quoteChar === '"' && ch === "\\") {
218
- escape = true;
219
- } else if (ch === quoteChar) {
220
- inQuote = false;
221
- } else {
222
- current += ch;
223
- }
224
- } else if (ch === '"' || ch === "'") {
225
- inQuote = true;
226
- quoteChar = ch;
227
- } else if (ch === " ") {
228
- if (current) {
229
- tokens.push(current);
230
- current = "";
231
- }
232
- } else {
233
- current += ch;
234
- }
235
- }
236
- if (current) tokens.push(current);
237
- return tokens;
238
- }
@@ -1,28 +0,0 @@
1
- import { useState, useCallback } from "react";
2
- import type { ToastData, ToastVariant } from "./components/Toast.js";
3
-
4
- let _nextId = 0;
5
-
6
- interface UseNotificationsResult {
7
- toasts: ToastData[];
8
- push: (message: string, variant?: ToastVariant, duration?: number) => void;
9
- dismiss: (id: string) => void;
10
- }
11
-
12
- export function useNotifications(): UseNotificationsResult {
13
- const [toasts, setToasts] = useState<ToastData[]>([]);
14
-
15
- const push = useCallback(
16
- (message: string, variant: ToastVariant = "info", duration?: number) => {
17
- const id = `toast-${++_nextId}`;
18
- setToasts((prev) => [...prev, { id, message, variant, duration }]);
19
- },
20
- []
21
- );
22
-
23
- const dismiss = useCallback((id: string) => {
24
- setToasts((prev) => prev.filter((t) => t.id !== id));
25
- }, []);
26
-
27
- return { toasts, push, dismiss };
28
- }
@@ -1,69 +0,0 @@
1
- import { useState, useCallback } from "react";
2
- import { useInput } from "ink";
3
-
4
- interface UseScrollResult {
5
- scrollOffset: number;
6
- setScrollOffset: (offset: number) => void;
7
- viewportHeight: number;
8
- isAutoScroll: boolean;
9
- scrollUp: (lines?: number) => void;
10
- scrollDown: (lines?: number) => void;
11
- snapToBottom: () => void;
12
- }
13
-
14
- /**
15
- * Manages scroll state for the Viewport.
16
- * scrollOffset=0 means auto-scroll (pinned to bottom).
17
- * Positive scrollOffset means scrolled up by that many lines.
18
- */
19
- export function useScroll(viewportHeight: number): UseScrollResult {
20
- const [scrollOffset, setScrollOffsetState] = useState(0);
21
-
22
- const isAutoScroll = scrollOffset === 0;
23
-
24
- const setScrollOffset = useCallback((offset: number) => {
25
- setScrollOffsetState(Math.max(0, offset));
26
- }, []);
27
-
28
- const scrollUp = useCallback(
29
- (lines?: number) => {
30
- const step = lines ?? viewportHeight;
31
- setScrollOffsetState((prev) => prev + step);
32
- },
33
- [viewportHeight]
34
- );
35
-
36
- const scrollDown = useCallback(
37
- (lines?: number) => {
38
- const step = lines ?? viewportHeight;
39
- setScrollOffsetState((prev) => Math.max(0, prev - step));
40
- },
41
- [viewportHeight]
42
- );
43
-
44
- const snapToBottom = useCallback(() => {
45
- setScrollOffsetState(0);
46
- }, []);
47
-
48
- useInput((_input, key) => {
49
- if (key.pageUp) {
50
- scrollUp(viewportHeight);
51
- } else if (key.pageDown) {
52
- scrollDown(viewportHeight);
53
- } else if (key.shift && key.upArrow) {
54
- scrollUp(1);
55
- } else if (key.shift && key.downArrow) {
56
- scrollDown(1);
57
- }
58
- });
59
-
60
- return {
61
- scrollOffset,
62
- setScrollOffset,
63
- viewportHeight,
64
- isAutoScroll,
65
- scrollUp,
66
- scrollDown,
67
- snapToBottom,
68
- };
69
- }
package/src/ui/banner.ts DELETED
@@ -1,78 +0,0 @@
1
- import { createRequire } from "node:module";
2
- import chalk from "chalk";
3
-
4
- const _pkg = createRequire(import.meta.url)("../../package.json") as { version: string };
5
-
6
- const ART = `
7
- ██████╗ ██████╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗
8
- ██╔══██╗██╔══██╗██╔════╝ ██║ ██║██╔═══██╗╚════██╗
9
- ███████║██████╔╝██║ █████╗███████║██║ ██║ █████╔╝
10
- ██╔══██║██╔══██╗██║ ╚════╝╚════██║██║ ██║██╔═══╝
11
- ██║ ██║██║ ██║╚██████╗ ██║╚██████╔╝███████╗
12
- ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝`;
13
-
14
- const SEPARATOR = chalk.cyanBright("◈") + " " + chalk.dim("─".repeat(45));
15
-
16
- export interface BannerConfig {
17
- network?: string;
18
- wallet?: string;
19
- balance?: string;
20
- }
21
-
22
- /** Returns banner as an array of plain lines (no trailing newlines). */
23
- export function getBannerLines(config?: BannerConfig): string[] {
24
- const lines: string[] = [];
25
- // ART has a leading newline — skip it
26
- for (const l of ART.split("\n").slice(1)) {
27
- lines.push(chalk.cyan(l));
28
- }
29
- lines.push("");
30
- lines.push(" " + chalk.dim(`agent-to-agent arcing · v${_pkg.version}`));
31
- lines.push(" " + SEPARATOR);
32
- if (config) {
33
- lines.push("");
34
- if (config.network)
35
- lines.push(` ${chalk.dim("Network")} ${chalk.white(config.network)}`);
36
- if (config.wallet)
37
- lines.push(` ${chalk.dim("Wallet")} ${chalk.white(config.wallet)}`);
38
- if (config.balance)
39
- lines.push(` ${chalk.dim("Balance")} ${chalk.white(config.balance)}`);
40
- }
41
- lines.push("");
42
- lines.push(` ${chalk.dim("Type 'help' to get started")}`);
43
- lines.push("");
44
- return lines;
45
- }
46
-
47
- export interface StatusItem {
48
- label: string;
49
- value: string;
50
- }
51
-
52
- /** Returns the ASCII art lines (no status info) and a subtitle line. */
53
- export function getBannerArt(): { artLines: string[]; subtitle: string; separator: string } {
54
- const artLines: string[] = [];
55
- for (const l of ART.split("\n").slice(1)) {
56
- artLines.push(chalk.cyan(l));
57
- }
58
- return {
59
- artLines,
60
- subtitle: " " + chalk.dim(`agent-to-agent arcing · v${_pkg.version}`),
61
- separator: " " + SEPARATOR,
62
- };
63
- }
64
-
65
- /** Returns structured status items for flexWrap rendering. */
66
- export function getStatusItems(config?: BannerConfig): StatusItem[] {
67
- const items: StatusItem[] = [];
68
- if (config?.network) items.push({ label: "Network", value: config.network });
69
- if (config?.wallet) items.push({ label: "Wallet", value: config.wallet });
70
- if (config?.balance) items.push({ label: "Balance", value: config.balance });
71
- return items;
72
- }
73
-
74
- export function renderBanner(config?: BannerConfig): void {
75
- for (const line of getBannerLines(config)) {
76
- console.log(line);
77
- }
78
- }
package/src/ui/colors.ts DELETED
@@ -1,30 +0,0 @@
1
- import chalk from "chalk";
2
-
3
- // ─── ARC-402 Color System ─────────────────────────────────────────────────────
4
-
5
- export const c = {
6
- // Protocol mark + section headings
7
- cyan: chalk.cyan,
8
- brightCyan: chalk.cyanBright,
9
-
10
- // Primary content, values
11
- white: chalk.white,
12
-
13
- // Secondary info — addresses, timestamps, labels
14
- dim: chalk.dim,
15
-
16
- // Success states, fulfilled agreements
17
- green: chalk.green,
18
-
19
- // Errors, disputes, failures
20
- red: chalk.red,
21
-
22
- // Warnings, pending states, unconfirmed
23
- yellow: chalk.yellow,
24
-
25
- // Symbols
26
- mark: chalk.cyanBright("◈"),
27
- success: chalk.green("✓"),
28
- failure: chalk.red("✗"),
29
- warning: chalk.yellow("⚠"),
30
- };