@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.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/adf.mjs +162 -0
- package/dist/chunks/APEv2Parser-2CNNHMXV.mjs +22 -0
- package/dist/chunks/AiffParser-7BR4RL6G.mjs +162 -0
- package/dist/chunks/App-L5L37JI5.mjs +16747 -0
- package/dist/chunks/AsfParser-VVRSLFOM.mjs +538 -0
- package/dist/chunks/DsdiffParser-CMD4AX7A.mjs +156 -0
- package/dist/chunks/DsfParser-UOGZDS2M.mjs +94 -0
- package/dist/chunks/FlacParser-HB3T3CD4.mjs +23 -0
- package/dist/chunks/MP4Parser-66HBRUSX.mjs +973 -0
- package/dist/chunks/MatroskaParser-J3HUIMEW.mjs +579 -0
- package/dist/chunks/MpegParser-YW6LIUEW.mjs +442 -0
- package/dist/chunks/MusepackParser-PAUSXP7D.mjs +252 -0
- package/dist/chunks/OggParser-NUBV3GWC.mjs +359 -0
- package/dist/chunks/WavPackParser-WQAGT7TC.mjs +171 -0
- package/dist/chunks/WaveParser-EWLQVDX4.mjs +238 -0
- package/dist/chunks/adf-schema-JRU2BTOG.mjs +62 -0
- package/dist/chunks/build-QF5W473T.mjs +60 -0
- package/dist/chunks/chatgpt-subscription-BQGWYZXE.mjs +23 -0
- package/dist/chunks/chunk-2DIECGFL.mjs +6 -0
- package/dist/chunks/chunk-2NAP2ZF7.mjs +60 -0
- package/dist/chunks/chunk-3AT7IIP7.mjs +25696 -0
- package/dist/chunks/chunk-3GNIDM53.mjs +35 -0
- package/dist/chunks/chunk-3M4ZPOA3.mjs +1477 -0
- package/dist/chunks/chunk-4MQPTCXY.mjs +510 -0
- package/dist/chunks/chunk-5PO5PKRV.mjs +366 -0
- package/dist/chunks/chunk-5QU5VY7N.mjs +52 -0
- package/dist/chunks/chunk-5W7KES6P.mjs +436 -0
- package/dist/chunks/chunk-62NE4LG4.mjs +61 -0
- package/dist/chunks/chunk-64OKE4X3.mjs +45 -0
- package/dist/chunks/chunk-6GJ4QHRI.mjs +1278 -0
- package/dist/chunks/chunk-6VQEXLE2.mjs +144 -0
- package/dist/chunks/chunk-6XUV6EK6.mjs +41 -0
- package/dist/chunks/chunk-776TSXEP.mjs +43 -0
- package/dist/chunks/chunk-7CV2SA3H.mjs +285 -0
- package/dist/chunks/chunk-7MTRVW2U.mjs +3103 -0
- package/dist/chunks/chunk-7N2R2VCG.mjs +1434 -0
- package/dist/chunks/chunk-7T2YMTWL.mjs +374 -0
- package/dist/chunks/chunk-7XYNI52E.mjs +149 -0
- package/dist/chunks/chunk-APHX6HSV.mjs +7731 -0
- package/dist/chunks/chunk-APRU6PHC.mjs +40 -0
- package/dist/chunks/chunk-AUYKRQPJ.mjs +499 -0
- package/dist/chunks/chunk-DXWDD5XJ.mjs +136 -0
- package/dist/chunks/chunk-EWL5FG4I.mjs +39 -0
- package/dist/chunks/chunk-EYX2YLJW.mjs +117 -0
- package/dist/chunks/chunk-F5ELW46V.mjs +27 -0
- package/dist/chunks/chunk-G426FACA.mjs +49 -0
- package/dist/chunks/chunk-GEKSJHIV.mjs +2472 -0
- package/dist/chunks/chunk-HBUENVQL.mjs +570 -0
- package/dist/chunks/chunk-HPVFJYXR.mjs +112 -0
- package/dist/chunks/chunk-HWLWPXQ7.mjs +721 -0
- package/dist/chunks/chunk-I2HJYHFT.mjs +665 -0
- package/dist/chunks/chunk-I3UYSITV.mjs +68 -0
- package/dist/chunks/chunk-IC4JDZCI.mjs +3864 -0
- package/dist/chunks/chunk-IHDDCZBS.mjs +112 -0
- package/dist/chunks/chunk-IIGMZHQQ.mjs +10416 -0
- package/dist/chunks/chunk-KWFOS5WC.mjs +41 -0
- package/dist/chunks/chunk-LAZIXV2F.mjs +5290 -0
- package/dist/chunks/chunk-LFMB4PAA.mjs +10814 -0
- package/dist/chunks/chunk-M2RX3S2T.mjs +49 -0
- package/dist/chunks/chunk-M3WPIJYM.mjs +65 -0
- package/dist/chunks/chunk-NBTUWMGP.mjs +263 -0
- package/dist/chunks/chunk-NGK6PVSF.mjs +2676 -0
- package/dist/chunks/chunk-NZ7JTHEO.mjs +85 -0
- package/dist/chunks/chunk-OQN33RGQ.mjs +52 -0
- package/dist/chunks/chunk-RIX34QHC.mjs +2935 -0
- package/dist/chunks/chunk-SGUTYISF.mjs +16 -0
- package/dist/chunks/chunk-SLJ5L7PY.mjs +1473 -0
- package/dist/chunks/chunk-SLUKGXKH.mjs +68 -0
- package/dist/chunks/chunk-TMT32MXT.mjs +419 -0
- package/dist/chunks/chunk-UYY5M2PB.mjs +151 -0
- package/dist/chunks/chunk-VAUOM3IN.mjs +298 -0
- package/dist/chunks/chunk-VMHTYDH4.mjs +172 -0
- package/dist/chunks/chunk-VZS54AA5.mjs +200 -0
- package/dist/chunks/chunk-WFQUVXML.mjs +295 -0
- package/dist/chunks/chunk-X34PDRUH.mjs +809 -0
- package/dist/chunks/chunk-XNPZBLYL.mjs +33 -0
- package/dist/chunks/chunk-XX7OSWTO.mjs +157 -0
- package/dist/chunks/chunk-XYTWGHFS.mjs +600 -0
- package/dist/chunks/chunk-XYV3VCIX.mjs +336 -0
- package/dist/chunks/chunk-Y5ZLKFLE.mjs +1469 -0
- package/dist/chunks/chunk-ZJKXHM4Q.mjs +230 -0
- package/dist/chunks/cli-TCMBNZF6.mjs +1030 -0
- package/dist/chunks/commands-DTEKM4ZL.mjs +20 -0
- package/dist/chunks/daemon-ZC3FZ2P4.mjs +112449 -0
- package/dist/chunks/daemon-control-WDX7PMTC.mjs +300 -0
- package/dist/chunks/daemon-token-WRSULP7G.mjs +23 -0
- package/dist/chunks/devtools-H7CI2ZVG.mjs +85 -0
- package/dist/chunks/discord-IWDQJA7A.mjs +70588 -0
- package/dist/chunks/dist-C57KYFS2.mjs +4952 -0
- package/dist/chunks/dist-I3XBAGDL.mjs +11 -0
- package/dist/chunks/email-V4Q4VJON.mjs +58679 -0
- package/dist/chunks/environment-NX277MQG.mjs +15 -0
- package/dist/chunks/grok-subscription-4PYX7TBF.mjs +19 -0
- package/dist/chunks/layout-EPJQNFAI.mjs +22 -0
- package/dist/chunks/lib-N7FCZWKH.mjs +4038 -0
- package/dist/chunks/open-OTQDGDH5.mjs +36 -0
- package/dist/chunks/parser-JVY2PWSM.mjs +19 -0
- package/dist/chunks/pipeline-executor-BHBSJX2K.mjs +19 -0
- package/dist/chunks/react-IUIDQ5LX.mjs +11 -0
- package/dist/chunks/screen-54BUTYCW.mjs +27 -0
- package/dist/chunks/slack-3L5QTDZX.mjs +8113 -0
- package/dist/chunks/store-WR7TZJZS.mjs +32 -0
- package/dist/chunks/telegram-5ISVFBV3.mjs +14918 -0
- package/dist/chunks/terminal-O5WO7C5U.mjs +48 -0
- package/dist/chunks/theme-NORU4J74.mjs +20 -0
- package/dist/chunks/themes-F2FKU7CP.mjs +23 -0
- package/dist/chunks/token-6G3HCMNX.mjs +54 -0
- package/dist/chunks/token-util-UXYSDQIW.mjs +12 -0
- package/dist/chunks/tui-ODVYUIMT.mjs +197 -0
- package/dist/chunks/welcome-XHXFV7SH.mjs +32 -0
- package/dist/chunks/whatsapp-XSAMNGPJ.mjs +85412 -0
- package/dist/chunks/xterm-headless-YF53XWXE.mjs +3353 -0
- package/package.json +53 -0
- package/resources/wasm/coreutils.LICENSE +18 -0
- 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
|
+
};
|