@holon-run/agentinbox 0.7.0 → 1.0.0-beta.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/README.md CHANGED
@@ -64,6 +64,22 @@ manually or relying on the agent runtime to expose its own notification API.
64
64
  - filtering and source model are still evolving
65
65
  - first-run onboarding is currently skill-first rather than wizard-first
66
66
 
67
+ ## v1.0.0 Beta Upgrade Notes
68
+
69
+ `v1.0.0-beta.0` is the first release on the final v1 storage and API boundary.
70
+
71
+ - pre-v1 local databases are archived and replaced with a fresh v1 database
72
+ - old local state is not imported into the new v1 database
73
+ - canonical public surfaces are now host + stream registration, entry/thread
74
+ inbox reads, and handle-scoped delivery operations
75
+ - pre-v1 compatibility shims such as legacy source-kind registration aliases,
76
+ raw inbox-item read paths, and deprecated remote-module aliases are no longer
77
+ part of the supported surface
78
+
79
+ If you are upgrading from any pre-v1 build, expect `AgentInbox` to archive the
80
+ existing local database under `~/.agentinbox/` and start with a fresh v1
81
+ database.
82
+
67
83
  ## Install
68
84
 
69
85
  Requires:
@@ -127,13 +143,21 @@ Register the current terminal session:
127
143
  ```bash
128
144
  agentinbox agent register
129
145
  agentinbox agent register --agent-id agent-alpha
146
+ agentinbox agent register --notify-lease-ms 600000 --min-unacked-items 5
130
147
  agentinbox agent current
131
148
  ```
132
149
 
150
+ `notifyLeaseMs` and `minUnackedItems` are target-facing notification policy:
151
+ they control how often a target may be reminded and how many unacked items must
152
+ accumulate before AgentInbox notifies it. Service-wide activation batching
153
+ (`windowMs`, `maxItems`) and terminal gating heuristics remain daemon-level
154
+ policy, not per-agent knobs.
155
+
133
156
  Create a local source and publish an event:
134
157
 
135
158
  ```bash
136
- agentinbox source add local_event local-demo
159
+ agentinbox host add local_event local-demo
160
+ agentinbox source add <host_id> events local-demo
137
161
  agentinbox subscription add <source_id>
138
162
  agentinbox subscription add <source_id> --agent-id <agent_id>
139
163
  agentinbox source schema <source_id>
@@ -144,10 +168,10 @@ cat filter.json | agentinbox subscription add <source_id> --filter-stdin
144
168
  agentinbox source event <source_id> --native-id demo-1 --event local.demo
145
169
  agentinbox inbox read
146
170
  agentinbox inbox read --agent-id <agent_id>
147
- agentinbox inbox ack --agent-id <agent_id> --through <last_item_id>
171
+ agentinbox inbox ack --agent-id <agent_id> --through <last_entry_id>
148
172
  ```
149
173
 
150
- When acking a reviewed batch, prefer `--through <last_item_id>` over `--all`.
174
+ When acking a reviewed batch, prefer `--through <last_entry_id>` over `--all`.
151
175
  That preserves the boundary of the items you actually inspected. Use
152
176
  `ack --all` only when you have intentionally verified that every current
153
177
  unacked item should be cleared.
@@ -257,10 +281,11 @@ Generate new SQLite migrations after schema changes:
257
281
  npm run db:migrations:generate
