@agentdocumentformat/cli 0.7.2

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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/adf.mjs +162 -0
  4. package/dist/chunks/APEv2Parser-2CNNHMXV.mjs +22 -0
  5. package/dist/chunks/AiffParser-7BR4RL6G.mjs +162 -0
  6. package/dist/chunks/App-L5L37JI5.mjs +16747 -0
  7. package/dist/chunks/AsfParser-VVRSLFOM.mjs +538 -0
  8. package/dist/chunks/DsdiffParser-CMD4AX7A.mjs +156 -0
  9. package/dist/chunks/DsfParser-UOGZDS2M.mjs +94 -0
  10. package/dist/chunks/FlacParser-HB3T3CD4.mjs +23 -0
  11. package/dist/chunks/MP4Parser-66HBRUSX.mjs +973 -0
  12. package/dist/chunks/MatroskaParser-J3HUIMEW.mjs +579 -0
  13. package/dist/chunks/MpegParser-YW6LIUEW.mjs +442 -0
  14. package/dist/chunks/MusepackParser-PAUSXP7D.mjs +252 -0
  15. package/dist/chunks/OggParser-NUBV3GWC.mjs +359 -0
  16. package/dist/chunks/WavPackParser-WQAGT7TC.mjs +171 -0
  17. package/dist/chunks/WaveParser-EWLQVDX4.mjs +238 -0
  18. package/dist/chunks/adf-schema-JRU2BTOG.mjs +62 -0
  19. package/dist/chunks/build-QF5W473T.mjs +60 -0
  20. package/dist/chunks/chatgpt-subscription-BQGWYZXE.mjs +23 -0
  21. package/dist/chunks/chunk-2DIECGFL.mjs +6 -0
  22. package/dist/chunks/chunk-2NAP2ZF7.mjs +60 -0
  23. package/dist/chunks/chunk-3AT7IIP7.mjs +25696 -0
  24. package/dist/chunks/chunk-3GNIDM53.mjs +35 -0
  25. package/dist/chunks/chunk-3M4ZPOA3.mjs +1477 -0
  26. package/dist/chunks/chunk-4MQPTCXY.mjs +510 -0
  27. package/dist/chunks/chunk-5PO5PKRV.mjs +366 -0
  28. package/dist/chunks/chunk-5QU5VY7N.mjs +52 -0
  29. package/dist/chunks/chunk-5W7KES6P.mjs +436 -0
  30. package/dist/chunks/chunk-62NE4LG4.mjs +61 -0
  31. package/dist/chunks/chunk-64OKE4X3.mjs +45 -0
  32. package/dist/chunks/chunk-6GJ4QHRI.mjs +1278 -0
  33. package/dist/chunks/chunk-6VQEXLE2.mjs +144 -0
  34. package/dist/chunks/chunk-6XUV6EK6.mjs +41 -0
  35. package/dist/chunks/chunk-776TSXEP.mjs +43 -0
  36. package/dist/chunks/chunk-7CV2SA3H.mjs +285 -0
  37. package/dist/chunks/chunk-7MTRVW2U.mjs +3103 -0
  38. package/dist/chunks/chunk-7N2R2VCG.mjs +1434 -0
  39. package/dist/chunks/chunk-7T2YMTWL.mjs +374 -0
  40. package/dist/chunks/chunk-7XYNI52E.mjs +149 -0
  41. package/dist/chunks/chunk-APHX6HSV.mjs +7731 -0
  42. package/dist/chunks/chunk-APRU6PHC.mjs +40 -0
  43. package/dist/chunks/chunk-AUYKRQPJ.mjs +499 -0
  44. package/dist/chunks/chunk-DXWDD5XJ.mjs +136 -0
  45. package/dist/chunks/chunk-EWL5FG4I.mjs +39 -0
  46. package/dist/chunks/chunk-EYX2YLJW.mjs +117 -0
  47. package/dist/chunks/chunk-F5ELW46V.mjs +27 -0
  48. package/dist/chunks/chunk-G426FACA.mjs +49 -0
  49. package/dist/chunks/chunk-GEKSJHIV.mjs +2472 -0
  50. package/dist/chunks/chunk-HBUENVQL.mjs +570 -0
  51. package/dist/chunks/chunk-HPVFJYXR.mjs +112 -0
  52. package/dist/chunks/chunk-HWLWPXQ7.mjs +721 -0
  53. package/dist/chunks/chunk-I2HJYHFT.mjs +665 -0
  54. package/dist/chunks/chunk-I3UYSITV.mjs +68 -0
  55. package/dist/chunks/chunk-IC4JDZCI.mjs +3864 -0
  56. package/dist/chunks/chunk-IHDDCZBS.mjs +112 -0
  57. package/dist/chunks/chunk-IIGMZHQQ.mjs +10416 -0
  58. package/dist/chunks/chunk-KWFOS5WC.mjs +41 -0
  59. package/dist/chunks/chunk-LAZIXV2F.mjs +5290 -0
  60. package/dist/chunks/chunk-LFMB4PAA.mjs +10814 -0
  61. package/dist/chunks/chunk-M2RX3S2T.mjs +49 -0
  62. package/dist/chunks/chunk-M3WPIJYM.mjs +65 -0
  63. package/dist/chunks/chunk-NBTUWMGP.mjs +263 -0
  64. package/dist/chunks/chunk-NGK6PVSF.mjs +2676 -0
  65. package/dist/chunks/chunk-NZ7JTHEO.mjs +85 -0
  66. package/dist/chunks/chunk-OQN33RGQ.mjs +52 -0
  67. package/dist/chunks/chunk-RIX34QHC.mjs +2935 -0
  68. package/dist/chunks/chunk-SGUTYISF.mjs +16 -0
  69. package/dist/chunks/chunk-SLJ5L7PY.mjs +1473 -0
  70. package/dist/chunks/chunk-SLUKGXKH.mjs +68 -0
  71. package/dist/chunks/chunk-TMT32MXT.mjs +419 -0
  72. package/dist/chunks/chunk-UYY5M2PB.mjs +151 -0
  73. package/dist/chunks/chunk-VAUOM3IN.mjs +298 -0
  74. package/dist/chunks/chunk-VMHTYDH4.mjs +172 -0
  75. package/dist/chunks/chunk-VZS54AA5.mjs +200 -0
  76. package/dist/chunks/chunk-WFQUVXML.mjs +295 -0
  77. package/dist/chunks/chunk-X34PDRUH.mjs +809 -0
  78. package/dist/chunks/chunk-XNPZBLYL.mjs +33 -0
  79. package/dist/chunks/chunk-XX7OSWTO.mjs +157 -0
  80. package/dist/chunks/chunk-XYTWGHFS.mjs +600 -0
  81. package/dist/chunks/chunk-XYV3VCIX.mjs +336 -0
  82. package/dist/chunks/chunk-Y5ZLKFLE.mjs +1469 -0
  83. package/dist/chunks/chunk-ZJKXHM4Q.mjs +230 -0
  84. package/dist/chunks/cli-TCMBNZF6.mjs +1030 -0
  85. package/dist/chunks/commands-DTEKM4ZL.mjs +20 -0
  86. package/dist/chunks/daemon-ZC3FZ2P4.mjs +112449 -0
  87. package/dist/chunks/daemon-control-WDX7PMTC.mjs +300 -0
  88. package/dist/chunks/daemon-token-WRSULP7G.mjs +23 -0
  89. package/dist/chunks/devtools-H7CI2ZVG.mjs +85 -0
  90. package/dist/chunks/discord-IWDQJA7A.mjs +70588 -0
  91. package/dist/chunks/dist-C57KYFS2.mjs +4952 -0
  92. package/dist/chunks/dist-I3XBAGDL.mjs +11 -0
  93. package/dist/chunks/email-V4Q4VJON.mjs +58679 -0
  94. package/dist/chunks/environment-NX277MQG.mjs +15 -0
  95. package/dist/chunks/grok-subscription-4PYX7TBF.mjs +19 -0
  96. package/dist/chunks/layout-EPJQNFAI.mjs +22 -0
  97. package/dist/chunks/lib-N7FCZWKH.mjs +4038 -0
  98. package/dist/chunks/open-OTQDGDH5.mjs +36 -0
  99. package/dist/chunks/parser-JVY2PWSM.mjs +19 -0
  100. package/dist/chunks/pipeline-executor-BHBSJX2K.mjs +19 -0
  101. package/dist/chunks/react-IUIDQ5LX.mjs +11 -0
  102. package/dist/chunks/screen-54BUTYCW.mjs +27 -0
  103. package/dist/chunks/slack-3L5QTDZX.mjs +8113 -0
  104. package/dist/chunks/store-WR7TZJZS.mjs +32 -0
  105. package/dist/chunks/telegram-5ISVFBV3.mjs +14918 -0
  106. package/dist/chunks/terminal-O5WO7C5U.mjs +48 -0
  107. package/dist/chunks/theme-NORU4J74.mjs +20 -0
  108. package/dist/chunks/themes-F2FKU7CP.mjs +23 -0
  109. package/dist/chunks/token-6G3HCMNX.mjs +54 -0
  110. package/dist/chunks/token-util-UXYSDQIW.mjs +12 -0
  111. package/dist/chunks/tui-ODVYUIMT.mjs +197 -0
  112. package/dist/chunks/welcome-XHXFV7SH.mjs +32 -0
  113. package/dist/chunks/whatsapp-XSAMNGPJ.mjs +85412 -0
  114. package/dist/chunks/xterm-headless-YF53XWXE.mjs +3353 -0
  115. package/package.json +53 -0
  116. package/resources/wasm/coreutils.LICENSE +18 -0
  117. package/resources/wasm/coreutils.wasm +0 -0
