@holon-run/agentinbox 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +178 -0
- package/README.md +168 -0
- package/dist/src/adapters.js +111 -0
- package/dist/src/backend.js +175 -0
- package/dist/src/cli.js +620 -0
- package/dist/src/client.js +279 -0
- package/dist/src/control_server.js +93 -0
- package/dist/src/daemon.js +246 -0
- package/dist/src/filter.js +167 -0
- package/dist/src/http.js +408 -0
- package/dist/src/matcher.js +47 -0
- package/dist/src/model.js +2 -0
- package/dist/src/paths.js +141 -0
- package/dist/src/service.js +1338 -0
- package/dist/src/source_schema.js +150 -0
- package/dist/src/sources/feishu.js +567 -0
- package/dist/src/sources/github.js +485 -0
- package/dist/src/sources/github_ci.js +372 -0
- package/dist/src/store.js +1271 -0
- package/dist/src/terminal.js +301 -0
- package/dist/src/util.js +36 -0
- package/package.json +52 -0
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const adapters_1 = require("./adapters");
|
|
10
|
+
const client_1 = require("./client");
|
|
11
|
+
const control_server_1 = require("./control_server");
|
|
12
|
+
const daemon_1 = require("./daemon");
|
|
13
|
+
const http_1 = require("./http");
|
|
14
|
+
const paths_1 = require("./paths");
|
|
15
|
+
const service_1 = require("./service");
|
|
16
|
+
const store_1 = require("./store");
|
|
17
|
+
const terminal_1 = require("./terminal");
|
|
18
|
+
const util_1 = require("./util");
|
|
19
|
+
async function main() {
|
|
20
|
+
const args = process.argv.slice(2);
|
|
21
|
+
const normalized = normalizeHelpArgs(args);
|
|
22
|
+
const command = normalized[0];
|
|
23
|
+
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
24
|
+
printHelp(normalized.slice(1));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (command === "version" || command === "--version" || command === "-v") {
|
|
28
|
+
if (hasHelpFlag(normalized.slice(1))) {
|
|
29
|
+
printHelp(["version"]);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
printVersion();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (command === "serve") {
|
|
36
|
+
if (hasHelpFlag(normalized.slice(1))) {
|
|
37
|
+
printHelp(["serve"]);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
await runServe(normalized.slice(1));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (command === "daemon") {
|
|
44
|
+
if (hasHelpFlag(normalized.slice(1))) {
|
|
45
|
+
printHelp(["daemon"]);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
await runDaemon(normalized.slice(1));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const client = await createClient(normalized);
|
|
52
|
+
if (command === "source" && normalized[1] === "add") {
|
|
53
|
+
const [type, sourceKey] = normalized.slice(2, 4);
|
|
54
|
+
if (!type || !sourceKey) {
|
|
55
|
+
throw new Error("usage: agentinbox source add <type> <sourceKey> [--config-json JSON] [--config-ref REF]");
|
|
56
|
+
}
|
|
57
|
+
await printRemote(client, "/sources/register", {
|
|
58
|
+
sourceType: type,
|
|
59
|
+
sourceKey,
|
|
60
|
+
configRef: takeFlagValue(normalized, "--config-ref") ?? null,
|
|
61
|
+
config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
|
|
62
|
+
});
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (command === "source" && normalized[1] === "list") {
|
|
66
|
+
await printRemote(client, "/sources", undefined, "GET");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (command === "source" && normalized[1] === "show") {
|
|
70
|
+
const sourceId = normalized[2];
|
|
71
|
+
if (!sourceId) {
|
|
72
|
+
throw new Error("usage: agentinbox source show <sourceId>");
|
|
73
|
+
}
|
|
74
|
+
await printRemote(client, `/sources/${encodeURIComponent(sourceId)}`, undefined, "GET");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (command === "source" && normalized[1] === "schema") {
|
|
78
|
+
const sourceType = normalized[2];
|
|
79
|
+
if (!sourceType) {
|
|
80
|
+
throw new Error("usage: agentinbox source schema <sourceType>");
|
|
81
|
+
}
|
|
82
|
+
await printRemote(client, `/source-types/${encodeURIComponent(sourceType)}/schema`, undefined, "GET");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (command === "source" && normalized[1] === "poll") {
|
|
86
|
+
const sourceId = normalized[2];
|
|
87
|
+
if (!sourceId) {
|
|
88
|
+
throw new Error("usage: agentinbox source poll <sourceId>");
|
|
89
|
+
}
|
|
90
|
+
await printRemote(client, `/sources/${encodeURIComponent(sourceId)}/poll`, {});
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (command === "source" && normalized[1] === "event") {
|
|
94
|
+
const sourceId = normalized[2];
|
|
95
|
+
const sourceNativeId = takeFlagValue(normalized, "--native-id");
|
|
96
|
+
const eventVariant = takeFlagValue(normalized, "--event");
|
|
97
|
+
if (!sourceId || !sourceNativeId || !eventVariant) {
|
|
98
|
+
throw new Error("usage: agentinbox source event <sourceId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]");
|
|
99
|
+
}
|
|
100
|
+
await printRemote(client, `/sources/${encodeURIComponent(sourceId)}/events`, {
|
|
101
|
+
sourceNativeId,
|
|
102
|
+
eventVariant,
|
|
103
|
+
occurredAt: takeFlagValue(normalized, "--occurred-at") ?? undefined,
|
|
104
|
+
metadata: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--metadata-json")),
|
|
105
|
+
rawPayload: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--payload-json")),
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (command === "agent" && normalized[1] === "register") {
|
|
110
|
+
const detected = (0, terminal_1.detectTerminalContext)(process.env);
|
|
111
|
+
await printRemote(client, "/agents/register", {
|
|
112
|
+
agentId: takeFlagValue(normalized, "--agent-id") ?? null,
|
|
113
|
+
forceRebind: normalized.includes("--force-rebind"),
|
|
114
|
+
backend: detected.backend,
|
|
115
|
+
runtimeKind: detected.runtimeKind,
|
|
116
|
+
runtimeSessionId: detected.runtimeSessionId ?? null,
|
|
117
|
+
tmuxPaneId: detected.tmuxPaneId ?? null,
|
|
118
|
+
tty: detected.tty ?? null,
|
|
119
|
+
termProgram: detected.termProgram ?? null,
|
|
120
|
+
itermSessionId: detected.itermSessionId ?? null,
|
|
121
|
+
notifyLeaseMs: parseOptionalNumber(takeFlagValue(normalized, "--notify-lease-ms")) ?? null,
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (command === "agent" && normalized[1] === "list") {
|
|
126
|
+
await printRemote(client, "/agents", undefined, "GET");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (command === "agent" && normalized[1] === "show") {
|
|
130
|
+
const agentId = normalized[2];
|
|
131
|
+
if (!agentId) {
|
|
132
|
+
throw new Error("usage: agentinbox agent show <agentId>");
|
|
133
|
+
}
|
|
134
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}`, undefined, "GET");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (command === "agent" && normalized[1] === "remove") {
|
|
138
|
+
const agentId = normalized[2];
|
|
139
|
+
if (!agentId) {
|
|
140
|
+
throw new Error("usage: agentinbox agent remove <agentId>");
|
|
141
|
+
}
|
|
142
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}`, undefined, "DELETE");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (command === "agent" && normalized[1] === "target" && normalized[2] === "add" && normalized[3] === "webhook") {
|
|
146
|
+
const agentId = normalized[4];
|
|
147
|
+
const url = takeFlagValue(normalized, "--url");
|
|
148
|
+
if (!agentId || !url) {
|
|
149
|
+
throw new Error("usage: agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N]");
|
|
150
|
+
}
|
|
151
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/targets`, {
|
|
152
|
+
kind: "webhook",
|
|
153
|
+
url,
|
|
154
|
+
activationMode: takeFlagValue(normalized, "--activation-mode") ?? undefined,
|
|
155
|
+
notifyLeaseMs: parseOptionalNumber(takeFlagValue(normalized, "--notify-lease-ms")) ?? null,
|
|
156
|
+
});
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (command === "agent" && normalized[1] === "target" && normalized[2] === "list") {
|
|
160
|
+
const agentId = normalized[3];
|
|
161
|
+
if (!agentId) {
|
|
162
|
+
throw new Error("usage: agentinbox agent target list <agentId>");
|
|
163
|
+
}
|
|
164
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/targets`, undefined, "GET");
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (command === "agent" && normalized[1] === "target" && normalized[2] === "remove") {
|
|
168
|
+
const [agentId, targetId] = normalized.slice(3, 5);
|
|
169
|
+
if (!agentId || !targetId) {
|
|
170
|
+
throw new Error("usage: agentinbox agent target remove <agentId> <targetId>");
|
|
171
|
+
}
|
|
172
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/targets/${encodeURIComponent(targetId)}`, undefined, "DELETE");
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (command === "subscription" && normalized[1] === "add") {
|
|
176
|
+
const [agentId, sourceId] = normalized.slice(2, 4);
|
|
177
|
+
if (!agentId || !sourceId) {
|
|
178
|
+
throw new Error("usage: agentinbox subscription add <agentId> <sourceId> [--filter-json JSON] [--start-policy POLICY] [--start-offset N] [--start-time ISO8601]");
|
|
179
|
+
}
|
|
180
|
+
await printRemote(client, "/subscriptions/register", {
|
|
181
|
+
agentId,
|
|
182
|
+
sourceId,
|
|
183
|
+
filter: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--filter-json")),
|
|
184
|
+
startPolicy: takeFlagValue(normalized, "--start-policy") ?? undefined,
|
|
185
|
+
startOffset: parseOptionalNumber(takeFlagValue(normalized, "--start-offset")),
|
|
186
|
+
startTime: takeFlagValue(normalized, "--start-time") ?? undefined,
|
|
187
|
+
});
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (command === "subscription" && normalized[1] === "list") {
|
|
191
|
+
const query = buildQuery({
|
|
192
|
+
source_id: takeFlagValue(normalized, "--source-id"),
|
|
193
|
+
agent_id: takeFlagValue(normalized, "--agent-id"),
|
|
194
|
+
});
|
|
195
|
+
await printRemote(client, `/subscriptions${query}`, undefined, "GET");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (command === "subscription" && normalized[1] === "show") {
|
|
199
|
+
const subscriptionId = normalized[2];
|
|
200
|
+
if (!subscriptionId) {
|
|
201
|
+
throw new Error("usage: agentinbox subscription show <subscriptionId>");
|
|
202
|
+
}
|
|
203
|
+
await printRemote(client, `/subscriptions/${encodeURIComponent(subscriptionId)}`, undefined, "GET");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (command === "subscription" && normalized[1] === "remove") {
|
|
207
|
+
const subscriptionId = normalized[2];
|
|
208
|
+
if (!subscriptionId) {
|
|
209
|
+
throw new Error("usage: agentinbox subscription remove <subscriptionId>");
|
|
210
|
+
}
|
|
211
|
+
await printRemote(client, `/subscriptions/${encodeURIComponent(subscriptionId)}`, undefined, "DELETE");
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (command === "subscription" && normalized[1] === "poll") {
|
|
215
|
+
const subscriptionId = normalized[2];
|
|
216
|
+
if (!subscriptionId) {
|
|
217
|
+
throw new Error("usage: agentinbox subscription poll <subscriptionId>");
|
|
218
|
+
}
|
|
219
|
+
await printRemote(client, `/subscriptions/${encodeURIComponent(subscriptionId)}/poll`, {});
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (command === "subscription" && normalized[1] === "lag") {
|
|
223
|
+
const subscriptionId = normalized[2];
|
|
224
|
+
if (!subscriptionId) {
|
|
225
|
+
throw new Error("usage: agentinbox subscription lag <subscriptionId>");
|
|
226
|
+
}
|
|
227
|
+
await printRemote(client, `/subscriptions/${encodeURIComponent(subscriptionId)}/lag`, undefined, "GET");
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (command === "subscription" && normalized[1] === "reset") {
|
|
231
|
+
const subscriptionId = normalized[2];
|
|
232
|
+
const startPolicy = takeFlagValue(normalized, "--start-policy");
|
|
233
|
+
if (!subscriptionId || !startPolicy) {
|
|
234
|
+
throw new Error("usage: agentinbox subscription reset <subscriptionId> --start-policy latest|earliest|at_offset|at_time [--start-offset N] [--start-time ISO8601]");
|
|
235
|
+
}
|
|
236
|
+
await printRemote(client, `/subscriptions/${encodeURIComponent(subscriptionId)}/reset`, {
|
|
237
|
+
startPolicy,
|
|
238
|
+
startOffset: parseOptionalNumber(takeFlagValue(normalized, "--start-offset")),
|
|
239
|
+
startTime: takeFlagValue(normalized, "--start-time") ?? undefined,
|
|
240
|
+
});
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (command === "inbox" && normalized[1] === "list") {
|
|
244
|
+
await printRemote(client, "/agents", undefined, "GET");
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (command === "inbox" && normalized[1] === "show") {
|
|
248
|
+
const agentId = normalized[2];
|
|
249
|
+
if (!agentId) {
|
|
250
|
+
throw new Error("usage: agentinbox inbox show <agentId>");
|
|
251
|
+
}
|
|
252
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/inbox`, undefined, "GET");
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (command === "inbox" && normalized[1] === "read") {
|
|
256
|
+
const agentId = normalized[2];
|
|
257
|
+
if (!agentId) {
|
|
258
|
+
throw new Error("usage: agentinbox inbox read <agentId>");
|
|
259
|
+
}
|
|
260
|
+
const query = buildQuery({
|
|
261
|
+
after_item_id: takeFlagValue(normalized, "--after-item"),
|
|
262
|
+
include_acked: hasFlag(normalized, "--include-acked") ? "true" : undefined,
|
|
263
|
+
});
|
|
264
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/inbox/items${query}`, undefined, "GET");
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (command === "inbox" && normalized[1] === "watch") {
|
|
268
|
+
const agentId = normalized[2];
|
|
269
|
+
if (!agentId) {
|
|
270
|
+
throw new Error("usage: agentinbox inbox watch <agentId> [--after-item ID] [--include-acked] [--heartbeat-ms N]");
|
|
271
|
+
}
|
|
272
|
+
for await (const event of client.watchInbox(agentId, {
|
|
273
|
+
afterItemId: takeFlagValue(normalized, "--after-item"),
|
|
274
|
+
includeAcked: hasFlag(normalized, "--include-acked"),
|
|
275
|
+
heartbeatMs: parseOptionalNumber(takeFlagValue(normalized, "--heartbeat-ms")),
|
|
276
|
+
})) {
|
|
277
|
+
if (event.event !== "items") {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
console.log((0, util_1.jsonResponse)(event));
|
|
281
|
+
}
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (command === "inbox" && normalized[1] === "ack") {
|
|
285
|
+
const agentId = normalized[2];
|
|
286
|
+
const itemId = takeFlagValue(normalized, "--item");
|
|
287
|
+
const throughItemId = takeFlagValue(normalized, "--through");
|
|
288
|
+
const ackAll = hasFlag(normalized, "--all");
|
|
289
|
+
const modeCount = Number(Boolean(itemId)) + Number(Boolean(throughItemId)) + Number(ackAll);
|
|
290
|
+
if (!agentId || modeCount !== 1) {
|
|
291
|
+
throw new Error("usage: agentinbox inbox ack <agentId> (--through <itemId> | --item <itemId> | --all)");
|
|
292
|
+
}
|
|
293
|
+
if (ackAll) {
|
|
294
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/inbox/ack-all`, {});
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/inbox/ack`, throughItemId ? { throughItemId } : { itemIds: [itemId] });
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (command === "inbox" && normalized[1] === "compact") {
|
|
301
|
+
const agentId = normalized[2];
|
|
302
|
+
if (!agentId) {
|
|
303
|
+
throw new Error("usage: agentinbox inbox compact <agentId>");
|
|
304
|
+
}
|
|
305
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/inbox/compact`, {});
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (command === "gc") {
|
|
309
|
+
await printRemote(client, "/gc", {});
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if (command === "fixture" && normalized[1] === "emit") {
|
|
313
|
+
const sourceId = normalized[2];
|
|
314
|
+
const sourceNativeId = takeFlagValue(normalized, "--native-id") ?? `fixture-${Date.now()}`;
|
|
315
|
+
const eventVariant = takeFlagValue(normalized, "--event") ?? "message";
|
|
316
|
+
if (!sourceId) {
|
|
317
|
+
throw new Error("usage: agentinbox fixture emit <sourceId> [--native-id ID] [--event EVENT] [--metadata-json JSON] [--payload-json JSON]");
|
|
318
|
+
}
|
|
319
|
+
await printRemote(client, "/fixtures/emit", {
|
|
320
|
+
sourceId,
|
|
321
|
+
sourceNativeId,
|
|
322
|
+
eventVariant,
|
|
323
|
+
metadata: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--metadata-json")),
|
|
324
|
+
rawPayload: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--payload-json")),
|
|
325
|
+
});
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (command === "deliver" && normalized[1] === "send") {
|
|
329
|
+
const provider = takeFlagValue(normalized, "--provider");
|
|
330
|
+
const surface = takeFlagValue(normalized, "--surface");
|
|
331
|
+
const targetRef = takeFlagValue(normalized, "--target");
|
|
332
|
+
const kind = takeFlagValue(normalized, "--kind") ?? "reply";
|
|
333
|
+
if (!provider || !surface || !targetRef) {
|
|
334
|
+
throw new Error("usage: agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--kind KIND] [--payload-json JSON]");
|
|
335
|
+
}
|
|
336
|
+
await printRemote(client, "/deliveries/send", {
|
|
337
|
+
provider,
|
|
338
|
+
surface,
|
|
339
|
+
targetRef,
|
|
340
|
+
threadRef: takeFlagValue(normalized, "--thread") ?? null,
|
|
341
|
+
replyMode: takeFlagValue(normalized, "--reply-mode") ?? null,
|
|
342
|
+
kind,
|
|
343
|
+
payload: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--payload-json")),
|
|
344
|
+
});
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
if (command === "status") {
|
|
348
|
+
await printRemote(client, "/status", undefined, "GET");
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (command === "gc") {
|
|
352
|
+
await printRemote(client, "/gc", {});
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (hasHelpFlag(normalized.slice(1))) {
|
|
356
|
+
printHelp([command]);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
throw new Error(`unknown command: ${args.join(" ")}`);
|
|
360
|
+
}
|
|
361
|
+
async function runServe(args) {
|
|
362
|
+
const port = parseOptionalNumber(takeFlagValue(args, "--port"));
|
|
363
|
+
const serveConfig = (0, paths_1.resolveServeConfig)({
|
|
364
|
+
env: process.env,
|
|
365
|
+
homeDirOverride: takeFlagValue(args, "--home"),
|
|
366
|
+
statePathOverride: takeFlagValue(args, "--state"),
|
|
367
|
+
socketPathOverride: takeFlagValue(args, "--socket"),
|
|
368
|
+
portOverride: port,
|
|
369
|
+
});
|
|
370
|
+
const store = await store_1.AgentInboxStore.open(serveConfig.dbPath);
|
|
371
|
+
let service;
|
|
372
|
+
const adapters = new adapters_1.AdapterRegistry(store, async (input) => service.appendSourceEvent(input));
|
|
373
|
+
service = new service_1.AgentInboxService(store, adapters);
|
|
374
|
+
const server = (0, http_1.createServer)(service);
|
|
375
|
+
await adapters.start();
|
|
376
|
+
await service.start();
|
|
377
|
+
const controlServer = await (0, control_server_1.startControlServer)(server, serveConfig.transport);
|
|
378
|
+
const daemonPaths = (0, paths_1.resolveDaemonPaths)(process.env, takeFlagValue(args, "--home"));
|
|
379
|
+
if (serveConfig.transport.kind === "socket") {
|
|
380
|
+
(0, daemon_1.writePidFile)(daemonPaths.pidPath, process.pid);
|
|
381
|
+
}
|
|
382
|
+
console.log((0, util_1.jsonResponse)({
|
|
383
|
+
ok: true,
|
|
384
|
+
homeDir: serveConfig.homeDir,
|
|
385
|
+
dbPath: serveConfig.dbPath,
|
|
386
|
+
...controlServer.info,
|
|
387
|
+
}));
|
|
388
|
+
const shutdown = () => {
|
|
389
|
+
void controlServer.close().finally(() => {
|
|
390
|
+
void adapters.stop();
|
|
391
|
+
void service.stop();
|
|
392
|
+
store.close();
|
|
393
|
+
if (serveConfig.transport.kind === "socket") {
|
|
394
|
+
(0, daemon_1.removePidFile)(daemonPaths.pidPath);
|
|
395
|
+
}
|
|
396
|
+
process.exit(0);
|
|
397
|
+
});
|
|
398
|
+
};
|
|
399
|
+
process.on("SIGINT", shutdown);
|
|
400
|
+
process.on("SIGTERM", shutdown);
|
|
401
|
+
}
|
|
402
|
+
async function runDaemon(args) {
|
|
403
|
+
const action = args[0];
|
|
404
|
+
const options = {
|
|
405
|
+
env: process.env,
|
|
406
|
+
homeDirOverride: takeFlagValue(args, "--home"),
|
|
407
|
+
socketPathOverride: takeFlagValue(args, "--socket"),
|
|
408
|
+
baseUrlOverride: takeFlagValue(args, "--url"),
|
|
409
|
+
};
|
|
410
|
+
if (action === "start") {
|
|
411
|
+
const result = await (0, daemon_1.startDaemon)(options);
|
|
412
|
+
console.log((0, util_1.jsonResponse)(result));
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (action === "stop") {
|
|
416
|
+
const result = await (0, daemon_1.stopDaemon)(options);
|
|
417
|
+
console.log((0, util_1.jsonResponse)(result));
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (action === "status") {
|
|
421
|
+
const result = await (0, daemon_1.daemonStatus)(options);
|
|
422
|
+
console.log((0, util_1.jsonResponse)(result));
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
throw new Error("usage: agentinbox daemon <start|stop|status>");
|
|
426
|
+
}
|
|
427
|
+
async function createClient(args) {
|
|
428
|
+
const transport = await (0, daemon_1.ensureDaemonForClient)({
|
|
429
|
+
env: process.env,
|
|
430
|
+
homeDirOverride: takeFlagValue(args, "--home"),
|
|
431
|
+
socketPathOverride: takeFlagValue(args, "--socket"),
|
|
432
|
+
baseUrlOverride: takeFlagValue(args, "--url"),
|
|
433
|
+
noAutoStart: hasFlag(args, "--no-auto-start"),
|
|
434
|
+
});
|
|
435
|
+
return new client_1.AgentInboxClient(transport);
|
|
436
|
+
}
|
|
437
|
+
async function printRemote(client, endpoint, body, method = "POST") {
|
|
438
|
+
const response = await client.request(endpoint, body, method);
|
|
439
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
440
|
+
throw new Error((0, util_1.jsonResponse)(response.data));
|
|
441
|
+
}
|
|
442
|
+
console.log((0, util_1.jsonResponse)(response.data));
|
|
443
|
+
}
|
|
444
|
+
function takeFlagValue(args, flag) {
|
|
445
|
+
const index = args.indexOf(flag);
|
|
446
|
+
if (index === -1) {
|
|
447
|
+
return undefined;
|
|
448
|
+
}
|
|
449
|
+
return args[index + 1];
|
|
450
|
+
}
|
|
451
|
+
function hasFlag(args, flag) {
|
|
452
|
+
return args.includes(flag);
|
|
453
|
+
}
|
|
454
|
+
function parseOptionalNumber(value) {
|
|
455
|
+
if (value == null) {
|
|
456
|
+
return undefined;
|
|
457
|
+
}
|
|
458
|
+
const parsed = Number(value);
|
|
459
|
+
if (Number.isNaN(parsed)) {
|
|
460
|
+
throw new Error(`expected number, received ${value}`);
|
|
461
|
+
}
|
|
462
|
+
return parsed;
|
|
463
|
+
}
|
|
464
|
+
function normalizeHelpArgs(args) {
|
|
465
|
+
if (args[0] !== "help") {
|
|
466
|
+
return args;
|
|
467
|
+
}
|
|
468
|
+
if (!args[1]) {
|
|
469
|
+
return ["help"];
|
|
470
|
+
}
|
|
471
|
+
return [args[1], "--help"];
|
|
472
|
+
}
|
|
473
|
+
function hasHelpFlag(args) {
|
|
474
|
+
return args.includes("--help") || args.includes("-h");
|
|
475
|
+
}
|
|
476
|
+
function buildQuery(params) {
|
|
477
|
+
const search = new URLSearchParams();
|
|
478
|
+
for (const [key, value] of Object.entries(params)) {
|
|
479
|
+
if (value) {
|
|
480
|
+
search.set(key, value);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const query = search.toString();
|
|
484
|
+
return query ? `?${query}` : "";
|
|
485
|
+
}
|
|
486
|
+
function printHelp(path = []) {
|
|
487
|
+
const key = path[0] ?? "root";
|
|
488
|
+
const helpByKey = {
|
|
489
|
+
root: `agentinbox
|
|
490
|
+
|
|
491
|
+
Usage:
|
|
492
|
+
agentinbox <command> [options]
|
|
493
|
+
agentinbox help [command]
|
|
494
|
+
agentinbox --help, -h
|
|
495
|
+
agentinbox --version, -v
|
|
496
|
+
|
|
497
|
+
Commands:
|
|
498
|
+
serve
|
|
499
|
+
daemon
|
|
500
|
+
source
|
|
501
|
+
agent
|
|
502
|
+
subscription
|
|
503
|
+
inbox
|
|
504
|
+
gc
|
|
505
|
+
fixture
|
|
506
|
+
deliver
|
|
507
|
+
status
|
|
508
|
+
gc
|
|
509
|
+
version
|
|
510
|
+
`,
|
|
511
|
+
serve: `agentinbox serve
|
|
512
|
+
|
|
513
|
+
Usage:
|
|
514
|
+
agentinbox serve [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock]
|
|
515
|
+
agentinbox serve --port 4747 [--state ~/.agentinbox/agentinbox.sqlite]
|
|
516
|
+
`,
|
|
517
|
+
daemon: `agentinbox daemon
|
|
518
|
+
|
|
519
|
+
Usage:
|
|
520
|
+
agentinbox daemon start [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock]
|
|
521
|
+
agentinbox daemon stop [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock]
|
|
522
|
+
agentinbox daemon status [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock]
|
|
523
|
+
`,
|
|
524
|
+
source: `agentinbox source
|
|
525
|
+
|
|
526
|
+
Usage:
|
|
527
|
+
agentinbox source add <type> <sourceKey> [--config-json JSON] [--config-ref REF]
|
|
528
|
+
agentinbox source list
|
|
529
|
+
agentinbox source show <sourceId>
|
|
530
|
+
agentinbox source schema <sourceType>
|
|
531
|
+
agentinbox source poll <sourceId>
|
|
532
|
+
agentinbox source event <sourceId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]
|
|
533
|
+
`,
|
|
534
|
+
agent: `agentinbox agent
|
|
535
|
+
|
|
536
|
+
Usage:
|
|
537
|
+
agentinbox agent register [--agent-id ID] [--force-rebind] [--notify-lease-ms N]
|
|
538
|
+
agentinbox agent list
|
|
539
|
+
agentinbox agent show <agentId>
|
|
540
|
+
agentinbox agent remove <agentId>
|
|
541
|
+
agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N]
|
|
542
|
+
agentinbox agent target list <agentId>
|
|
543
|
+
agentinbox agent target remove <agentId> <targetId>
|
|
544
|
+
`,
|
|
545
|
+
subscription: `agentinbox subscription
|
|
546
|
+
|
|
547
|
+
Usage:
|
|
548
|
+
agentinbox subscription add <agentId> <sourceId> [--filter-json JSON] [--start-policy POLICY] [--start-offset N] [--start-time ISO8601]
|
|
549
|
+
agentinbox subscription list [--source-id ID] [--agent-id ID]
|
|
550
|
+
agentinbox subscription show <subscriptionId>
|
|
551
|
+
agentinbox subscription remove <subscriptionId>
|
|
552
|
+
agentinbox subscription poll <subscriptionId>
|
|
553
|
+
agentinbox subscription lag <subscriptionId>
|
|
554
|
+
agentinbox subscription reset <subscriptionId> --start-policy latest|earliest|at_offset|at_time [--start-offset N] [--start-time ISO8601]
|
|
555
|
+
`,
|
|
556
|
+
inbox: `agentinbox inbox
|
|
557
|
+
|
|
558
|
+
Usage:
|
|
559
|
+
agentinbox inbox list
|
|
560
|
+
agentinbox inbox show <agentId>
|
|
561
|
+
agentinbox inbox read <agentId> [--after-item ID] [--include-acked]
|
|
562
|
+
agentinbox inbox watch <agentId> [--after-item ID] [--include-acked] [--heartbeat-ms N]
|
|
563
|
+
agentinbox inbox ack <agentId> (--through <itemId> | --item <itemId> | --all)
|
|
564
|
+
agentinbox inbox compact <agentId>
|
|
565
|
+
`,
|
|
566
|
+
fixture: `agentinbox fixture
|
|
567
|
+
|
|
568
|
+
Usage:
|
|
569
|
+
agentinbox fixture emit <sourceId> [--native-id ID] [--event EVENT] [--metadata-json JSON] [--payload-json JSON]
|
|
570
|
+
`,
|
|
571
|
+
deliver: `agentinbox deliver
|
|
572
|
+
|
|
573
|
+
Usage:
|
|
574
|
+
agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--kind KIND] [--payload-json JSON]
|
|
575
|
+
`,
|
|
576
|
+
status: `agentinbox status
|
|
577
|
+
|
|
578
|
+
Usage:
|
|
579
|
+
agentinbox status
|
|
580
|
+
`,
|
|
581
|
+
gc: `agentinbox gc
|
|
582
|
+
|
|
583
|
+
Usage:
|
|
584
|
+
agentinbox gc
|
|
585
|
+
`,
|
|
586
|
+
version: `agentinbox version
|
|
587
|
+
|
|
588
|
+
Usage:
|
|
589
|
+
agentinbox version
|
|
590
|
+
agentinbox --version, -v
|
|
591
|
+
`,
|
|
592
|
+
};
|
|
593
|
+
console.log(helpByKey[key] ?? helpByKey.root);
|
|
594
|
+
}
|
|
595
|
+
function printVersion() {
|
|
596
|
+
console.log(`agentinbox ${readPackageVersion()}`);
|
|
597
|
+
}
|
|
598
|
+
function readPackageVersion() {
|
|
599
|
+
const packageJsonPath = findPackageJsonPath(__dirname);
|
|
600
|
+
const parsed = JSON.parse(node_fs_1.default.readFileSync(packageJsonPath, "utf8"));
|
|
601
|
+
return typeof parsed.version === "string" ? parsed.version : "0.0.0";
|
|
602
|
+
}
|
|
603
|
+
function findPackageJsonPath(startDir) {
|
|
604
|
+
let currentDir = startDir;
|
|
605
|
+
while (true) {
|
|
606
|
+
const candidate = node_path_1.default.join(currentDir, "package.json");
|
|
607
|
+
if (node_fs_1.default.existsSync(candidate)) {
|
|
608
|
+
return candidate;
|
|
609
|
+
}
|
|
610
|
+
const parentDir = node_path_1.default.dirname(currentDir);
|
|
611
|
+
if (parentDir === currentDir) {
|
|
612
|
+
throw new Error(`could not locate package.json from ${startDir}`);
|
|
613
|
+
}
|
|
614
|
+
currentDir = parentDir;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
main().catch((error) => {
|
|
618
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
619
|
+
process.exit(1);
|
|
620
|
+
});
|