258
282
  ```
259
283
 
260
- `AgentInbox` now upgrades SQLite state with versioned SQL migrations in
261
- `drizzle/migrations`. On upgrade with pending migrations, the daemon creates a
262
- local backup next to the DB file (for example,
263
- `~/.agentinbox/agentinbox.sqlite.backup-<timestamp>`).
284
+ `AgentInbox` now initializes SQLite state from a single v1 baseline migration in
285
+ `drizzle/migrations`. If startup detects a pre-v1 local database, it archives
286
+ that database next to the DB path (for example,
287
+ `~/.agentinbox/agentinbox.sqlite.pre-v1.<timestamp>.bak`) and starts with a
288
+ fresh v1 database; pre-v1 local data is not imported.
264
289
 
265
290
  ## License
266
291
 
@@ -146,10 +146,65 @@ class AdapterRegistry {
146
146
  }
147
147
  return this.remoteSource.deriveInlinePreview(source, item);
148
148
  }
149
+ async deriveNotificationGrouping(source, item) {
150
+ if (source.sourceType === "local_event") {
151
+ return null;
152
+ }
153
+ return this.remoteSource.deriveNotificationGrouping(source, item);
154
+ }
155
+ async summarizeDigestThread(source, items, grouping) {
156
+ if (source.sourceType === "local_event") {
157
+ return null;
158
+ }
159
+ return this.remoteSource.summarizeDigestThread(source, items, grouping);
160
+ }
161
+ async listDeliveryOperations(source, handle) {
162
+ const module = await this.resolveDeliveryModule(source, handle);
163
+ if (!module?.listDeliveryOperations) {
164
+ return [];
165
+ }
166
+ return module.listDeliveryOperations({ handle, source });
167
+ }
168
+ async invokeDeliveryOperation(source, handle, operation, input, attempt) {
169
+ const module = await this.resolveDeliveryModule(source, handle);
170
+ if (!module?.invokeDeliveryOperation) {
171
+ throw new Error(`delivery operations are not supported for provider ${handle.provider}`);
172
+ }
173
+ return module.invokeDeliveryOperation({ handle, operation, input, attempt, source });
174
+ }
149
175
  status() {
150
176
  return {
151
177
  remote: this.remoteSource.status?.() ?? {},
152
178
  };
153
179
  }
180
+ async resolveDeliveryModule(source, handle) {
181
+ if (source) {
182
+ if (source.sourceType === "local_event") {
183
+ return null;
184
+ }
185
+ return this.remoteModuleRegistry.resolve(source, this.homeDir);
186
+ }
187
+ if (handle.provider === "github") {
188
+ return this.remoteModuleRegistry.resolve(syntheticBuiltinSource("github_repo"), this.homeDir);
189
+ }
190
+ if (handle.provider === "feishu") {
191
+ return this.remoteModuleRegistry.resolve(syntheticBuiltinSource("feishu_bot"), this.homeDir);
192
+ }
193
+ return null;
194
+ }
154
195
  }
155
196
  exports.AdapterRegistry = AdapterRegistry;
197
+ function syntheticBuiltinSource(sourceType) {
198
+ return {
199
+ sourceId: `builtin:${sourceType}`,
200
+ hostId: `builtin-host:${sourceType}`,
201
+ streamKind: sourceType === "github_repo" ? "repo_events" : "message_events",
202
+ streamKey: sourceType,
203
+ sourceType,
204
+ sourceKey: sourceType,
205
+ status: "active",
206
+ createdAt: "",
207
+ updatedAt: "",
208
+ config: {},
209
+ };
210
+ }
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SqliteEventBusBackend = void 0;
4
- exports.streamIdForSource = streamIdForSource;
5
- exports.consumerIdForSubscription = consumerIdForSubscription;
6
- exports.defaultInboxIdForAgent = defaultInboxIdForAgent;
7
4
  exports.streamKeyForSource = streamKeyForSource;
8
5
  exports.toAppendResult = toAppendResult;
9
6
  const util_1 = require("./util");
@@ -18,7 +15,7 @@ class SqliteEventBusBackend {
18
15
  return existing;
19
16
  }
20
17
  const stream = {
21
- streamId: streamIdForSource(input.sourceId),
18
+ streamId: (0, util_1.generateCanonicalId)("str"),
22
19
  sourceId: input.sourceId,
23
20
  streamKey: input.streamKey,
24
21
  backend: input.backend,
@@ -46,7 +43,7 @@ class SqliteEventBusBackend {
46
43
  }
47
44
  const nextOffset = this.resolveInitialOffset(input.streamId, input.startPolicy, input.startOffset ?? null, input.startTime ?? null);
48
45
  const consumer = {
49
- consumerId: consumerIdForSubscription(input.subscriptionId),
46
+ consumerId: (0, util_1.generateCanonicalId)("con"),
50
47
  streamId: input.streamId,
51
48
  subscriptionId: input.subscriptionId,
52
49
  consumerKey: input.consumerKey,
@@ -154,17 +151,8 @@ class SqliteEventBusBackend {
154
151
  }
155
152
  }
156
153
  exports.SqliteEventBusBackend = SqliteEventBusBackend;
157
- function streamIdForSource(sourceId) {
158
- return `stream_${sourceId}`;
159
- }
160
- function consumerIdForSubscription(subscriptionId) {
161
- return `consumer_${subscriptionId}`;
162
- }
163
- function defaultInboxIdForAgent(agentId) {
164
- return `inbox_${agentId}`;
165
- }
166
- function streamKeyForSource(sourceType, sourceKey) {
167
- return `${sourceType}:${sourceKey}`;
154
+ function streamKeyForSource(sourceId) {
155
+ return `source:${sourceId}`;
168
156
  }
169
157
  function toAppendResult(result) {
170
158
  return {
package/dist/src/cli.js CHANGED
@@ -51,14 +51,167 @@ async function main() {
51
51
  return;
52
52
  }
53
53
  const client = await createClient(normalized);
54
+ if (command === "host" && normalized[1] === "add") {
55
+ const [hostType, hostKey] = normalized.slice(2, 4);
56
+ if (!hostType || !hostKey) {
57
+ throw new Error("usage: agentinbox host add <hostType> <hostKey> [--config-json JSON] [--config-ref REF]");
58
+ }
59
+ await printRemote(client, "/hosts", {
60
+ hostType,
61
+ hostKey,
62
+ configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
63
+ config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
64
+ });
65
+ return;
66
+ }
67
+ if (command === "host" && normalized[1] === "list") {
68
+ await printRemote(client, "/hosts", undefined, "GET");
69
+ return;
70
+ }
71
+ if (command === "host" && normalized[1] === "show") {
72
+ const hostId = normalized[2];
73
+ if (!hostId) {
74
+ throw new Error("usage: agentinbox host show <hostId>");
75
+ }
76
+ await printRemote(client, `/hosts/${encodeURIComponent(hostId)}`, undefined, "GET");
77
+ return;
78
+ }
79
+ if (command === "host" && normalized[1] === "schema") {
80
+ const hostId = normalized[2];
81
+ if (!hostId) {
82
+ throw new Error("usage: agentinbox host schema <hostId>");
83
+ }
84
+ await printRemote(client, `/hosts/${encodeURIComponent(hostId)}/schema`, undefined, "GET");
85
+ return;
86
+ }
87
+ if (command === "stream" && normalized[1] === "add") {
88
+ const [hostId, streamKind, streamKey] = normalized.slice(2, 5);
89
+ if (!hostId || !streamKind || !streamKey) {
90
+ throw new Error("usage: agentinbox stream add <hostId> <streamKind> <streamKey> [--config-json JSON] [--config-ref REF]");
91
+ }
92
+ await printRemote(client, "/streams", {
93
+ hostId,
94
+ streamKind,
95
+ streamKey,
96
+ configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
97
+ config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
98
+ });
99
+ return;
100
+ }
101
+ if (command === "stream" && normalized[1] === "list") {
102
+ await printRemote(client, "/streams", undefined, "GET");
103
+ return;
104
+ }
105
+ if (command === "stream" && normalized[1] === "show") {
106
+ const streamId = normalized[2];
107
+ if (!streamId) {
108
+ throw new Error("usage: agentinbox stream show <streamId>");
109
+ }
110
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}`, undefined, "GET");
111
+ return;
112
+ }
113
+ if (command === "stream" && normalized[1] === "remove") {
114
+ const removeArgs = normalized.slice(2);
115
+ const positionals = positionalArgs(removeArgs, ["--with-subscriptions"]);
116
+ const streamId = positionals[0];
117
+ if (!streamId || positionals[1]) {
118
+ throw new Error("usage: agentinbox stream remove <streamId> [--with-subscriptions]");
119
+ }
120
+ const query = buildQuery({
121
+ with_subscriptions: hasFlag(normalized, "--with-subscriptions") ? "true" : undefined,
122
+ });
123
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}${query}`, undefined, "DELETE");
124
+ return;
125
+ }
126
+ if (command === "stream" && normalized[1] === "update") {
127
+ const streamId = normalized[2];
128
+ if (!streamId) {
129
+ throw new Error("usage: agentinbox stream update <streamId> [--config-json JSON] [--config-ref REF | --clear-config-ref]");
130
+ }
131
+ const configRef = takeFlagValue(normalized, "--config-ref");
132
+ const clearConfigRef = hasFlag(normalized, "--clear-config-ref");
133
+ const configJson = takeFlagValue(normalized, "--config-json");
134
+ if (configRef != null && clearConfigRef) {
135
+ throw new Error("stream update accepts only one of --config-ref or --clear-config-ref");
136
+ }
137
+ if (!clearConfigRef && configRef == null && configJson == null) {
138
+ throw new Error("usage: agentinbox stream update <streamId> [--config-json JSON] [--config-ref REF | --clear-config-ref]");
139
+ }
140
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}`, {
141
+ ...(clearConfigRef ? { configRef: null } : (configRef != null ? { configRef } : {})),
142
+ config: configJson != null ? (0, util_1.parseJsonArg)(configJson, "--config-json") : undefined,
143
+ }, "PATCH");
144
+ return;
145
+ }
146
+ if (command === "stream" && normalized[1] === "pause") {
147
+ const streamId = normalized[2];
148
+ if (!streamId) {
149
+ throw new Error("usage: agentinbox stream pause <streamId>");
150
+ }
151
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}/pause`, {});
152
+ return;
153
+ }
154
+ if (command === "stream" && normalized[1] === "resume") {
155
+ const streamId = normalized[2];
156
+ if (!streamId) {
157
+ throw new Error("usage: agentinbox stream resume <streamId>");
158
+ }
159
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}/resume`, {});
160
+ return;
161
+ }
162
+ if (command === "stream" && normalized[1] === "schema") {
163
+ if (normalized[2] === "preview") {
164
+ const sourceRef = normalized[3];
165
+ if (!sourceRef) {
166
+ throw new Error("usage: agentinbox stream schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]");
167
+ }
168
+ await printRemote(client, "/streams/schema-preview", {
169
+ sourceRef,
170
+ configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
171
+ config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
172
+ });
173
+ return;
174
+ }
175
+ const streamRef = normalized[2];
176
+ if (!streamRef) {
177
+ throw new Error("usage: agentinbox stream schema <streamId>");
178
+ }
179
+ await printRemote(client, `/streams/${encodeURIComponent(streamRef)}/schema`, undefined, "GET");
180
+ return;
181
+ }
182
+ if (command === "stream" && normalized[1] === "poll") {
183
+ const streamId = normalized[2];
184
+ if (!streamId) {
185
+ throw new Error("usage: agentinbox stream poll <streamId>");
186
+ }
187
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}/poll`, {});
188
+ return;
189
+ }
190
+ if (command === "stream" && normalized[1] === "event") {
191
+ const streamId = normalized[2];
192
+ const sourceNativeId = takeFlagValue(normalized, "--native-id");
193
+ const eventVariant = takeFlagValue(normalized, "--event");
194
+ if (!streamId || !sourceNativeId || !eventVariant) {
195
+ throw new Error("usage: agentinbox stream event <streamId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]");
196
+ }
197
+ await printRemote(client, `/streams/${encodeURIComponent(streamId)}/events`, {
198
+ sourceNativeId,
199
+ eventVariant,
200
+ occurredAt: takeFlagValue(normalized, "--occurred-at") ?? undefined,
201
+ metadata: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--metadata-json")),
202
+ rawPayload: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--payload-json")),
203
+ });
204
+ return;
205
+ }
54
206
  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]");
207
+ const [hostId, streamKind, streamKey] = normalized.slice(2, 5);
208
+ if (!hostId || !streamKind || !streamKey) {
209
+ throw new Error("usage: agentinbox source add <hostId> <streamKind> <streamKey> [--config-json JSON] [--config-ref REF]");
58
210
  }
59
211
  await printRemote(client, "/sources", {
60
- sourceType: type,
61
- sourceKey,
212
+ hostId,
213
+ streamKind,
214
+ streamKey,
62
215
  configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
63
216
  config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
64
217
  });
@@ -126,27 +279,11 @@ async function main() {
126
279
  return;
127
280
  }
128
281
  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
282
  const sourceRef = normalized[2];
142
283
  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;
284
+ throw new Error("usage: agentinbox source schema <sourceId>");
148
285
  }
149
- await printRemote(client, `/source-types/${encodeURIComponent(sourceRef)}/schema`, undefined, "GET");
286
+ await printRemote(client, `/sources/${encodeURIComponent(sourceRef)}/schema`, undefined, "GET");
150
287
  return;
151
288
  }
152
289
  if (command === "source" && normalized[1] === "poll") {
@@ -187,6 +324,7 @@ async function main() {
187
324
  termProgram: detected.termProgram ?? undefined,
188
325
  itermSessionId: detected.itermSessionId ?? undefined,
189
326
  notifyLeaseMs: parseOptionalNumber(takeFlagValue(normalized, "--notify-lease-ms")) ?? undefined,
327
+ minUnackedItems: parseOptionalNumber(takeFlagValue(normalized, "--min-unacked-items")) ?? undefined,
190
328
  });
191
329
  return;
192
330
  }
@@ -226,13 +364,14 @@ async function main() {
226
364
  const agentId = normalized[4];
227
365
  const url = takeFlagValue(normalized, "--url");
228
366
  if (!agentId || !url) {
229
- throw new Error("usage: agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N]");
367
+ throw new Error("usage: agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N] [--min-unacked-items N]");
230
368
  }
231
369
  await printRemote(client, `/agents/${encodeURIComponent(agentId)}/targets`, {
232
370
  kind: "webhook",
233
371
  url,
234
372
  activationMode: takeFlagValue(normalized, "--activation-mode") ?? undefined,
235
373
  notifyLeaseMs: parseOptionalNumber(takeFlagValue(normalized, "--notify-lease-ms")) ?? undefined,
374
+ minUnackedItems: parseOptionalNumber(takeFlagValue(normalized, "--min-unacked-items")) ?? undefined,
236
375
  });
237
376
  return;
238
377
  }
@@ -432,19 +571,19 @@ async function main() {
432
571
  }
433
572
  if (command === "inbox" && normalized[1] === "read") {
434
573
  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]");
574
+ const allowedFlags = ["--agent-id", "--after-entry", "--include-acked"];
575
+ if (positionalArgs(args, ["--agent-id", "--after-entry"]).length > 0 || unexpectedFlags(args, allowedFlags).length > 0) {
576
+ throw new Error("usage: agentinbox inbox read [--agent-id ID] [--after-entry ID] [--include-acked]");
438
577
  }
439
578
  const selection = await selectAgentForCommand(client, {
440
579
  explicitAgentId: takeFlagValue(normalized, "--agent-id"),
441
580
  autoRegister: true,
442
581
  });
443
582
  const query = buildQuery({
444
- after_item_id: takeFlagValue(normalized, "--after-item"),
583
+ after_entry_id: takeFlagValue(normalized, "--after-entry"),
445
584
  include_acked: hasFlag(normalized, "--include-acked") ? "true" : undefined,
446
585
  });
447
- const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/items${query}`, undefined, "GET");
586
+ const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/entries${query}`, undefined, "GET");
448
587
  console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
449
588
  return;
450
589
  }
@@ -467,8 +606,8 @@ async function main() {
467
606
  }
468
607
  if (command === "inbox" && normalized[1] === "watch") {
469
608
  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]");
609
+ if (positionalArgs(args, ["--agent-id", "--after-entry", "--heartbeat-ms"]).length > 0) {
610
+ throw new Error("usage: agentinbox inbox watch [--agent-id ID] [--after-entry ID] [--include-acked] [--heartbeat-ms N]");
472
611
  }
473
612
  const selection = await selectAgentForCommand(client, {
474
613
  explicitAgentId: takeFlagValue(normalized, "--agent-id"),
@@ -481,7 +620,7 @@ async function main() {
481
620
  console.log((0, util_1.jsonResponse)(metadata));
482
621
  }
483
622
  for await (const event of client.watchInbox(selection.agentId, {
484
- afterItemId: takeFlagValue(normalized, "--after-item"),
623
+ afterEntryId: takeFlagValue(normalized, "--after-entry"),
485
624
  includeAcked: hasFlag(normalized, "--include-acked"),
486
625
  heartbeatMs: parseOptionalNumber(takeFlagValue(normalized, "--heartbeat-ms")),
487
626
  })) {
@@ -494,18 +633,41 @@ async function main() {
494
633
  }
495
634
  if (command === "inbox" && normalized[1] === "ack") {
496
635
  const args = normalized.slice(2);
497
- const itemId = takeFlagValue(normalized, "--item");
498
- const throughItemId = takeFlagValue(normalized, "--through");
636
+ const itemId = takeFlagValue(normalized, "--entry");
637
+ const throughEntryId = takeFlagValue(normalized, "--through");
499
638
  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)");
639
+ const modeCount = Number(Boolean(itemId)) + Number(Boolean(throughEntryId)) + Number(ackAll);
640
+ if (positionalArgs(args, ["--agent-id", "--entry", "--through"]).length > 0 || modeCount !== 1) {
641
+ throw new Error("usage: agentinbox inbox ack [--agent-id ID] (--through <entryId> | --entry <entryId> | --all)");
503
642
  }
504
643
  const selection = await selectAgentForCommand(client, {
505
644
  explicitAgentId: takeFlagValue(normalized, "--agent-id"),
506
645
  autoRegister: true,
507
646
  });
508
- const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/ack`, ackAll ? { all: true } : (throughItemId ? { throughItemId } : { itemIds: [itemId] }));
647
+ const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/ack`, ackAll ? { all: true } : (throughEntryId ? { throughEntryId } : { entryIds: [itemId] }));
648
+ console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
649
+ return;
650
+ }
651
+ if (command === "inbox" && normalized[1] === "policy" && normalized[2] === "show") {
652
+ const selection = await selectAgentForCommand(client, {
653
+ explicitAgentId: takeFlagValue(normalized, "--agent-id"),
654
+ autoRegister: true,
655
+ });
656
+ const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/policy`, undefined, "GET");
657
+ console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
658
+ return;
659
+ }
660
+ if (command === "inbox" && normalized[1] === "policy" && normalized[2] === "set") {
661
+ const selection = await selectAgentForCommand(client, {
662
+ explicitAgentId: takeFlagValue(normalized, "--agent-id"),
663
+ autoRegister: true,
664
+ });
665
+ const response = await requestRemote(client, `/agents/${encodeURIComponent(selection.agentId)}/inbox/policy`, {
666
+ enabled: hasFlag(normalized, "--enabled") ? true : (hasFlag(normalized, "--disabled") ? false : undefined),
667
+ windowMs: parseOptionalNumber(takeFlagValue(normalized, "--window-ms")),
668
+ maxItems: parseOptionalNumber(takeFlagValue(normalized, "--max-items")),
669
+ maxThreadAgeMs: parseOptionalNumber(takeFlagValue(normalized, "--max-thread-age-ms")),
670
+ });
509
671
  console.log((0, util_1.jsonResponse)(withCommandMetadata(response.data, selection)));
510
672
  return;
511
673
  }