@@ -0,0 +1,1030 @@
1
+ import { createRequire as __adfCreateRequire } from 'node:module';
2
+ import { fileURLToPath as __adfFileURLToPath } from 'node:url';
3
+ import { dirname as __adfDirname } from 'node:path';
4
+ const require = __adfCreateRequire(import.meta.url);
5
+ const __filename = __adfFileURLToPath(import.meta.url);
6
+ const __dirname = __adfDirname(__filename);
7
+ import {
8
+ AUTH_PROVIDER_LABELS,
9
+ loginChatGpt,
10
+ loginGrok,
11
+ normalizeAuthProvider,
12
+ openBrowser
13
+ } from "./chunk-6VQEXLE2.mjs";
14
+ import "./chunk-2NAP2ZF7.mjs";
15
+ import {
16
+ DEFAULT_DAEMON_URL,
17
+ resolveDaemonToken,
18
+ resolveDaemonUrl
19
+ } from "./chunk-G426FACA.mjs";
20
+ import "./chunk-IHDDCZBS.mjs";
21
+ import "./chunk-M2RX3S2T.mjs";
22
+
23
+ // src/main/cli/index.ts
24
+ var defaultIo = {
25
+ fetch: globalThis.fetch.bind(globalThis),
26
+ stdout: (text) => process.stdout.write(text),
27
+ stderr: (text) => process.stderr.write(text)
28
+ }, TUI_FLAGS = /* @__PURE__ */ new Set(["--view", "--agent", "--loop", "--theme", "--mono", "--no-color", "--ascii", "--no-alt-screen", "--no-mouse", "--mouse", "--no-kitty"]);
29
+ function tuiInvocation(argv) {
30
+ for (let i = 0; i < argv.length; i++) {
31
+ let arg = argv[i];
32
+ if (arg === "--url" || arg === "-u" || arg === "--token") {
33
+ i++;
34
+ continue;
35
+ }
36
+ if (!(arg.startsWith("--url=") || arg.startsWith("--token=") || arg === "--json"))
37
+ return arg === "tui" || TUI_FLAGS.has(arg) || [...TUI_FLAGS].some((flag) => arg.startsWith(`${flag}=`)) ? argv.filter((a) => a !== "--json") : null;
38
+ }
39
+ return argv.filter((a) => a !== "--json");
40
+ }
41
+ async function defaultLaunchTui(argv) {
42
+ let { runTui } = await import("./tui-ODVYUIMT.mjs");
43
+ return await runTui(argv);
44
+ }
45
+ function urlFromArgv(argv) {
46
+ for (let i = 0; i < argv.length; i++) {
47
+ if (argv[i] === "--url" || argv[i] === "-u") return resolveDaemonUrl(argv[i + 1]);
48
+ if (argv[i].startsWith("--url=")) return resolveDaemonUrl(argv[i].slice(6));
49
+ }
50
+ return resolveDaemonUrl(void 0);
51
+ }
52
+ async function daemonReady(io, url) {
53
+ if (!io.ensureDaemon) return { ok: !0, started: null };
54
+ try {
55
+ return { ok: !0, started: (await io.ensureDaemon(url))?.pid ?? null };
56
+ } catch (err) {
57
+ let advice = err.advice;
58
+ return io.stderr(`${err instanceof Error ? err.message : String(err)}
59
+ ${advice ? `${advice}
60
+ ` : ""}`), { ok: !1, started: null };
61
+ }
62
+ }
63
+ async function runCli(argv = process.argv.slice(2), io = defaultIo) {
64
+ let tuiArgv = tuiInvocation(argv);
65
+ if (tuiArgv) {
66
+ let ready = tuiArgv.includes("--help") || tuiArgv.includes("-h") ? { ok: !0, started: null } : await daemonReady(io, urlFromArgv(tuiArgv));
67
+ if (!ready.ok) return 1;
68
+ try {
69
+ let code = await (io.launchTui ?? defaultLaunchTui)(tuiArgv);
70
+ return ready.started && io.stdout(`The daemon (pid ${ready.started}) keeps running in the background. Stop it with: adf daemon stop
71
+ `), code;
72
+ } catch (err) {
73
+ return io.stderr(`${err instanceof Error ? err.message : String(err)}
74
+ `), 1;
75
+ }
76
+ }
77
+ let parsed;
78
+ try {
79
+ parsed = parseArgs(argv);
80
+ } catch (err) {
81
+ return io.stderr(`${err instanceof Error ? err.message : String(err)}
82
+
83
+ ${usage()}
84
+ `), 2;
85
+ }
86
+ let { command, args, options } = parsed;
87
+ if (!["help", "--help", "-h"].includes(command) && !(await daemonReady(io, options.daemonUrl)).ok) return 1;
88
+ try {
89
+ switch (command) {
90
+ case "help":
91
+ case "--help":
92
+ case "-h":
93
+ return io.stdout(`${usage()}
94
+ `), 0;
95
+ case "agents":
96
+ return await printGet(io, options, "/agents", formatAgents);
97
+ case "status":
98
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/status`, formatStatus));
99
+ case "start":
100
+ return await controlAgent(io, options, args, "start");
101
+ case "stop":
102
+ case "unload":
103
+ return await controlAgent(io, options, args, "stop");
104
+ case "abort":
105
+ return await controlLoop(io, options, args, "abort");
106
+ case "interrupt":
107
+ return await controlLoop(io, options, args, "interrupt");
108
+ case "loops":
109
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/loops`, formatLoops));
110
+ case "config":
111
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/config`, formatJsonPretty));
112
+ case "providers":
113
+ return await printGet(io, options, "/runtime/providers", formatProviders);
114
+ case "auth":
115
+ return args[0] ? await authCommand(io, options, args) : await printGet(io, options, "/runtime/auth", formatAuth);
116
+ case "settings":
117
+ return await printGet(io, options, "/runtime/settings", formatJsonPretty);
118
+ case "network":
119
+ return args[0] ? await networkAdmin(io, options, args) : await printGet(io, options, "/runtime/network", formatNetwork);
120
+ case "usage":
121
+ return args[0] ? await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/usage`, formatUsage)) : await printGet(io, options, "/runtime/usage", formatUsage);
122
+ case "files":
123
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/files`, formatFiles));
124
+ case "file":
125
+ return await withAgentAndValue(args, "file path", io, async (agent, path) => {
126
+ let data = await requestJson(io, options, `/agents/${enc(agent)}/files/content?path=${enc(path)}`);
127
+ return options.json ? io.stdout(`${JSON.stringify(data, null, 2)}
128
+ `) : isRecord(data) && data.encoding === "utf-8" && typeof data.content == "string" ? io.stdout(data.content) : isRecord(data) && typeof data.content_base64 == "string" ? io.stdout(`${data.content_base64}
129
+ `) : io.stdout(`${JSON.stringify(data, null, 2)}
130
+ `), 0;
131
+ });
132
+ case "inbox":
133
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/inbox`, formatMessages("inbox")));
134
+ case "outbox":
135
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/outbox`, formatMessages("outbox")));
136
+ case "timers":
137
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/timers`, formatTimers));
138
+ case "tasks":
139
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/tasks`, formatTasks));
140
+ case "task":
141
+ return await withAgentAndValue(args, "task id", io, async (agent, taskId) => printGet(io, options, `/agents/${enc(agent)}/tasks/${enc(taskId)}`, formatJsonPretty));
142
+ case "approve":
143
+ return await resolveTask(io, options, args, "approve");
144
+ case "deny":
145
+ return await resolveTask(io, options, args, "deny");
146
+ case "asks":
147
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/asks`, formatAsks));
148
+ case "answer":
149
+ return await answerAsk(io, options, args);
150
+ case "identities":
151
+ return await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/identities`, formatIdentities));
152
+ case "runtime":
153
+ return args[0] ? await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/runtime`, formatJsonPretty)) : await printGet(io, options, "/runtime", formatJsonPretty);
154
+ case "mcp":
155
+ return args[0] ? await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/runtime/mcp`, formatMcp)) : await printGet(io, options, "/runtime/mcp", formatGlobalMcp);
156
+ case "adapters":
157
+ return args[0] ? await withAgent(args, io, async (agent) => printGet(io, options, `/agents/${enc(agent)}/runtime/adapters`, formatAdapters)) : await printGet(io, options, "/runtime/adapters", formatGlobalAdapters);
158
+ case "events":
159
+ return await streamEvents(io, options, args);
160
+ case "chat":
161
+ return await sendChat(io, options, args);
162
+ case "identity":
163
+ return await identityCommand(io, options, args);
164
+ case "templates":
165
+ return await printGet(io, options, "/templates", formatTemplates);
166
+ case "new":
167
+ return await newAgent(io, options, args);
168
+ default:
169
+ return io.stderr(`Unknown command: ${command}
170
+
171
+ ${usage()}
172
+ `), 2;
173
+ }
174
+ } catch (err) {
175
+ return io.stderr(`${err instanceof Error ? err.message : String(err)}
176
+ `), 1;
177
+ }
178
+ }
179
+ function parseArgs(argv) {
180
+ let args = [...argv], daemonUrl = process.env.ADF_DAEMON_URL ?? DEFAULT_DAEMON_URL, json = !1, token, positional = [];
181
+ for (let i = 0; i < args.length; i++) {
182
+ let arg = args[i];
183
+ if (arg === "--json")
184
+ json = !0;
185
+ else if (arg === "--url" || arg === "-u") {
186
+ let value = args[++i];
187
+ if (!value) throw new Error(`${arg} requires a daemon URL`);
188
+ daemonUrl = value;
189
+ } else if (arg.startsWith("--url="))
190
+ daemonUrl = arg.slice(6);
191
+ else if (arg === "--token") {
192
+ let value = args[++i];
193
+ if (!value) throw new Error("--token requires a value");
194
+ token = value;
195
+ } else arg.startsWith("--token=") ? token = arg.slice(8) : positional.push(arg);
196
+ }
197
+ return {
198
+ command: positional[0] ?? "help",
199
+ args: positional.slice(1),
200
+ options: {
201
+ daemonUrl: daemonUrl.replace(/\/+$/, ""),
202
+ json,
203
+ ...token ? { token } : {}
204
+ }
205
+ };
206
+ }
207
+ async function printGet(io, options, path, formatter) {
208
+ let data = await requestJson(io, options, path);
209
+ return io.stdout(options.json ? `${JSON.stringify(data, null, 2)}
210
+ ` : formatter(data)), 0;
211
+ }
212
+ function authHeader(options) {
213
+ let token = resolveDaemonToken(options.token, process.env, options.daemonUrl);
214
+ return token ? { Authorization: `Bearer ${token}` } : {};
215
+ }
216
+ async function requestJson(io, options, path, init) {
217
+ let response;
218
+ try {
219
+ response = await io.fetch(`${options.daemonUrl}${path}`, {
220
+ ...init,
221
+ headers: {
222
+ ...init?.headers ?? {},
223
+ Accept: "application/json",
224
+ ...authHeader(options)
225
+ }
226
+ });
227
+ } catch (err) {
228
+ throw err instanceof TypeError ? new Error(`Cannot reach the ADF daemon at ${options.daemonUrl} (${err.message}). Start it with: adf daemon start`) : err;
229
+ }
230
+ let text = await response.text(), body = null;
231
+ if (text.trim())
232
+ try {
233
+ body = JSON.parse(text);
234
+ } catch {
235
+ body = text;
236
+ }
237
+ if (!response.ok) {
238
+ let message = isRecord(body) && typeof body.error == "string" ? body.error : `HTTP ${response.status} ${response.statusText}`;
239
+ throw new Error(message);
240
+ }
241
+ return body;
242
+ }
243
+ function takeLoop(args) {
244
+ let rest = [], loop;
245
+ for (let i = 0; i < args.length; i++) {
246
+ let arg = args[i];
247
+ if (arg === "--loop") {
248
+ if (loop = args[++i], !loop) throw new Error("--loop requires a loop name");
249
+ } else arg.startsWith("--loop=") ? loop = arg.slice(7) : rest.push(arg);
250
+ }
251
+ return { loop: loop && loop !== "main" ? loop : void 0, rest };
252
+ }
253
+ async function sendChat(io, options, args) {
254
+ let { loop, rest } = takeLoop(args), agent = rest[0], text = rest.slice(1).join(" ");
255
+ if (!agent || !text) throw new Error("Usage: adf chat <agent> [--loop <name>] <message>");
256
+ let data = await requestJson(io, options, `/agents/${enc(agent)}/chat`, {
257
+ method: "POST",
258
+ headers: { "Content-Type": "application/json" },
259
+ body: JSON.stringify({ text, ...loop ? { loop } : {} })
260
+ });
261
+ return io.stdout(options.json ? `${JSON.stringify(data, null, 2)}
262
+ ` : formatChatAck(data)), 0;
263
+ }
264
+ async function controlLoop(io, options, args, action) {
265
+ let { loop, rest } = takeLoop(args), agent = rest[0];
266
+ if (!agent) throw new Error(`Usage: adf ${action} <agent> [--loop <name>]`);
267
+ let query = loop ? `?loop=${enc(loop)}` : "", data = await requestJson(io, options, `/agents/${enc(agent)}/${action}${query}`, { method: "POST" });
268
+ return options.json ? io.stdout(`${JSON.stringify(data, null, 2)}
269
+ `) : action === "abort" ? io.stdout(formatAgentControl("abort", loop ? `${agent} (loop ${loop})` : agent, data)) : io.stdout(isRecord(data) && data.interrupted === !1 ? `Nothing running in ${agent} ${loop ?? "main"}
270
+ ` : `Interrupted ${agent} ${loop ?? "main"}: the loop is idle and keeps accepting work
271
+ `), 0;
272
+ }
273
+ function formatLoops(value) {
274
+ let loops = isRecord(value) && Array.isArray(value.loops) ? value.loops.filter(isRecord) : [];
275
+ return loops.length === 0 ? `No loops
276
+ ` : table(["loop", "kind", "enabled", "status", "entries", "goal"], loops.map((loop) => [
277
+ String(loop.name ?? ""),
278
+ loop.isMain === !0 || loop.name === "main" ? "main" : "inner",
279
+ String(loop.enabled ?? !0),
280
+ String(loop.status ?? ""),
281
+ String(loop.entryCount ?? ""),
282
+ truncateCell(String(loop.goal ?? ""), 60)
283
+ ]));
284
+ }
285
+ function truncateCell(text, max) {
286
+ let line = text.replace(/\s+/g, " ").trim();
287
+ return line.length > max ? `${line.slice(0, max - 1)}\u2026` : line;
288
+ }
289
+ async function resolveTask(io, options, args, action) {
290
+ let agent = args[0], taskId = args[1], reason = action === "deny" ? args.slice(2).join(" ") : void 0;
291
+ if (!agent || !taskId) throw new Error(`Usage: adf ${action} <agent> <taskId>${action === "deny" ? " [reason]" : ""}`);
292
+ let data = await requestJson(io, options, `/agents/${enc(agent)}/tasks/${enc(taskId)}/resolve`, {
293
+ method: "POST",
294
+ headers: { "Content-Type": "application/json" },
295
+ body: JSON.stringify({ action, ...reason ? { reason } : {} })
296
+ });
297
+ return io.stdout(options.json ? `${JSON.stringify(data, null, 2)}
298
+ ` : formatTaskResolution(action, taskId, data)), 0;
299
+ }
300
+ async function answerAsk(io, options, args) {
301
+ let agent = args[0], requestId = args[1], answer = args.slice(2).join(" ");
302
+ if (!agent || !requestId || !answer) throw new Error("Usage: adf answer <agent> <requestId> <answer>");
303
+ let data = await requestJson(io, options, `/agents/${enc(agent)}/asks/${enc(requestId)}/respond`, {
304
+ method: "POST",
305
+ headers: { "Content-Type": "application/json" },
306
+ body: JSON.stringify({ answer })
307
+ });
308
+ return io.stdout(options.json ? `${JSON.stringify(data, null, 2)}
309
+ ` : `Answered ${requestId}
310
+ `), 0;
311
+ }
312
+ async function controlAgent(io, options, args, action) {
313
+ let agent = args[0];
314
+ if (!agent) throw new Error(`Usage: adf ${action} <agent>`);
315
+ let data = await requestJson(io, options, `/agents/${enc(agent)}/${action}`, { method: "POST" });
316
+ return io.stdout(options.json ? `${JSON.stringify(data, null, 2)}
317
+ ` : formatAgentControl(action, agent, data)), 0;
318
+ }
319
+ function authDeps(io, options) {
320
+ return {
321
+ request: (method, path, body) => requestJson(io, options, path, body === void 0 ? { method } : { method, headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) }),
322
+ sleep: io.sleep,
323
+ openBrowser: io.openBrowser ?? openBrowser,
324
+ startCallbackServer: io.startCallbackServer
325
+ };
326
+ }
327
+ function requireAuthProvider(value) {
328
+ let provider = normalizeAuthProvider(value);
329
+ if (!provider) throw new Error("Specify a provider: chatgpt or grok");
330
+ return provider;
331
+ }
332
+ async function authCommand(io, options, args) {
333
+ let flags = new Set(args.filter((arg) => arg.startsWith("--"))), positional = args.filter((arg) => !arg.startsWith("--")), action = positional[0];
334
+ if (action === "status") return await printGet(io, options, "/runtime/auth", formatAuth);
335
+ if (action === "login")
336
+ return requireAuthProvider(positional[1]) === "chatgpt" ? await loginChatGptCli(io, options, flags) : await loginGrokCli(io, options);
337
+ if (action === "logout") {
338
+ let provider = requireAuthProvider(positional[1]), data = await requestJson(io, options, `/auth/${provider}/logout`, { method: "POST" });
339
+ return io.stdout(options.json ? `${JSON.stringify(data, null, 2)}
340
+ ` : `Signed out of ${AUTH_PROVIDER_LABELS[provider]}.
341
+ `), 0;
342
+ }
343
+ throw new Error("Usage: adf auth [status | login <chatgpt|grok> | logout <chatgpt|grok>]");
344
+ }
345
+ function reportAuth(io, provider, outcome) {
346
+ return outcome.ok ? (io.stdout(`Signed in to ${AUTH_PROVIDER_LABELS[provider]}${outcome.email ? ` as ${outcome.email}` : ""}.
347
+ `), 0) : outcome.timedOut ? (io.stderr(`Timed out waiting for ${AUTH_PROVIDER_LABELS[provider]} sign-in. Run "adf auth" to check status.
348
+ `), 1) : (io.stderr(`Sign-in failed: ${outcome.error}
349
+ `), 1);
350
+ }
351
+ async function loginChatGptCli(io, options, flags) {
352
+ let stop = new AbortController(), printedStart = !1, outcome = await loginChatGpt({ ...authDeps(io, options), signal: stop.signal }, {
353
+ daemonUrl: options.daemonUrl,
354
+ mode: flags.has("--relay") ? "relay" : flags.has("--loopback") ? "loopback" : "auto",
355
+ onStart: (info) => {
356
+ if (options.json) {
357
+ info.mode === "loopback" && (io.stdout(`${JSON.stringify(info.raw, null, 2)}
358
+ `), printedStart = !0, stop.abort());
359
+ return;
360
+ }
361
+ io.stdout(info.mode === "relay" ? `Open this URL to sign in to ChatGPT:
362
+
363
+ ${info.authUrl}
364
+
365
+ Waiting for the callback on ${info.redirectUri} ...
366
+ ` : `Open this URL to sign in to ChatGPT:
367
+
368
+ ${info.authUrl}
369
+
370
+ Waiting for sign-in to complete...
371
+ `);
372
+ }
373
+ });
374
+ return printedStart ? 0 : options.json && outcome.ok ? (io.stdout(`${JSON.stringify(outcome.raw, null, 2)}
375
+ `), 0) : reportAuth(io, "chatgpt", outcome);
376
+ }
377
+ async function loginGrokCli(io, options) {
378
+ let stop = new AbortController(), outcome = await loginGrok({ ...authDeps(io, options), signal: stop.signal }, {
379
+ onStart: (info) => {
380
+ if (options.json) {
381
+ io.stdout(`${JSON.stringify(info.raw, null, 2)}
382
+ `), stop.abort();
383
+ return;
384
+ }
385
+ io.stdout(`Open this URL to sign in to Grok:
386
+
387
+ ${info.verificationUri}
388
+
389
+ And enter the code: ${info.userCode}
390
+
391
+ Waiting for approval...
392
+ `);
393
+ }
394
+ });
395
+ return options.json ? 0 : reportAuth(io, "grok", outcome);
396
+ }
397
+ async function networkAdmin(io, options, args) {
398
+ let area = args[0], action = args[1];
399
+ if (area === "mesh") {
400
+ if (action === "enable" || action === "disable")
401
+ return await postAndPrint(io, options, `/network/mesh/${action}`, formatJsonPretty);
402
+ if (!action || action === "status") return await printGet(io, options, "/network/mesh", formatJsonPretty);
403
+ }
404
+ if (area === "server") {
405
+ if (action === "start" || action === "stop" || action === "restart")
406
+ return await postAndPrint(io, options, `/network/server/${action}`, formatJsonPretty);
407
+ if (!action || action === "status") return await printGet(io, options, "/network/server", formatJsonPretty);
408
+ }
409
+ if (area === "tools") return await printGet(io, options, "/network/mesh/recent-tools", formatJsonPretty);
410
+ if (area === "lan") return await printGet(io, options, "/network/mesh/lan-addresses", formatJsonPretty);
411
+ if (area === "runtimes") return await printGet(io, options, "/network/mesh/discovered-runtimes", formatJsonPretty);
412
+ throw new Error("Usage: adf network [mesh [status|enable|disable] | server [status|start|stop|restart] | tools | lan | runtimes]");
413
+ }
414
+ async function postAndPrint(io, options, path, formatter) {
415
+ let data = await requestJson(io, options, path, { method: "POST" });
416
+ return io.stdout(options.json ? `${JSON.stringify(data, null, 2)}
417
+ ` : formatter(data)), 0;
418
+ }
419
+ async function streamEvents(io, options, args) {
420
+ let agent = args[0], path = agent ? `/events?agentId=${enc(agent)}` : "/events", response = await io.fetch(`${options.daemonUrl}${path}`, {
421
+ headers: { Accept: "text/event-stream", ...authHeader(options) }
422
+ });
423
+ if (!response.ok || !response.body) {
424
+ let detail = await response.json().catch(() => null);
425
+ throw new Error(`Event stream failed: ${typeof detail?.error == "string" ? detail.error : `HTTP ${response.status} ${response.statusText}`}`);
426
+ }
427
+ let reader = response.body.getReader(), decoder = new TextDecoder(), buffer = "";
428
+ for (; ; ) {
429
+ let { value, done } = await reader.read();
430
+ if (done) break;
431
+ buffer += decoder.decode(value, { stream: !0 });
432
+ let parts = buffer.split(/\n\n/);
433
+ buffer = parts.pop() ?? "";
434
+ for (let part of parts) {
435
+ let dataLine = part.split(/\n/).find((line) => line.startsWith("data: "));
436
+ if (!dataLine) continue;
437
+ let payload = dataLine.slice(6);
438
+ if (options.json) io.stdout(`${payload}
439
+ `);
440
+ else
441
+ try {
442
+ io.stdout(`${formatEvent(JSON.parse(payload))}
443
+ `);
444
+ } catch {
445
+ io.stdout(`${payload}
446
+ `);
447
+ }
448
+ }
449
+ }
450
+ return 0;
451
+ }
452
+ async function withAgent(args, io, run) {
453
+ let agent = args[0];
454
+ return agent ? await run(agent) : (io.stderr(`Missing agent id or handle.
455
+ `), 2);
456
+ }
457
+ async function withAgentAndValue(args, label, io, run) {
458
+ let agent = args[0], value = args[1];
459
+ return !agent || !value ? (io.stderr(`Missing agent id/handle or ${label}.
460
+ `), 2) : await run(agent, value);
461
+ }
462
+ var pipedLines = null, pipedLineIndex = 0;
463
+ async function defaultPrompt(question, opts = {}) {
464
+ let { createInterface } = await import("readline");
465
+ if (!process.stdin.isTTY) {
466
+ if (pipedLines === null) {
467
+ let chunks = [];
468
+ for await (let chunk of process.stdin) chunks.push(Buffer.from(chunk));
469
+ pipedLines = Buffer.concat(chunks).toString("utf-8").split(/\r?\n/);
470
+ }
471
+ return pipedLines[pipedLineIndex++] ?? "";
472
+ }
473
+ let rl = createInterface({ input: process.stdin, output: process.stdout, terminal: !0, historySize: 0 }), internals = rl, muted = !1;
474
+ if (opts.hidden) {
475
+ let write = internals._writeToOutput.bind(rl);
476
+ internals._writeToOutput = (text) => {
477
+ muted || write(text);
478
+ };
479
+ }
480
+ try {
481
+ return await new Promise((resolve) => {
482
+ rl.question(question, resolve), muted = !!opts.hidden;
483
+ });
484
+ } finally {
485
+ rl.close(), opts.hidden && process.stdout.write(`
486
+ `);
487
+ }
488
+ }
489
+ function ask(io, question, hidden = !1) {
490
+ return (io.prompt ?? defaultPrompt)(question, { hidden });
491
+ }
492
+ function postJson(io, options, path, body = {}) {
493
+ return requestJson(io, options, path, {
494
+ method: "POST",
495
+ headers: { "Content-Type": "application/json" },
496
+ body: JSON.stringify(body)
497
+ });
498
+ }
499
+ async function passphraseIfNeeded(io, identity, confirmNew) {
500
+ if (!isRecord(identity) || identity.passphraseRequired !== !0) return;
501
+ io.stdout(`This machine has no usable OS keychain, so the owner identity is kept in a passphrase-protected file.
502
+ `);
503
+ let passphrase = await ask(io, confirmNew ? "Choose a passphrase (8+ characters): " : "Passphrase: ", !0);
504
+ if (confirmNew && await ask(io, "Repeat the passphrase: ", !0) !== passphrase)
505
+ throw new Error("The passphrases do not match.");
506
+ return passphrase;
507
+ }
508
+ async function identityCommand(io, options, args) {
509
+ let action = args[0] ?? "status";
510
+ if (action === "status") return await printGet(io, options, "/identity", formatIdentity);
511
+ if (action === "new" || action === "create") {
512
+ let current = await requestJson(io, options, "/identity");
513
+ if (isRecord(current) && current.status !== "none")
514
+ return io.stdout(formatIdentity(current)), io.stderr(`An owner identity already exists here; nothing was created.
515
+ `), 1;
516
+ let passphrase = await passphraseIfNeeded(io, current, !0), created = await postJson(io, options, "/identity/create", passphrase ? { passphrase } : {});
517
+ if (options.json)
518
+ return io.stdout(`${JSON.stringify(created, null, 2)}
519
+ `), 0;
520
+ let words = isRecord(created) && Array.isArray(created.words) ? created.words.map(String) : [], identity = isRecord(created) && isRecord(created.identity) ? created.identity : {};
521
+ io.stdout(
522
+ `Owner identity created: ${String(identity.ownerDid ?? "")}
523
+
524
+ Your seed phrase \u2014 write these 12 words down, in order, and keep them somewhere safe.
525
+ Anyone with this phrase can act as you; without it, your owner identity cannot be
526
+ recovered if this machine is lost. It will NOT be shown again.
527
+
528
+ ${formatWords(words)}
529
+
530
+ Use the same phrase in ADF Studio (Settings \u2192 Import Identity) or \`adf identity restore\`
531
+ on another machine to be the same owner there.
532
+
533
+ `
534
+ );
535
+ let answer = (await ask(io, 'Type "yes" once you have written the words down: ')).trim().toLowerCase();
536
+ return answer === "yes" || answer === "y" ? (await postJson(io, options, "/identity/confirm-backup"), io.stdout(`Backup confirmed.
537
+ `)) : io.stdout(`Backup not confirmed. The phrase cannot be shown again by the daemon; if you did not save it,
538
+ you can reveal it in ADF Studio on this machine (Settings \u2192 Back Up Seed Phrase).
539
+ `), 0;
540
+ }
541
+ if (action === "restore" || action === "import") {
542
+ let current = await requestJson(io, options, "/identity");
543
+ if (isRecord(current) && current.status === "ready")
544
+ return io.stdout(formatIdentity(current)), 0;
545
+ isRecord(current) && typeof current.ownerDid == "string" && current.ownerDid && io.stdout(`This machine's owner is ${current.ownerDid}; enter the seed phrase for that owner.
546
+ `);
547
+ let mnemonic = (await ask(io, "Seed phrase (12 words, input hidden): ", !0)).trim();
548
+ if (!mnemonic) throw new Error("No seed phrase entered.");
549
+ let passphrase = await passphraseIfNeeded(io, current, isRecord(current) && current.status !== "locked"), restored = await postJson(io, options, "/identity/restore", { mnemonic, ...passphrase ? { passphrase } : {} }), identity = isRecord(restored) && isRecord(restored.identity) ? restored.identity : restored;
550
+ return io.stdout(options.json ? `${JSON.stringify(restored, null, 2)}
551
+ ` : `Owner identity restored.
552
+ ${formatIdentity(identity)}`), 0;
553
+ }
554
+ if (action === "unlock") {
555
+ let passphrase = await ask(io, "Passphrase: ", !0), unlocked = await postJson(io, options, "/identity/unlock", { passphrase }), identity = isRecord(unlocked) && isRecord(unlocked.identity) ? unlocked.identity : unlocked;
556
+ return io.stdout(options.json ? `${JSON.stringify(unlocked, null, 2)}
557
+ ` : formatIdentity(identity)), 0;
558
+ }
559
+ if (action === "lock") {
560
+ let locked = await postJson(io, options, "/identity/lock"), identity = isRecord(locked) && isRecord(locked.identity) ? locked.identity : locked;
561
+ return io.stdout(options.json ? `${JSON.stringify(locked, null, 2)}
562
+ ` : formatIdentity(identity)), 0;
563
+ }
564
+ throw new Error("Usage: adf identity [status | new | restore | unlock | lock]");
565
+ }
566
+ async function newAgent(io, options, args) {
567
+ let body = {}, valueFlags = {
568
+ "--template": "template",
569
+ "-t": "template",
570
+ "--provider": "provider",
571
+ "--model": "model",
572
+ "--dir": "directory",
573
+ "--directory": "directory"
574
+ }, positional = [];
575
+ for (let i = 0; i < args.length; i++) {
576
+ let arg = args[i], eq = arg.indexOf("="), flag = arg.startsWith("--") && eq > 0 ? arg.slice(0, eq) : arg;
577
+ if (flag === "--start") {
578
+ body.start = !0;
579
+ continue;
580
+ }
581
+ let key = valueFlags[flag];
582
+ if (key) {
583
+ let value = eq > 0 && flag !== arg ? arg.slice(eq + 1) : args[++i];
584
+ if (!value) throw new Error(`${flag} requires a value`);
585
+ body[key] = value;
586
+ continue;
587
+ }
588
+ if (arg.startsWith("-")) throw new Error(`Unknown option for adf new: ${arg}`);
589
+ positional.push(arg);
590
+ }
591
+ positional.length > 0 && (body.name = positional.join(" "));
592
+ let created = await postJson(io, options, "/agents/create", body);
593
+ if (options.json)
594
+ return io.stdout(`${JSON.stringify(created, null, 2)}
595
+ `), 0;
596
+ let row = isRecord(created) ? created : {};
597
+ return io.stdout(table(["field", "value"], [
598
+ ["name", String(row.name ?? "")],
599
+ ["agentId", String(row.agentId ?? "")],
600
+ ["did", String(row.did ?? "")],
601
+ ["filePath", String(row.filePath ?? "")],
602
+ ["started", String(row.started ?? !1)]
603
+ ])), 0;
604
+ }
605
+ function formatWords(words) {
606
+ let cells = words.map((word, i) => `${String(i + 1).padStart(2)}. ${word}`.padEnd(16)), rows = [];
607
+ for (let i = 0; i < cells.length; i += 4) rows.push(` ${cells.slice(i, i + 4).join(" ").trimEnd()}`);
608
+ return rows.join(`
609
+ `);
610
+ }
611
+ function formatIdentity(value) {
612
+ return isRecord(value) ? `${table(["field", "value"], [
613
+ ["status", String(value.status ?? "")],
614
+ ["ownerDid", String(value.ownerDid ?? "")],
615
+ ["runtimeDid", String(value.runtimeDid ?? "")],
616
+ ["storage", String(value.storage ?? "")],
617
+ ["backupConfirmed", String(value.backupConfirmed ?? !1)]
618
+ ])}${typeof value.message == "string" ? `${value.message}
619
+ ` : ""}` : formatJsonPretty(value);
620
+ }
621
+ function formatTemplates(value) {
622
+ let templates = isRecord(value) && Array.isArray(value.templates) ? value.templates.filter(isRecord) : [];
623
+ if (templates.length === 0) return `No templates.
624
+ `;
625
+ let defaultId = isRecord(value) ? String(value.defaultId ?? "") : "";
626
+ return table(["id", "name", "default", "model", "about"], templates.map((t) => [
627
+ String(t.id ?? ""),
628
+ String(t.name ?? ""),
629
+ t.id === defaultId ? "yes" : "",
630
+ [t.modelProvider, t.modelId].filter(Boolean).map(String).join("/"),
631
+ truncate(String(t.templateDescription ?? t.description ?? ""), 60)
632
+ ]));
633
+ }
634
+ function formatAgents(value) {
635
+ let rows = Array.isArray(value) ? value.filter(isRecord) : [];
636
+ return rows.length === 0 ? `No agents loaded.
637
+ ` : table(["id", "handle", "name", "autostart"], rows.map((row) => [
638
+ String(row.id ?? ""),
639
+ String(row.handle ?? ""),
640
+ String(row.name ?? ""),
641
+ String(row.autostart ?? !1)
642
+ ]));
643
+ }
644
+ function formatStatus(value) {
645
+ return isRecord(value) ? table(["field", "value"], [
646
+ ["id", String(value.id ?? "")],
647
+ ["handle", String(value.handle ?? "")],
648
+ ["name", String(value.name ?? "")],
649
+ ["runtimeState", String(value.runtimeState ?? "")],
650
+ ["targetState", String(value.targetState ?? "")],
651
+ ["loopCount", String(value.loopCount ?? "")],
652
+ ["filePath", String(value.filePath ?? "")]
653
+ ]) : formatJsonPretty(value);
654
+ }
655
+ function formatFiles(value) {
656
+ let files = isRecord(value) && Array.isArray(value.files) ? value.files.filter(isRecord) : [];
657
+ return files.length === 0 ? `No files.
658
+ ` : table(["path", "size", "mime", "protection"], files.map((file) => [
659
+ String(file.path ?? ""),
660
+ String(file.size ?? ""),
661
+ String(file.mime_type ?? ""),
662
+ String(file.protection ?? "")
663
+ ]));
664
+ }
665
+ function formatProviders(value) {
666
+ if (!isRecord(value)) return formatJsonPretty(value);
667
+ let providers = Array.isArray(value.providers) ? value.providers.filter(isRecord) : [], usage2 = Array.isArray(value.agentUsage) ? value.agentUsage.filter(isRecord) : [], providerTable = providers.length === 0 ? `Providers: none
668
+ ` : `Providers:
669
+ ${table(["id", "type", "name", "model", "key"], providers.map((provider) => [
670
+ String(provider.id ?? ""),
671
+ String(provider.type ?? ""),
672
+ String(provider.name ?? ""),
673
+ String(provider.defaultModel ?? ""),
674
+ String(provider.hasApiKey ?? !1)
675
+ ]))}`, usageTable = usage2.length === 0 ? `Agent usage: none
676
+ ` : `Agent usage:
677
+ ${table(["agent", "provider", "model", "source"], usage2.map((row) => [
678
+ String(row.handle ?? row.agentId ?? ""),
679
+ String(row.providerId ?? ""),
680
+ String(row.modelId ?? ""),
681
+ String(row.source ?? "")
682
+ ]))}`;
683
+ return `${providerTable}
684
+ ${usageTable}`;
685
+ }
686
+ function formatAuth(value) {
687
+ if (!isRecord(value)) return formatJsonPretty(value);
688
+ let chatgpt = isRecord(value.chatgpt) ? value.chatgpt : {}, grok = isRecord(value.grok) ? value.grok : {}, providers = Array.isArray(value.providers) ? value.providers.filter(isRecord) : [], chatgptTable = `ChatGPT:
689
+ ${table(["field", "value"], [
690
+ ["authenticated", String(chatgpt.authenticated ?? !1)],
691
+ ["email", String(chatgpt.email ?? "")]
692
+ ])}`, grokTable = `Grok:
693
+ ${table(["field", "value"], [
694
+ ["authenticated", String(grok.authenticated ?? !1)],
695
+ ["email", String(grok.email ?? "")]
696
+ ])}`, providersTable = providers.length === 0 ? `Provider credentials: none
697
+ ` : `Provider credentials:
698
+ ${table(["id", "type", "storage", "apiKey"], providers.map((provider) => [
699
+ String(provider.id ?? ""),
700
+ String(provider.type ?? ""),
701
+ String(provider.credentialStorage ?? ""),
702
+ String(provider.hasApiKey ?? !1)
703
+ ]))}`;
704
+ return `${chatgptTable}
705
+ ${grokTable}
706
+ ${providersTable}`;
707
+ }
708
+ function formatNetwork(value) {
709
+ if (!isRecord(value)) return formatJsonPretty(value);
710
+ let mesh = isRecord(value.mesh) ? value.mesh : {}, websocket = isRecord(value.websocket) ? value.websocket : {}, agents = Array.isArray(value.agents) ? value.agents.filter(isRecord) : [], summary = table(["field", "value"], [
711
+ ["meshEnabledSetting", String(mesh.enabledSetting ?? "")],
712
+ ["meshLan", String(mesh.lan ?? "")],
713
+ ["meshPort", String(mesh.port ?? "")],
714
+ ["wsActive", String(websocket.activeConnections ?? 0)],
715
+ ["wsInbound", String(websocket.inboundConnections ?? 0)],
716
+ ["wsOutbound", String(websocket.outboundConnections ?? 0)]
717
+ ]), agentTable = agents.length === 0 ? `Network agents: none
718
+ ` : `Network agents:
719
+ ${table(["agent", "receive", "mode", "ws", "routes"], agents.map((agent) => [
720
+ String(agent.handle ?? agent.agentId ?? ""),
721
+ String(agent.receive ?? !1),
722
+ String(agent.sendMode ?? ""),
723
+ String(agent.wsConnectionsConfigured ?? 0),
724
+ String(agent.servingRoutes ?? 0)
725
+ ]))}`;
726
+ return `${summary}
727
+ ${agentTable}`;
728
+ }
729
+ function formatUsage(value) {
730
+ if (!isRecord(value)) return formatJsonPretty(value);
731
+ let totals = isRecord(value.totals) ? value.totals : {}, summaryRows = [
732
+ ["source", String(value.source ?? "")],
733
+ ["input", formatNumber(totals.input)],
734
+ ["output", formatNumber(totals.output)],
735
+ ["cacheRead", formatNumber(totals.cacheRead)],
736
+ ["cacheWrite", formatNumber(totals.cacheWrite)],
737
+ ["total", formatNumber(totals.total)]
738
+ ];
739
+ value.agentId && summaryRows.unshift(["agentId", String(value.agentId)]), typeof value.loopRows == "number" && summaryRows.push(["loopRows", formatNumber(value.loopRows)]), typeof value.usageRows == "number" && summaryRows.push(["usageRows", formatNumber(value.usageRows)]);
740
+ let rows = Array.isArray(value.byModel) ? value.byModel.filter(isRecord).map((row) => [
741
+ String(row.provider ?? ""),
742
+ String(row.model ?? ""),
743
+ formatNumber(row.input),
744
+ formatNumber(row.output),
745
+ formatNumber(row.cacheRead),
746
+ formatNumber(row.cacheWrite),
747
+ formatNumber(row.total),
748
+ formatNumber(row.rows ?? row.days)
749
+ ]) : [], modelTable = rows.length === 0 ? `Models: none
750
+ ` : `Models:
751
+ ${table(["provider", "model", "input", "output", "cacheRead", "cacheWrite", "total", "rows/days"], rows)}`;
752
+ return `${table(["field", "value"], summaryRows)}
753
+ ${modelTable}`;
754
+ }
755
+ function formatMessages(label) {
756
+ return (value) => {
757
+ let messages = isRecord(value) && Array.isArray(value.messages) ? value.messages.filter(isRecord) : [];
758
+ return messages.length === 0 ? `No ${label} messages.
759
+ ` : table(["id", "status", label === "inbox" ? "from" : "to", "content"], messages.map((message) => [
760
+ String(message.id ?? ""),
761
+ String(message.status ?? ""),
762
+ String(label === "inbox" ? message.from ?? "" : message.to ?? ""),
763
+ truncate(String(message.content ?? ""), 80)
764
+ ]));
765
+ };
766
+ }
767
+ function formatTimers(value) {
768
+ let timers = isRecord(value) && Array.isArray(value.timers) ? value.timers.filter(isRecord) : [];
769
+ return timers.length === 0 ? `No timers.
770
+ ` : table(["id", "next_wake_at", "runs", "payload"], timers.map((timer) => [
771
+ String(timer.id ?? ""),
772
+ typeof timer.next_wake_at == "number" ? new Date(timer.next_wake_at).toISOString() : String(timer.next_wake_at ?? ""),
773
+ String(timer.run_count ?? ""),
774
+ truncate(String(timer.payload ?? ""), 80)
775
+ ]));
776
+ }
777
+ function formatTasks(value) {
778
+ let tasks = isRecord(value) && Array.isArray(value.tasks) ? value.tasks.filter(isRecord) : [];
779
+ return tasks.length === 0 ? `No tasks.
780
+ ` : table(["id", "status", "tool", "origin", "auth"], tasks.map((task) => [
781
+ String(task.id ?? ""),
782
+ String(task.status ?? ""),
783
+ String(task.tool ?? ""),
784
+ truncate(String(task.origin ?? ""), 32),
785
+ String(task.requires_authorization ?? !1)
786
+ ]));
787
+ }
788
+ function formatAsks(value) {
789
+ let asks = isRecord(value) && Array.isArray(value.asks) ? value.asks.filter(isRecord) : [];
790
+ return asks.length === 0 ? `No pending asks.
791
+ ` : table(["requestId", "question"], asks.map((ask2) => [
792
+ String(ask2.requestId ?? ""),
793
+ truncate(String(ask2.question ?? ""), 100)
794
+ ]));
795
+ }
796
+ function formatIdentities(value) {
797
+ let identities = isRecord(value) && Array.isArray(value.identities) ? value.identities.filter(isRecord) : [];
798
+ return identities.length === 0 ? `No identities.
799
+ ` : table(["purpose", "encrypted", "code_access"], identities.map((identity) => [
800
+ String(identity.purpose ?? ""),
801
+ String(identity.encrypted ?? !1),
802
+ String(identity.code_access ?? !1)
803
+ ]));
804
+ }
805
+ function formatMcp(value) {
806
+ if (!isRecord(value)) return formatJsonPretty(value);
807
+ let configured = Array.isArray(value.configured) ? value.configured.filter(isRecord) : [], states = Array.isArray(value.states) ? value.states.filter(isRecord) : [], configuredTable = configured.length === 0 ? `Configured MCP: none
808
+ ` : `Configured MCP:
809
+ ${table(["name", "transport", "tools"], configured.map((server) => [
810
+ String(server.name ?? ""),
811
+ String(server.transport ?? ""),
812
+ String(server.toolCount ?? "")
813
+ ]))}`, stateTable = states.length === 0 ? `Runtime MCP: none
814
+ ` : `Runtime MCP:
815
+ ${table(["name", "status", "tools", "error"], states.map((state) => [
816
+ String(state.name ?? ""),
817
+ String(state.status ?? ""),
818
+ String(state.toolCount ?? ""),
819
+ truncate(String(state.error ?? ""), 80)
820
+ ]))}`;
821
+ return `${configuredTable}
822
+ ${stateTable}`;
823
+ }
824
+ function formatGlobalMcp(value) {
825
+ let servers = isRecord(value) && Array.isArray(value.servers) ? value.servers.filter(isRecord) : [];
826
+ return servers.length === 0 ? `No daemon MCP servers registered.
827
+ ` : table(["id", "name", "type", "package", "storage", "env"], servers.map((server) => [
828
+ String(server.id ?? ""),
829
+ String(server.name ?? ""),
830
+ String(server.type ?? ""),
831
+ String(server.npmPackage ?? server.pypiPackage ?? server.command ?? server.url ?? ""),
832
+ String(server.credentialStorage ?? ""),
833
+ Array.isArray(server.env) ? String(server.env.length) : "0"
834
+ ]));
835
+ }
836
+ function formatAdapters(value) {
837
+ if (!isRecord(value)) return formatJsonPretty(value);
838
+ let configured = Array.isArray(value.configured) ? value.configured.filter(isRecord) : [], states = Array.isArray(value.states) ? value.states.filter(isRecord) : [], configuredTable = configured.length === 0 ? `Configured adapters: none
839
+ ` : `Configured adapters:
840
+ ${table(["type", "enabled"], configured.map((adapter) => [
841
+ String(adapter.type ?? ""),
842
+ String(adapter.enabled ?? !1)
843
+ ]))}`, stateTable = states.length === 0 ? `Runtime adapters: none
844
+ ` : `Runtime adapters:
845
+ ${table(["type", "status", "error"], states.map((state) => [
846
+ String(state.type ?? ""),
847
+ String(state.status ?? ""),
848
+ truncate(String(state.error ?? ""), 80)
849
+ ]))}`;
850
+ return `${configuredTable}
851
+ ${stateTable}`;
852
+ }
853
+ function formatGlobalAdapters(value) {
854
+ let adapters = isRecord(value) && Array.isArray(value.adapters) ? value.adapters.filter(isRecord) : [];
855
+ return adapters.length === 0 ? `No daemon adapters registered.
856
+ ` : table(["id", "type", "package"], adapters.map((adapter) => [
857
+ String(adapter.id ?? ""),
858
+ String(adapter.type ?? ""),
859
+ String(adapter.npmPackage ?? "")
860
+ ]));
861
+ }
862
+ function formatChatAck(value) {
863
+ return isRecord(value) ? value.accepted ? `Accepted turn ${String(value.turnId ?? "")}
864
+ ` : `${JSON.stringify(value, null, 2)}
865
+ ` : formatJsonPretty(value);
866
+ }
867
+ function formatAgentControl(action, agent, value) {
868
+ if (!isRecord(value)) return formatJsonPretty(value);
869
+ if (value.success !== !0) return `${JSON.stringify(value, null, 2)}
870
+ `;
871
+ if (action === "start") {
872
+ let details = [
873
+ value.loaded === !0 ? "loaded" : "",
874
+ value.startupTriggered === !1 ? "no startup trigger fired" : ""
875
+ ].filter(Boolean);
876
+ return `Started ${agent}${details.length > 0 ? ` (${details.join(", ")})` : ""}
877
+ `;
878
+ }
879
+ return action === "abort" ? `Aborted current turn for ${agent}
880
+ ` : `Stopped ${agent}
881
+ `;
882
+ }
883
+ function formatTaskResolution(action, taskId, value) {
884
+ if (!isRecord(value)) return formatJsonPretty(value);
885
+ let task = isRecord(value.task) ? value.task : {}, status = typeof task.status == "string" ? task.status : action === "approve" ? "approved" : "denied";
886
+ return `${action === "approve" ? "Approved" : "Denied"} ${taskId} (${status})
887
+ `;
888
+ }
889
+ function formatEvent(value) {
890
+ if (!isRecord(value)) return JSON.stringify(value);
891
+ let envelope = isRecord(value.event) ? value.event : value, cursor = value.cursor ?? envelope.seq, seq = String(cursor ?? ""), type = String(envelope.event_type ?? ""), agent = envelope.agent_id ? ` ${String(envelope.agent_id)}` : "", payload = isRecord(envelope.payload) ? envelope.payload : {}, detail = typeof payload.message == "string" ? payload.message : typeof payload.type == "string" ? payload.type : "";
892
+ return `[${seq}] ${type}${agent}${detail ? ` ${detail}` : ""}`;
893
+ }
894
+ function formatJsonPretty(value) {
895
+ return `${JSON.stringify(value, null, 2)}
896
+ `;
897
+ }
898
+ function table(headers, rows) {
899
+ let widths = headers.map((header, i) => Math.max(header.length, ...rows.map((row) => (row[i] ?? "").length))), renderRow = (row) => row.map((cell, i) => cell.padEnd(widths[i])).join(" ");
900
+ return `${renderRow(headers)}
901
+ ${widths.map((width) => "-".repeat(width)).join(" ")}
902
+ ${rows.map(renderRow).join(`
903
+ `)}
904
+ `;
905
+ }
906
+ function truncate(value, max) {
907
+ return value.length <= max ? value : `${value.slice(0, max - 3)}...`;
908
+ }
909
+ function formatNumber(value) {
910
+ return typeof value == "number" && Number.isFinite(value) ? value.toLocaleString() : "";
911
+ }
912
+ function enc(value) {
913
+ return encodeURIComponent(value);
914
+ }
915
+ function isRecord(value) {
916
+ return !!value && typeof value == "object" && !Array.isArray(value);
917
+ }
918
+ function usage() {
919
+ return `ADF CLI: run and talk to your ADF agents from a terminal.
920
+
921
+ Usage: adf [--url <daemon-url>] [--json] <command>
922
+ adf [tui] [--view <id>] [--agent <id>] [--loop <name>]
923
+ adf daemon [start|status|stop|restart|logs]
924
+
925
+ With no command, adf opens the terminal app (see \`adf tui --help\`).
926
+ When the daemon URL is on this machine and nothing answers there, adf
927
+ starts the daemon in the background first (--no-daemon or
928
+ ADF_NO_AUTOSTART=1 turn that off). Quitting leaves it running.
929
+
930
+ Commands:
931
+ tui The terminal app (the default)
932
+ agents List loaded agents
933
+ status <agent> Show runtime status
934
+ start <agent> Start an agent and fire startup when applicable
935
+ stop <agent> Stop and unload an agent
936
+ unload <agent> Alias for stop
937
+ loops <agent> List the agent's loops: main plus its inner
938
+ (side) loops, parallel threads with their own
939
+ history, e.g. a memory consolidator on a timer
940
+ interrupt <agent> [--loop <name>]
941
+ End the running turn; the loop goes idle and
942
+ keeps accepting chats, timers and triggers
943
+ abort <agent> [--loop <name>] Hard-abort the current turn without unloading;
944
+ that loop stays stopped until the agent is
945
+ reloaded (prefer interrupt)
946
+ runtime [agent] Show daemon or agent runtime diagnostics
947
+ providers Show provider configuration and agent resolution
948
+ auth Show auth and credential presence
949
+ auth login <chatgpt|grok> Sign in to a subscription provider
950
+ [--relay|--loopback] chooses where the
951
+ ChatGPT OAuth callback is served; defaults to
952
+ relay when --url points at a remote daemon
953
+ auth logout <chatgpt|grok> Clear a subscription provider's tokens
954
+ settings Show sanitized daemon runtime settings
955
+ network Show mesh and WebSocket diagnostics
956
+ network mesh [enable|disable] Control daemon mesh registration
957
+ network server [start|stop|restart]
958
+ Control the mesh HTTP server
959
+ network tools|lan|runtimes Show mesh tools, LAN addresses, or peers
960
+ usage [agent] Show runtime or agent token usage
961
+ config <agent> Show agent config
962
+ files <agent> List agent files
963
+ file <agent> <path> Print one agent file
964
+ inbox <agent> List inbox messages
965
+ outbox <agent> List outbox messages
966
+ timers <agent> List timers
967
+ tasks <agent> List tasks and pending approvals
968
+ task <agent> <taskId> Show one task
969
+ approve <agent> <taskId> Approve a pending task
970
+ deny <agent> <taskId> [reason] Deny a pending task
971
+ asks <agent> List pending ask requests
972
+ answer <agent> <requestId> <answer>
973
+ Answer a pending ask request
974
+ identities <agent> List identity metadata without secret values
975
+ mcp [agent] Show daemon MCP registrations or agent MCP state
976
+ adapters [agent] Show daemon adapter registrations or agent adapter state
977
+ events [agent] Follow daemon SSE events
978
+ chat <agent> [--loop <name>] <message>
979
+ Send chat (to main, or an inner loop) and
980
+ print the accepted turn id
981
+ identity Show the owner identity status
982
+ identity new Create an owner identity; shows the 12-word
983
+ seed phrase once \u2014 write it down
984
+ identity restore Restore the owner identity from its seed
985
+ phrase (typed at a hidden prompt; the same
986
+ phrase as ADF Studio = the same owner)
987
+ identity unlock|lock Unlock/lock a passphrase-protected identity
988
+ (machines without an OS keychain)
989
+ templates List agent templates
990
+ new [name] [--template <id>] [--provider <id>] [--model <id>]
991
+ [--dir <path>] [--start] Create an agent from a template, sealed
992
+ with the owner identity (like Studio)
993
+
994
+ Daemon:
995
+ daemon [--port <n>] [--host <h>] [--settings <file>]
996
+ Run the daemon in the foreground (Ctrl+C
997
+ stops it; also ADF_DAEMON_PORT,
998
+ ADF_DAEMON_HOST, ADF_DAEMON_SETTINGS,
999
+ ADF_USER_DATA_DIR)
1000
+ daemon start [--port <n>] [--force]
1001
+ Start it in the background (what adf does
1002
+ on its own); --force skips the ADF Studio
1003
+ check
1004
+ daemon status Is it running: pid, uptime, version, log file
1005
+ daemon stop Stop it gracefully (agents unloaded,
1006
+ containers stopped)
1007
+ daemon restart Stop, then start in the background
1008
+ daemon logs [-f] [-n <lines>] Show the background daemon's log (-f follows)
1009
+ daemon token Print this machine's daemon access token (for
1010
+ clients on other machines: --token or
1011
+ ADF_DAEMON_TOKEN)
1012
+
1013
+ Options:
1014
+ --url, -u <url> Daemon URL
1015
+ --token <token> Daemon access token (default: ADF_DAEMON_TOKEN,
1016
+ else read automatically on the daemon's machine)
1017
+ --json JSON output
1018
+ --no-daemon Never start the daemon automatically
1019
+ --version, -v Print the version
1020
+
1021
+ Environment:
1022
+ ADF_DAEMON_URL Defaults to ${DEFAULT_DAEMON_URL}
1023
+ ADF_DAEMON_TOKEN Daemon access token (overrides the local
1024
+ <data dir>/daemon-token file)
1025
+ ADF_NO_AUTOSTART=1 Same as --no-daemon`;
1026
+ }
1027
+ export {
1028
+ runCli,
1029
+ tuiInvocation
1030
+ };