@holon-run/agentinbox 0.7.0 → 1.0.0-beta.1

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 (33) hide show
  1. package/README.md +36 -7
  2. package/dist/src/adapters.js +55 -0
  3. package/dist/src/backend.js +4 -16
  4. package/dist/src/cli.js +329 -52
  5. package/dist/src/client.js +2 -2
  6. package/dist/src/http.js +479 -55
  7. package/dist/src/runtime_gate.js +49 -41
  8. package/dist/src/service.js +922 -200
  9. package/dist/src/source_hosts.js +75 -0
  10. package/dist/src/source_resolution.js +2 -2
  11. package/dist/src/source_schema.js +2 -2
  12. package/dist/src/sources/feishu.js +66 -28
  13. package/dist/src/sources/github.js +222 -36
  14. package/dist/src/sources/remote.js +50 -3
  15. package/dist/src/sources/remote_modules.js +100 -15
  16. package/dist/src/store.js +875 -110
  17. package/dist/src/terminal.js +33 -7
  18. package/dist/src/util.js +46 -1
  19. package/drizzle/migrations/{0000_initial.sql → 0000_v1_initial.sql} +182 -6
  20. package/drizzle/migrations/0002_host_scoped_lifecycle_retirements.sql +42 -0
  21. package/drizzle/migrations/0003_subscription_tracked_resource_indexes.sql +5 -0
  22. package/drizzle/schema.ts +98 -3
  23. package/package.json +2 -1
  24. package/scripts/release_smoke.sh +123 -0
  25. package/dist/src/sources/remote_profiles.js +0 -13
  26. package/drizzle/migrations/0001_inbox_items_source_occurred_at_idx.sql +0 -3
  27. package/drizzle/migrations/0002_subscription_cleanup_policy.sql +0 -45
  28. package/drizzle/migrations/0003_subscription_lifecycle_retirements.sql +0 -14
  29. package/drizzle/migrations/0004_source_idle_states.sql +0 -10
  30. package/drizzle/migrations/0005_timers.sql +0 -22
  31. package/drizzle/migrations/0006_terminal_runtime_pid.sql +0 -1
  32. package/drizzle/migrations/0007_activation_dispatch_last_notified_fingerprint.sql +0 -2
  33. package/drizzle/migrations/0008_inbox_item_sequence.sql +0 -21
package/dist/src/cli.js CHANGED
@@ -19,8 +19,11 @@ const store_1 = require("./store");
19
19
  const terminal_1 = require("./terminal");
20
20
  const util_1 = require("./util");