@@ -527,9 +689,10 @@ async function main() {
527
689
  const targetRef = takeFlagValue(normalized, "--target");
528
690
  const kind = takeFlagValue(normalized, "--kind") ?? "reply";
529
691
  if (!provider || !surface || !targetRef) {
530
- throw new Error("usage: agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--kind KIND] [--payload-json JSON]");
692
+ throw new Error("usage: agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--source-id SOURCE_ID] [--kind KIND] [--payload-json JSON]");
531
693
  }
532
694
  await printRemote(client, "/deliveries/send", {
695
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
533
696
  provider,
534
697
  surface,
535
698
  targetRef,
@@ -540,6 +703,58 @@ async function main() {
540
703
  });
541
704
  return;
542
705
  }
706
+ if (command === "deliver" && normalized[1] === "actions") {
707
+ const provider = takeFlagValue(normalized, "--provider");
708
+ const surface = takeFlagValue(normalized, "--surface");
709
+ const targetRef = takeFlagValue(normalized, "--target");
710
+ const handleJson = takeFlagValue(normalized, "--handle-json");
711
+ if (!handleJson && (!provider || !surface || !targetRef)) {
712
+ throw new Error("usage: agentinbox deliver actions (--handle-json JSON | --provider PROVIDER --surface SURFACE --target TARGET) [--source-id SOURCE_ID]");
713
+ }
714
+ await printRemote(client, "/deliveries/actions", handleJson
715
+ ? {
716
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
717
+ deliveryHandle: (0, util_1.parseJsonArg)(handleJson),
718
+ }
719
+ : {
720
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
721
+ provider,
722
+ surface,
723
+ targetRef,
724
+ threadRef: takeFlagValue(normalized, "--thread") ?? undefined,
725
+ replyMode: takeFlagValue(normalized, "--reply-mode") ?? undefined,
726
+ });
727
+ return;
728
+ }
729
+ if (command === "deliver" && normalized[1] === "invoke") {
730
+ const provider = takeFlagValue(normalized, "--provider");
731
+ const surface = takeFlagValue(normalized, "--surface");
732
+ const targetRef = takeFlagValue(normalized, "--target");
733
+ const handleJson = takeFlagValue(normalized, "--handle-json");
734
+ const operation = takeFlagValue(normalized, "--operation");
735
+ const inputJson = takeFlagValue(normalized, "--input-json");
736
+ if (!operation || !inputJson || (!handleJson && (!provider || !surface || !targetRef))) {
737
+ 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]");
738
+ }
739
+ await printRemote(client, "/deliveries/invoke", handleJson
740
+ ? {
741
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
742
+ deliveryHandle: (0, util_1.parseJsonArg)(handleJson),
743
+ operation,
744
+ input: (0, util_1.parseJsonArg)(inputJson, "--input-json"),
745
+ }
746
+ : {
747
+ sourceId: takeFlagValue(normalized, "--source-id") ?? undefined,
748
+ provider,
749
+ surface,
750
+ targetRef,
751
+ threadRef: takeFlagValue(normalized, "--thread") ?? undefined,
752
+ replyMode: takeFlagValue(normalized, "--reply-mode") ?? undefined,
753
+ operation,
754
+ input: (0, util_1.parseJsonArg)(inputJson, "--input-json"),
755
+ });
756
+ return;
757
+ }
543
758
  if (command === "status") {
544
759
  await printRemote(client, "/status", undefined, "GET");
545
760
  return;
@@ -910,32 +1125,54 @@ Usage:
910
1125
  agentinbox daemon start [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock] [--log-level error|warn|info|debug|trace]
911
1126
  agentinbox daemon stop [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock]
912
1127
  agentinbox daemon status [--home ~/.agentinbox] [--socket ~/.agentinbox/agentinbox.sock]
1128
+ `,
1129
+ host: `agentinbox host
1130
+
1131
+ Usage:
1132
+ agentinbox host add <hostType> <hostKey> [--config-json JSON] [--config-ref REF]
1133
+ agentinbox host list
1134
+ agentinbox host show <hostId>
1135
+ agentinbox host schema <hostId>
1136
+ `,
1137
+ stream: `agentinbox stream
1138
+
1139
+ Usage:
1140
+ agentinbox stream add <hostId> <streamKind> <streamKey> [--config-json JSON] [--config-ref REF]
1141
+ agentinbox stream list
1142
+ agentinbox stream show <streamId>
1143
+ agentinbox stream update <streamId> [--config-json JSON] [--config-ref REF | --clear-config-ref]
1144
+ agentinbox stream remove <streamId> [--with-subscriptions]
1145
+ agentinbox stream pause <streamId>
1146
+ agentinbox stream resume <streamId>
1147
+ agentinbox stream schema <streamId>
1148
+ agentinbox stream schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]
1149
+ agentinbox stream poll <streamId>
1150
+ agentinbox stream event <streamId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]
913
1151
  `,
914
1152
  source: `agentinbox source