21
21
  async function main() {
22
- const args = process.argv.slice(2);
23
- const normalized = normalizeHelpArgs(args);
22
+ const rawArgs = process.argv.slice(2);
23
+ const detectedArgs = normalizeHelpArgs(rawArgs);
24
+ const normalized = shouldTreatJsonFlagAsNoop(detectedArgs)
25
+ ? stripNoopJsonFlag(detectedArgs)
26
+ : detectedArgs;
24
27
  const command = normalized[0];
25
28
  if (!command || command === "help" || command === "--help" || command === "-h") {
26
29
  printHelp(normalized.slice(1));
@@ -51,14 +54,167 @@ async function main() {
51
54
  return;
52
55
  }
53
56
  const client = await createClient(normalized);
57
+ if (command === "host" && normalized[1] === "add") {
58
+ const [hostType, hostKey] = normalized.slice(2, 4);
59
+ if (!hostType || !hostKey) {
60
+ throw new Error("usage: agentinbox host add <hostType> <hostKey> [--config-json JSON] [--config-ref REF]");
61
+ }
62
+ await printRemote(client, "/hosts", {
63
+ hostType,
64
+ hostKey,
65
+ configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
66
+ config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
67
+ });
68
+ return;
69
+ }
70
+ if (command === "host" && normalized[1] === "list") {
71
+ await printRemote(client, "/hosts", undefined, "GET");
72
+ return;
73
+ }
74
+ if (command === "host" && normalized[1] === "show") {
75
+ const hostId = normalized[2];
76
+ if (!hostId) {
77
+ throw new Error("usage: agentinbox host show <hostId>");
78
+ }
79
+ await printRemote(client, `/hosts/${encodeURIComponent(hostId)}`, undefined, "GET");
80
+ return;
81
+ }
82
+ if (command === "host" && normalized[1] === "schema") {
83
+ const hostId = normalized[2];
84
+ if (!hostId) {
85
+ throw new Error("usage: agentinbox host schema <hostId>");
86
+ }
87
+ await printRemote(client, `/hosts/${encodeURIComponent(hostId)}/schema`, undefined, "GET");
88
+ return;
89
+ }
90
+ if (command === "stream" && normalized[1] === "add") {
91
+ const [hostId, streamKind, streamKey] = normalized.slice(2, 5);
92
+ if (!hostId || !streamKind || !streamKey) {
93
+ throw new Error("usage: agentinbox stream add <hostId> <streamKind> <streamKey> [--config-json JSON] [--config-ref REF]");
94
+ }
95
+ await printRemote(client, "/streams", {
96
+ hostId,
97
+ streamKind,
98
+ streamKey,
99
+ configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
100
+ config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
101
+ });
102
+ return;
103
+ }
104
+ if (command === "stream" && normalized[1] === "list") {
105
+ await printRemote(client, "/streams", undefined, "GET");
106
+ return;
107
+ }
108
+ if (command === "stream" && normalized[1] === "show") {
109
+ const streamId = normalized[2];
110
+ if (!streamId) {
111
+ throw new Error("usage: agentinbox stream show <streamId>");
112
+ }
113
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}`, undefined, "GET");
114
+ return;
115
+ }
116
+ if (command === "stream" && normalized[1] === "remove") {
117
+ const removeArgs = normalized.slice(2);
118
+ const positionals = positionalArgs(removeArgs, ["--with-subscriptions"]);
119
+ const streamId = positionals[0];
120
+ if (!streamId || positionals[1]) {
121
+ throw new Error("usage: agentinbox stream remove <streamId> [--with-subscriptions]");
122
+ }
123
+ const query = buildQuery({
124
+ with_subscriptions: hasFlag(normalized, "--with-subscriptions") ? "true" : undefined,
125
+ });
126
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}${query}`, undefined, "DELETE");
127
+ return;
128
+ }
129
+ if (command === "stream" && normalized[1] === "update") {
130
+ const streamId = normalized[2];
131
+ if (!streamId) {
132
+ throw new Error("usage: agentinbox stream update <streamId> [--config-json JSON] [--config-ref REF | --clear-config-ref]");
133
+ }
134
+ const configRef = takeFlagValue(normalized, "--config-ref");
135
+ const clearConfigRef = hasFlag(normalized, "--clear-config-ref");
136
+ const configJson = takeFlagValue(normalized, "--config-json");
137
+ if (configRef != null && clearConfigRef) {
138
+ throw new Error("stream update accepts only one of --config-ref or --clear-config-ref");
139
+ }
140
+ if (!clearConfigRef && configRef == null && configJson == null) {
141
+ throw new Error("usage: agentinbox stream update <streamId> [--config-json JSON] [--config-ref REF | --clear-config-ref]");
142
+ }
143
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}`, {
144
+ ...(clearConfigRef ? { configRef: null } : (configRef != null ? { configRef } : {})),
145
+ config: configJson != null ? (0, util_1.parseJsonArg)(configJson, "--config-json") : undefined,
146
+ }, "PATCH");
147
+ return;
148
+ }
149
+ if (command === "stream" && normalized[1] === "pause") {
150
+ const streamId = normalized[2];
151
+ if (!streamId) {
152
+ throw new Error("usage: agentinbox stream pause <streamId>");
153
+ }
154
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}/pause`, {});
155
+ return;
156
+ }
157
+ if (command === "stream" && normalized[1] === "resume") {
158
+ const streamId = normalized[2];
159
+ if (!streamId) {
160
+ throw new Error("usage: agentinbox stream resume <streamId>");
161
+ }
162
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}/resume`, {});
163
+ return;
164
+ }
165
+ if (command === "stream" && normalized[1] === "schema") {
166
+ if (normalized[2] === "preview") {
167
+ const sourceRef = normalized[3];
168
+ if (!sourceRef) {
169
+ throw new Error("usage: agentinbox stream schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]");
170
+ }
171
+ await printRemote(client, "/streams/schema-preview", {
172
+ sourceRef,
173
+ configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
174
+ config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
175
+ });
176
+ return;
177
+ }
178
+ const streamRef = normalized[2];
179
+ if (!streamRef) {
180
+ throw new Error("usage: agentinbox stream schema <streamId>");
181
+ }
182
+ await printRemote(client, `/streams/${encodeURIComponent(streamRef)}/schema`, undefined, "GET");
183
+ return;
184
+ }
185
+ if (command === "stream" && normalized[1] === "poll") {
186
+ const streamId = normalized[2];
187
+ if (!streamId) {
188
+ throw new Error("usage: agentinbox stream poll <streamId>");
189
+ }
190
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}/poll`, {});
191
+ return;
192
+ }
193
+ if (command === "stream" && normalized[1] === "event") {
194
+ const streamId = normalized[2];
195
+ const sourceNativeId = takeFlagValue(normalized, "--native-id");
196
+ const eventVariant = takeFlagValue(normalized, "--event");
197
+ if (!streamId || !sourceNativeId || !eventVariant) {
198
+ throw new Error("usage: agentinbox stream event <streamId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]");
199
+ }
200
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}/events`, {
201
+ sourceNativeId,
202
+ eventVariant,
203
+ occurredAt: takeFlagValue(normalized, "--occurred-at") ?? undefined,
204
+ metadata: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--metadata-json")),
205
+ rawPayload: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--payload-json")),
206
+ });
207
+ return;
208
+ }
54
209
  if (command === "source" && normalized[1] === "add") {
55
- const [type, sourceKey] = normalized.slice(2, 4);
56
- if (!type || !sourceKey) {
57
- throw new Error("usage: agentinbox source add <type> <sourceKey> [--config-json JSON] [--config-ref REF]");
210
+ const [hostId, streamKind, streamKey] = normalized.slice(2, 5);
211
+ if (!hostId || !streamKind || !streamKey) {
212
+ throw new Error("usage: agentinbox source add <hostId> <streamKind> <streamKey> [--config-json JSON] [--config-ref REF]");
58
213
  }
59
214
  await printRemote(client, "/sources", {
60
- sourceType: type,
61
- sourceKey,
215
+ hostId,
216
+ streamKind,
217
+ streamKey,
62
218
  configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
63
219
  config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
64
220
  });
@@ -126,27 +282,11 @@ async function main() {
126
282
  return;
127
283
  }
128
284
  if (command === "source" && normalized[1] === "schema") {
129
- if (normalized[2] === "preview") {
130
- const sourceRef = normalized[3];
131
- if (!sourceRef) {
132
- throw new Error("usage: agentinbox source schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]");
133
- }
134
- await printRemote(client, "/sources/schema-preview", {
135
- sourceRef,
136
- configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
137
- config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
138
- });
139
- return;
140
- }
141
285
  const sourceRef = normalized[2];
142
286
  if (!sourceRef) {
143
- throw new Error("usage: agentinbox source schema <sourceId|sourceType>");
144
- }
145
- if (sourceRef.startsWith("src_")) {
146
- await printRemote(client, `/sources/${encodeURIComponent(sourceRef)}/schema`, undefined, "GET");
147
- return;
287
+ throw new Error("usage: agentinbox source schema <sourceId>");
148
288
  }
149
- await printRemote(client, `/source-types/${encodeURIComponent(sourceRef)}/schema`, undefined, "GET");
289
+ await printRemote(client, `/sources/${encodeURIComponent(sourceRef)}/schema`, undefined, "GET");
150
290
  return;
151
291
  }
152
292
  if (command === "source" && normalized[1] === "poll") {
@@ -187,6 +327,7 @@ async function main() {
187
327
  termProgram: detected.termProgram ?? undefined,
188
328
  itermSessionId: detected.itermSessionId ?? undefined,
189
329
  notifyLeaseMs: parseOptionalNumber(takeFlagValue(normalized, "--notify-lease-ms")) ?? undefined,
330
+ minUnackedItems: parseOptionalNumber(takeFlagValue(normalized, "--min-unacked-items")) ?? undefined,
190
331
  });
191
332
  return;
192
333
  }
@@ -226,13 +367,14 @@ async function main() {
226
367
  const agentId = normalized[4];
227
368
  const url = takeFlagValue(normalized, "--url");
228
369
  if (!agentId || !url) {
229
- throw new Error("usage: agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N]");
370
+ throw new Error("usage: agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N] [--min-unacked-items N]");
230
371
  }
231
372
  await printRemote(client, `/agents/${encodeURIComponent(agentId)}/targets`, {
232
373
  kind: "webhook",
233
374
  url,
234
375
  activationMode: takeFlagValue(normalized, "--activation-mode") ?? undefined,
235
376
  notifyLeaseMs: parseOptionalNumber(takeFlagValue(normalized, "--notify-lease-ms")) ?? undefined,
377
+ minUnackedItems: parseOptionalNumber(takeFlagValue(normalized, "--min-unacked-items")) ?? undefined,
236
378
  });
237
379
  return;
238
380
  }
@@ -306,7 +448,7 @@ async function main() {
306
448
  startOffset: parseOptionalNumber(takeFlagValue(normalized, "--start-offset")),
307
449
  startTime: takeFlagValue(normalized, "--start-time") ?? undefined,
308
450
  });
309
- console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
451
+ console.log((0, util_1.jsonResponse)(withCommandMetadata(normalizeSubscriptionAddOutput(response.data, Boolean(shortcutName)), selection)));
310
452
  return;
311
453
  }
312
454
  if (command === "subscription" && normalized[1] === "list") {
@@ -432,19 +574,19 @@ async function main() {
432
574
  }
433
575
  if (command === "inbox" && normalized[1] === "read") {
434
576
  const args = normalized.slice(2);
435
- const allowedFlags = ["--agent-id", "--after-item", "--include-acked"];
436
- if (positionalArgs(args, ["--agent-id", "--after-item"]).length > 0 || unexpectedFlags(args, allowedFlags).length > 0) {
437
- throw new Error("usage: agentinbox inbox read [--agent-id ID] [--after-item ID] [--include-acked]");
577
+ const allowedFlags = ["--agent-id", "--after-entry", "--include-acked"];
578
+ if (positionalArgs(args, ["--agent-id", "--after-entry"]).length > 0 || unexpectedFlags(args, allowedFlags).length > 0) {
579
+ throw new Error("usage: agentinbox inbox read [--agent-id ID] [--after-entry ID] [--include-acked]");
438
580
  }
439
581
  const selection = await selectAgentForCommand(client, {
440
582
  explicitAgentId: takeFlagValue(normalized, "--agent-id"),
441
583
  autoRegister: true,
442
584
  });
443
585
  const query = buildQuery({
444
- after_item_id: takeFlagValue(normalized, "--after-item"),
586
+ after_entry_id: takeFlagValue(normalized, "--after-entry"),
445
587
  include_acked: hasFlag(normalized, "--include-acked") ? "true" : undefined,
446
588
  });
447
- const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/items${query}`, undefined, "GET");
589
+ const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/entries${query}`, undefined, "GET");
448
590
  console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
449
591
  return;
450
592
  }
@@ -467,8 +609,8 @@ async function main() {
467
609
  }
468
610
  if (command === "inbox" && normalized[1] === "watch") {
469
611
  const args = normalized.slice(2);
470
- if (positionalArgs(args, ["--agent-id", "--after-item", "--heartbeat-ms"]).length > 0) {
471
- throw new Error("usage: agentinbox inbox watch [--agent-id ID] [--after-item ID] [--include-acked] [--heartbeat-ms N]");
612
+ if (positionalArgs(args, ["--agent-id", "--after-entry", "--heartbeat-ms"]).length > 0) {
613
+ throw new Error("usage: agentinbox inbox watch [--agent-id ID] [--after-entry ID] [--include-acked] [--heartbeat-ms N]");
472
614
  }
473
615
  const selection = await selectAgentForCommand(client, {
474
616
  explicitAgentId: takeFlagValue(normalized, "--agent-id"),
@@ -481,7 +623,7 @@ async function main() {
481
623
  console.log((0, util_1.jsonResponse)(metadata));
482
624
  }
483
625
  for await (const event of client.watchInbox(selection.agentId, {
484
- afterItemId: takeFlagValue(normalized, "--after-item"),
626
+ afterEntryId: takeFlagValue(normalized, "--after-entry"),
485
627
  includeAcked: hasFlag(normalized, "--include-acked"),
486
628
  heartbeatMs: parseOptionalNumber(takeFlagValue(normalized, "--heartbeat-ms")),
487
629
  })) {
@@ -494,18 +636,41 @@ async function main() {
494
636
  }
495
637
  if (command === "inbox" && normalized[1] === "ack") {
496
638
  const args = normalized.slice(2);
497
- const itemId = takeFlagValue(normalized, "--item");
498
- const throughItemId = takeFlagValue(normalized, "--through");
639
+ const itemId = takeFlagValue(normalized, "--entry");
640
+ const throughEntryId = takeFlagValue(normalized, "--through");
499
641
  const ackAll = hasFlag(normalized, "--all");
500
- const modeCount = Number(Boolean(itemId)) + Number(Boolean(throughItemId)) + Number(ackAll);
501
- if (positionalArgs(args, ["--agent-id", "--item", "--through"]).length > 0 || modeCount !== 1) {
502
- throw new Error("usage: agentinbox inbox ack [--agent-id ID] (--through <itemId> | --item <itemId> | --all)");
642
+ const modeCount = Number(Boolean(itemId)) + Number(Boolean(throughEntryId)) + Number(ackAll);
643
+ if (positionalArgs(args, ["--agent-id", "--entry", "--through"]).length > 0 || modeCount !== 1) {
644
+ throw new Error("usage: agentinbox inbox ack [--agent-id ID] (--through <entryId> | --entry <entryId> | --all)");
503
645
  }
504
646
  const selection = await selectAgentForCommand(client, {
505
647
  explicitAgentId: takeFlagValue(normalized, "--agent-id"),
506
648
  autoRegister: true,
507
649
  });
508
- const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/ack`, ackAll ? { all: true } : (throughItemId ? { throughItemId } : { itemIds: [itemId] }));
650
+ const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/ack`, ackAll ? { all: true } : (throughEntryId ? { throughEntryId } : { entryIds: [itemId] }));
651
+ console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
652
+ return;
653
+ }
654
+ if (command === "inbox" && normalized[1] === "policy" && normalized[2] === "show") {
655
+ const selection = await selectAgentForCommand(client, {
656
+ explicitAgentId: takeFlagValue(normalized, "--agent-id"),
657
+ autoRegister: true,
658
+ });
659
+ const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/policy`, undefined, "GET");
660
+ console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
661
+ return;
662
+ }
663
+ if (command === "inbox" && normalized[1] === "policy" && normalized[2] === "set") {
664
+ const selection = await selectAgentForCommand(client, {
665
+ explicitAgentId: takeFlagValue(normalized, "--agent-id"),
666
+ autoRegister: true,
667
+ });
668
+ const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/policy`, {
669
+ enabled: hasFlag(normalized, "--enabled") ? true : (hasFlag(normalized, "--disabled") ? false : undefined),
670
+ windowMs: parseOptionalNumber(takeFlagValue(normalized, "--window-ms")),
671
+ maxItems: parseOptionalNumber(takeFlagValue(normalized, "--max-items")),
672
+ maxThreadAgeMs: parseOptionalNumber(takeFlagValue(normalized, "--max-thread-age-ms")),
673
+ });
509
674
  console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
510
675
  return;
511
676
  }
@@ -527,9 +692,10 @@ async function main() {
527
692
  const targetRef = takeFlagValue(normalized, "--target");
528
693
  const kind = takeFlagValue(normalized, "--kind") ?? "reply";
529
694
  if (!provider || !surface || !targetRef) {
530
- throw new Error("usage: agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--kind KIND] [--payload-json JSON]");
695
+ throw new Error("usage: agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--source-id SOURCE_ID] [--kind KIND] [--payload-json JSON]");
531
696
  }
532
697
  await printRemote(client, "/deliveries/send", {
698
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
533
699
  provider,
534
700
  surface,
535
701
  targetRef,
@@ -540,6 +706,58 @@ async function main() {
540
706
  });
541
707
  return;
542
708
  }
709
+ if (command === "deliver" && normalized[1] === "actions") {
710
+ const provider = takeFlagValue(normalized, "--provider");
711
+ const surface = takeFlagValue(normalized, "--surface");
712
+ const targetRef = takeFlagValue(normalized, "--target");
713
+ const handleJson = takeFlagValue(normalized, "--handle-json");
714
+ if (!handleJson && (!provider || !surface || !targetRef)) {
715
+ throw new Error("usage: agentinbox deliver actions (--handle-json JSON | --provider PROVIDER --surface SURFACE --target TARGET) [--source-id SOURCE_ID]");
716
+ }
717
+ await printRemote(client, "/deliveries/actions", handleJson
718
+ ? {
719
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
720
+ deliveryHandle: (0, util_1.parseJsonArg)(handleJson),
721
+ }
722
+ : {
723
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
724
+ provider,
725
+ surface,
726
+ targetRef,
727
+ threadRef: takeFlagValue(normalized, "--thread") ?? undefined,
728
+ replyMode: takeFlagValue(normalized, "--reply-mode") ?? undefined,
729
+ });
730
+ return;
731
+ }
732
+ if (command === "deliver" && normalized[1] === "invoke") {
733
+ const provider = takeFlagValue(normalized, "--provider");
734
+ const surface = takeFlagValue(normalized, "--surface");
735
+ const targetRef = takeFlagValue(normalized, "--target");
736
+ const handleJson = takeFlagValue(normalized, "--handle-json");
737
+ const operation = takeFlagValue(normalized, "--operation");
738
+ const inputJson = takeFlagValue(normalized, "--input-json");
739
+ if (!operation || !inputJson || (!handleJson && (!provider || !surface || !targetRef))) {
740
+ throw new Error("usage: agentinbox deliver invoke (--handle-json JSON | --provider PROVIDER --surface SURFACE --target TARGET) --operation NAME --input-json JSON [--source-id SOURCE_ID]");
741
+ }
742
+ await printRemote(client, "/deliveries/invoke", handleJson
743
+ ? {
744
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
745
+ deliveryHandle: (0, util_1.parseJsonArg)(handleJson),
746
+ operation,
747
+ input: (0, util_1.parseJsonArg)(inputJson, "--input-json"),
748
+ }
749
+ : {
750
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
751
+ provider,
752
+ surface,
753
+ targetRef,
754
+ threadRef: takeFlagValue(normalized, "--thread") ?? undefined,
755
+ replyMode: takeFlagValue(normalized, "--reply-mode") ?? undefined,
756
+ operation,
757
+ input: (0, util_1.parseJsonArg)(inputJson, "--input-json"),
758
+ });
759
+ return;
760
+ }
543
761
  if (command === "status") {
544
762
  await printRemote(client, "/status", undefined, "GET");
545
763
  return;
@@ -552,7 +770,7 @@ async function main() {
552
770
  printHelp([command]);
553
771
  return;
554
772
  }
555
- throw new Error(`unknown command: ${args.join(" ")}`);
773
+ throw new Error(`unknown command: ${normalized.join(" ")}`);
556
774
  }
557
775
  async function runServe(args) {
558
776
  const port = parseOptionalNumber(takeFlagValue(args, "--port"));
@@ -785,6 +1003,26 @@ function normalizeHelpArgs(args) {
785
1003
  }
786
1004
  return [args[1], "--help"];
787
1005
  }
1006
+ function stripNoopJsonFlag(args) {
1007
+ return args.filter((arg) => arg !== "--json");
1008
+ }
1009
+ function shouldTreatJsonFlagAsNoop(args) {
1010
+ if (!args.includes("--json")) {
1011
+ return false;
1012
+ }
1013
+ const command = args[0];
1014
+ if (!command) {
1015
+ return false;
1016
+ }
1017
+ if (args.includes("--help") || args.includes("-h")) {
1018
+ return false;
1019
+ }
1020
+ return command !== "help" &&
1021
+ command !== "version" &&
1022
+ command !== "--version" &&
1023
+ command !== "-v" &&
1024
+ command !== "serve";
1025
+ }
788
1026
  function hasHelpFlag(args) {
789
1027
  return args.includes("--help") || args.includes("-h");
790
1028
  }
@@ -832,6 +1070,19 @@ function withCommandMetadata(data, selection) {
832
1070
  ...(selection.warnings.length > 0 ? { warnings: selection.warnings } : {}),
833
1071
  };
834
1072
  }
1073
+ function normalizeSubscriptionAddOutput(data, shortcutUsed) {
1074
+ if (shortcutUsed) {
1075
+ return data;
1076
+ }
1077
+ const subscriptions = data.subscriptions;
1078
+ if (Array.isArray(subscriptions) &&
1079
+ subscriptions.length === 1 &&
1080
+ subscriptions[0] &&
1081
+ typeof subscriptions[0] === "object") {
1082
+ return subscriptions[0];
1083
+ }
1084
+ return data;
1085
+ }
835
1086
  function getRequiredTerminalContext() {
836
1087
  try {
837
1088
  return (0, terminal_1.detectTerminalContext)(process.env);
@@ -910,32 +1161,54 @@ Usage:
910
1161
  agentinbox daemon start [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock] [--log-level error|warn|info|debug|trace]
911
1162
  agentinbox daemon stop [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock]
912
1163
  agentinbox daemon status [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock]
1164
+ `,
1165
+ host: `agentinbox host
1166
+
1167
+ Usage:
1168
+ agentinbox host add <hostType> <hostKey> [--config-json JSON] [--config-ref REF]
1169
+ agentinbox host list
1170
+ agentinbox host show <hostId>
1171
+ agentinbox host schema <hostId>
1172
+ `,
1173
+ stream: `agentinbox stream
1174
+
1175
+ Usage:
1176
+ agentinbox stream add <hostId> <streamKind> <streamKey> [--config-json JSON] [--config-ref REF]
1177
+ agentinbox stream list
1178
+ agentinbox stream show <streamId>
1179
+ agentinbox stream update <streamId> [--config-json JSON] [--config-ref REF | --clear-config-ref]
1180
+ agentinbox stream remove <streamId> [--with-subscriptions]
1181
+ agentinbox stream pause <streamId>
1182
+ agentinbox stream resume <streamId>
1183
+ agentinbox stream schema <streamId>
1184
+ agentinbox stream schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]
1185
+ agentinbox stream poll <streamId>
1186
+ agentinbox stream event <streamId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]
913
1187
  `,
914
1188
  source: `agentinbox source
915
1189
 
916
1190
  Usage:
917
- agentinbox source add <type> <sourceKey> [--config-json JSON] [--config-ref REF]
1191
+ agentinbox source add <hostId> <streamKind> <streamKey> [--config-json JSON] [--config-ref REF]
918
1192
  agentinbox source list
919
1193
  agentinbox source show <sourceId>
920
1194
  agentinbox source update <sourceId> [--config-json JSON] [--config-ref REF | --clear-config-ref]
921
1195
  agentinbox source remove <sourceId> [--with-subscriptions]
922
1196
  agentinbox source pause <remoteSourceId>
923
1197
  agentinbox source resume <remoteSourceId>
924
- agentinbox source schema <sourceId|sourceType>
925
- agentinbox source schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]
1198
+ agentinbox source schema <sourceId>
926
1199
  agentinbox source poll <sourceId>
927
1200
  agentinbox source event <sourceId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]
928
1201
  `,
929
1202
  agent: `agentinbox agent
930
1203
 
931
1204
  Usage:
932
- agentinbox agent register [--agent-id ID] [--force-rebind] [--notify-lease-ms N]
1205
+ agentinbox agent register [--agent-id ID] [--force-rebind] [--notify-lease-ms N] [--min-unacked-items N]
933
1206
  agentinbox agent list
934
1207
  agentinbox agent current
935
1208
  agentinbox agent show <agentId>
936
1209
  agentinbox agent remove <agentId>
937
1210
  agentinbox agent resume <agentId>
938
- agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N]
1211
+ agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N] [--min-unacked-items N]
939
1212
  agentinbox agent target list <agentId>
940
1213
  agentinbox agent target remove <agentId> <targetId>
941
1214
  agentinbox agent target resume <agentId> <targetId>
@@ -965,16 +1238,20 @@ Usage:
965
1238
  Usage:
966
1239
  agentinbox inbox list
967
1240
  agentinbox inbox show <agentId>
968
- agentinbox inbox read [--agent-id ID] [--after-item ID] [--include-acked]
1241
+ agentinbox inbox read [--agent-id ID] [--after-entry ID] [--include-acked]
969
1242
  agentinbox inbox send --agent-id ID --message TEXT [--sender SENDER]
970
- agentinbox inbox watch [--agent-id ID] [--after-item ID] [--include-acked] [--heartbeat-ms N]
971
- agentinbox inbox ack [--agent-id ID] (--through <itemId> | --item <itemId> | --all)
1243
+ agentinbox inbox watch [--agent-id ID] [--after-entry ID] [--include-acked] [--heartbeat-ms N]
1244
+ agentinbox inbox ack [--agent-id ID] (--through <entryId> | --entry <entryId> | --all)
1245
+ agentinbox inbox policy show [--agent-id ID]
1246
+ agentinbox inbox policy set [--agent-id ID] [--enabled|--disabled] [--window-ms N] [--max-items N] [--max-thread-age-ms N]
972
1247
  agentinbox inbox compact <agentId>
973
1248
  `,
974
1249
  deliver: `agentinbox deliver
975
1250
 
976
1251
  Usage:
977
- agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--kind KIND] [--payload-json JSON]
1252
+ agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--source-id SOURCE_ID] [--kind KIND] [--payload-json JSON]
1253
+ agentinbox deliver actions (--handle-json JSON | --provider PROVIDER --surface SURFACE --target TARGET) [--source-id SOURCE_ID]
1254
+ agentinbox deliver invoke (--handle-json JSON | --provider PROVIDER --surface SURFACE --target TARGET) --operation NAME --input-json JSON [--source-id SOURCE_ID]
978
1255
  `,
979
1256
  status: `agentinbox status
980
1257
 
@@ -19,8 +19,8 @@ class AgentInboxClient {
19
19
  }
20
20
  watchInbox(agentId, options = {}) {
21
21
  const query = new URLSearchParams();
22
- if (options.afterItemId) {
23
- query.set("after_item_id", options.afterItemId);
22
+ if (options.afterEntryId) {
23
+ query.set("after_entry_id", options.afterEntryId);
24
24
  }
25
25
  if (options.includeAcked) {
26
26
  query.set("include_acked", "true");