915
1153
 
916
1154
  Usage:
917
- agentinbox source add <type> <sourceKey> [--config-json JSON] [--config-ref REF]
1155
+ agentinbox source add <hostId> <streamKind> <streamKey> [--config-json JSON] [--config-ref REF]
918
1156
  agentinbox source list
919
1157
  agentinbox source show <sourceId>
920
1158
  agentinbox source update <sourceId> [--config-json JSON] [--config-ref REF | --clear-config-ref]
921
1159
  agentinbox source remove <sourceId> [--with-subscriptions]
922
1160
  agentinbox source pause <remoteSourceId>
923
1161
  agentinbox source resume <remoteSourceId>
924
- agentinbox source schema <sourceId|sourceType>
925
- agentinbox source schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]
1162
+ agentinbox source schema <sourceId>
926
1163
  agentinbox source poll <sourceId>
927
1164
  agentinbox source event <sourceId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]
928
1165
  `,
929
1166
  agent: `agentinbox agent
930
1167
 
931
1168
  Usage:
932
- agentinbox agent register [--agent-id ID] [--force-rebind] [--notify-lease-ms N]
1169
+ agentinbox agent register [--agent-id ID] [--force-rebind] [--notify-lease-ms N] [--min-unacked-items N]
933
1170
  agentinbox agent list
934
1171
  agentinbox agent current
935
1172
  agentinbox agent show <agentId>
936
1173
  agentinbox agent remove <agentId>
937
1174
  agentinbox agent resume <agentId>
938
- agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N]
1175
+ agentinbox agent target add webhook <agentId> --url URL [--activation-mode MODE] [--notify-lease-ms N] [--min-unacked-items N]
939
1176
  agentinbox agent target list <agentId>
940
1177
  agentinbox agent target remove <agentId> <targetId>
941
1178
  agentinbox agent target resume <agentId> <targetId>
@@ -965,16 +1202,20 @@ Usage:
965
1202
  Usage:
966
1203
  agentinbox inbox list
967
1204
  agentinbox inbox show <agentId>
968
- agentinbox inbox read [--agent-id ID] [--after-item ID] [--include-acked]
1205
+ agentinbox inbox read [--agent-id ID] [--after-entry ID] [--include-acked]
969
1206
  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)
1207
+ agentinbox inbox watch [--agent-id ID] [--after-entry ID] [--include-acked] [--heartbeat-ms N]
1208
+ agentinbox inbox ack [--agent-id ID] (--through <entryId> | --entry <entryId> | --all)
1209
+ agentinbox inbox policy show [--agent-id ID]
1210
+ agentinbox inbox policy set [--agent-id ID] [--enabled|--disabled] [--window-ms N] [--max-items N] [--max-thread-age-ms N]
972
1211
  agentinbox inbox compact <agentId>
973
1212
  `,
974
1213
  deliver: `agentinbox deliver
975
1214
 
976
1215
  Usage:
977
- agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--kind KIND] [--payload-json JSON]
1216
+ agentinbox deliver send --provider PROVIDER --surface SURFACE --target TARGET [--source-id SOURCE_ID] [--kind KIND] [--payload-json JSON]
1217
+ agentinbox deliver actions (--handle-json JSON | --provider PROVIDER --surface SURFACE --target TARGET) [--source-id SOURCE_ID]
1218
+ agentinbox deliver invoke (--handle-json JSON | --provider PROVIDER --surface SURFACE --target TARGET) --operation NAME --input-json JSON [--source-id SOURCE_ID]
978
1219
  `,
979
1220
  status: `agentinbox status
980
1221