acn-client 0.13.0 → 0.14.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/dist/index.mjs CHANGED
@@ -83,6 +83,9 @@ var ACNClient = class {
83
83
  post(path, body) {
84
84
  return this.request("POST", path, { body });
85
85
  }
86
+ patch(path, body) {
87
+ return this.request("PATCH", path, { body });
88
+ }
86
89
  delete(path) {
87
90
  return this.request("DELETE", path);
88
91
  }
@@ -199,20 +202,20 @@ var ACNClient = class {
199
202
  return this.get("/api/v1/subnets");
200
203
  }
201
204
  /** Get subnet by ID */
202
- async getSubnet(subnetId) {
203
- return this.get(`/api/v1/subnets/${subnetId}`);
205
+ async getSubnet(slug) {
206
+ return this.get(`/api/v1/subnets/${slug}`);
204
207
  }
205
208
  /**
206
209
  * List immediate children of a subnet (ADR-0003).
207
210
  *
208
- * Wraps `GET /api/v1/subnets/{parentSubnetId}/children`. Returns
211
+ * Wraps `GET /api/v1/subnets/{parentSlug}/children`. Returns
209
212
  * `SUBNET_NOT_FOUND` when the parent does not exist. Visibility
210
213
  * matches `listSubnets` — private children you cannot see are
211
214
  * omitted from the result set.
212
215
  */
213
- async listChildren(parentSubnetId) {
216
+ async listChildren(parentSlug) {
214
217
  const data = await this.get(
215
- `/api/v1/subnets/${parentSubnetId}/children`
218
+ `/api/v1/subnets/${parentSlug}/children`
216
219
  );
217
220
  return data.subnets;
218
221
  }
@@ -222,16 +225,16 @@ var ACNClient = class {
222
225
  * Owner-only. Idempotent — promoting an already-persistent subnet
223
226
  * returns its current state unchanged.
224
227
  */
225
- async promoteSubnet(subnetId) {
226
- return this.post(`/api/v1/subnets/${subnetId}/promote`);
228
+ async promoteSubnet(slug) {
229
+ return this.post(`/api/v1/subnets/${slug}/promote`);
227
230
  }
228
231
  /** Delete a subnet you own (requires Agent API Key — only the owning agent can delete) */
229
- async deleteSubnet(subnetId) {
230
- return this.request("DELETE", `/api/v1/subnets/${subnetId}`);
232
+ async deleteSubnet(slug) {
233
+ return this.request("DELETE", `/api/v1/subnets/${slug}`);
231
234
  }
232
235
  /** Get agents in a subnet */
233
- async getSubnetAgents(subnetId) {
234
- return this.get(`/api/v1/subnets/${subnetId}/agents`);
236
+ async getSubnetAgents(slug) {
237
+ return this.get(`/api/v1/subnets/${slug}/agents`);
235
238
  }
236
239
  // ──────────────────────────────────────────────────────────────────────
237
240
  // Subnet membership (agent-side)
@@ -246,12 +249,12 @@ var ACNClient = class {
246
249
  // scheduled for removal. Requires ACN backend ≥ post-PR-#42.
247
250
  // ──────────────────────────────────────────────────────────────────────
248
251
  /** Join agent to subnet */
249
- async joinSubnet(agentId, subnetId) {
250
- return this.post(`/api/v1/agents/${agentId}/subnets/${subnetId}`);
252
+ async joinSubnet(agentId, slug) {
253
+ return this.post(`/api/v1/agents/${agentId}/subnets/${slug}`);
251
254
  }
252
255
  /** Remove agent from subnet */
253
- async leaveSubnet(agentId, subnetId) {
254
- return this.delete(`/api/v1/agents/${agentId}/subnets/${subnetId}`);
256
+ async leaveSubnet(agentId, slug) {
257
+ return this.delete(`/api/v1/agents/${agentId}/subnets/${slug}`);
255
258
  }
256
259
  /** Get agent's subnets */
257
260
  async getAgentSubnets(agentId) {
@@ -277,7 +280,7 @@ var ACNClient = class {
277
280
  // `/api/v1/agents/{a}/allowlist/{target}` and is unrelated).
278
281
  // ----- Allowlist (owner-only, 3 verbs) ---------------------------------
279
282
  /**
280
- * Pre-authorise `agentId` on `subnetId`'s allowlist (owner only).
283
+ * Pre-authorise `agentId` on `slug`'s allowlist (owner only).
281
284
  *
282
285
  * Allowlisted agents skip the approval queue: their next
283
286
  * `joinSubnet` lands in branch 4 (allowlist hit) and becomes an
@@ -287,35 +290,35 @@ var ACNClient = class {
287
290
  * return 409 ALREADY_ON_ALLOWLIST (raised as an error, never
288
291
  * silently no-op'd).
289
292
  */
290
- async subnetAllowlistAdd(subnetId, agentId) {
291
- return this.post(`/api/v1/subnets/${subnetId}/allowlist`, {
293
+ async subnetAllowlistAdd(slug, agentId) {
294
+ return this.post(`/api/v1/subnets/${slug}/allowlist`, {
292
295
  agent_id: agentId
293
296
  });
294
297
  }
295
298
  /**
296
- * Remove `agentId` from `subnetId`'s allowlist (owner only).
299
+ * Remove `agentId` from `slug`'s allowlist (owner only).
297
300
  *
298
301
  * Idempotent — removing an entry that doesn't exist still
299
302
  * returns 204. Per ADR-0004 §"Allowlist mutation does not
300
303
  * affect agents who already joined", this does NOT revoke
301
304
  * membership for agents already admitted via the allowlist.
302
305
  */
303
- async subnetAllowlistRemove(subnetId, agentId) {
304
- await this.delete(`/api/v1/subnets/${subnetId}/allowlist/${agentId}`);
306
+ async subnetAllowlistRemove(slug, agentId) {
307
+ await this.delete(`/api/v1/subnets/${slug}/allowlist/${agentId}`);
305
308
  }
306
309
  /**
307
- * List `subnetId`'s allowlist entries (owner only).
310
+ * List `slug`'s allowlist entries (owner only).
308
311
  *
309
312
  * Owner-only by design — the allowlist is a privacy-sensitive
310
313
  * trust signal and exposing it publicly would leak relationship
311
314
  * metadata.
312
315
  */
313
- async subnetAllowlistList(subnetId, options) {
316
+ async subnetAllowlistList(slug, options) {
314
317
  const params = {
315
318
  limit: options?.limit ?? 100,
316
319
  offset: options?.offset ?? 0
317
320
  };
318
- return this.get(`/api/v1/subnets/${subnetId}/allowlist`, params);
321
+ return this.get(`/api/v1/subnets/${slug}/allowlist`, params);
319
322
  }
320
323
  // ----- Join requests (4 verbs: 3 owner-side + 1 applicant-side) --------
321
324
  /**
@@ -329,9 +332,9 @@ var ACNClient = class {
329
332
  *
330
333
  * Optional `note` (≤500 chars) is recorded on the audit row.
331
334
  */
332
- async subnetJoinRequestApprove(subnetId, requestId, options) {
335
+ async subnetJoinRequestApprove(slug, requestId, options) {
333
336
  return this.post(
334
- `/api/v1/subnets/${subnetId}/join-requests/${requestId}/approve`,
337
+ `/api/v1/subnets/${slug}/join-requests/${requestId}/approve`,
335
338
  options?.note !== void 0 ? { note: options.note } : void 0
336
339
  );
337
340
  }
@@ -340,9 +343,9 @@ var ACNClient = class {
340
343
  *
341
344
  * No membership change. `subnet.join_rejected` webhook fires.
342
345
  */
343
- async subnetJoinRequestReject(subnetId, requestId, options) {
346
+ async subnetJoinRequestReject(slug, requestId, options) {
344
347
  return this.post(
345
- `/api/v1/subnets/${subnetId}/join-requests/${requestId}/reject`,
348
+ `/api/v1/subnets/${slug}/join-requests/${requestId}/reject`,
346
349
  options?.note !== void 0 ? { note: options.note } : void 0
347
350
  );
348
351
  }
@@ -352,29 +355,29 @@ var ACNClient = class {
352
355
  * Self-only — caller must be the agent who originally created
353
356
  * the request. `subnet.join_withdrawn` webhook fires.
354
357
  */
355
- async subnetJoinRequestWithdraw(subnetId, requestId, options) {
358
+ async subnetJoinRequestWithdraw(slug, requestId, options) {
356
359
  return this.request(
357
360
  "DELETE",
358
- `/api/v1/subnets/${subnetId}/join-requests/${requestId}`,
361
+ `/api/v1/subnets/${slug}/join-requests/${requestId}`,
359
362
  options?.note !== void 0 ? { body: { note: options.note } } : void 0
360
363
  );
361
364
  }
362
365
  /**
363
- * Owner lists join_request / allowlist_auto rows for `subnetId`.
366
+ * Owner lists join_request / allowlist_auto rows for `slug`.
364
367
  *
365
368
  * `kind` defaults to `'join_request'`; pass `'allowlist_auto'`
366
369
  * to inspect synthesised allowlist-hit audit rows. Server
367
370
  * rejects `kind='invitation'` with 400 INVALID_KIND_FILTER —
368
371
  * use `subnetInvitationList` instead.
369
372
  */
370
- async subnetJoinRequestList(subnetId, options) {
373
+ async subnetJoinRequestList(slug, options) {
371
374
  const params = {
372
375
  kind: options?.kind ?? "join_request",
373
376
  limit: options?.limit ?? 100,
374
377
  offset: options?.offset ?? 0
375
378
  };
376
379
  if (options?.status !== void 0) params.status = options.status;
377
- return this.get(`/api/v1/subnets/${subnetId}/join-requests`, params);
380
+ return this.get(`/api/v1/subnets/${slug}/join-requests`, params);
378
381
  }
379
382
  // ----- Invitations (5 + 1 verbs) ---------------------------------------
380
383
  /**
@@ -389,10 +392,10 @@ var ACNClient = class {
389
392
  *
390
393
  * Discriminate on `auto_resolved` to dispatch.
391
394
  */
392
- async subnetInvitationSend(subnetId, agentId, options) {
395
+ async subnetInvitationSend(slug, agentId, options) {
393
396
  const body = { agent_id: agentId };
394
397
  if (options?.note !== void 0) body.note = options.note;
395
- return this.post(`/api/v1/subnets/${subnetId}/invitations`, body);
398
+ return this.post(`/api/v1/subnets/${slug}/invitations`, body);
396
399
  }
397
400
  /**
398
401
  * Invitee accepts a pending invitation (CAS pending → approved).
@@ -402,9 +405,9 @@ var ACNClient = class {
402
405
  * gains the back-reference, and `subnet.invitation_accepted`
403
406
  * webhook fires.
404
407
  */
405
- async subnetInvitationAccept(subnetId, requestId, options) {
408
+ async subnetInvitationAccept(slug, requestId, options) {
406
409
  return this.post(
407
- `/api/v1/subnets/${subnetId}/invitations/${requestId}/accept`,
410
+ `/api/v1/subnets/${slug}/invitations/${requestId}/accept`,
408
411
  options?.note !== void 0 ? { note: options.note } : void 0
409
412
  );
410
413
  }
@@ -414,9 +417,9 @@ var ACNClient = class {
414
417
  * No membership change. `subnet.invitation_rejected` webhook
415
418
  * fires.
416
419
  */
417
- async subnetInvitationReject(subnetId, requestId, options) {
420
+ async subnetInvitationReject(slug, requestId, options) {
418
421
  return this.post(
419
- `/api/v1/subnets/${subnetId}/invitations/${requestId}/reject`,
422
+ `/api/v1/subnets/${slug}/invitations/${requestId}/reject`,
420
423
  options?.note !== void 0 ? { note: options.note } : void 0
421
424
  );
422
425
  }
@@ -427,26 +430,26 @@ var ACNClient = class {
427
430
  * `withdrawn` (not `rejected`) — distinct audit token so
428
431
  * consumers can tell "owner gave up" from "invitee said no".
429
432
  */
430
- async subnetInvitationCancel(subnetId, requestId, options) {
433
+ async subnetInvitationCancel(slug, requestId, options) {
431
434
  return this.request(
432
435
  "DELETE",
433
- `/api/v1/subnets/${subnetId}/invitations/${requestId}`,
436
+ `/api/v1/subnets/${slug}/invitations/${requestId}`,
434
437
  options?.note !== void 0 ? { body: { note: options.note } } : void 0
435
438
  );
436
439
  }
437
440
  /**
438
- * Owner lists invitation rows for `subnetId`.
441
+ * Owner lists invitation rows for `slug`.
439
442
  *
440
443
  * Owner-only — invitees use `agentSubnetInvitations` for their
441
444
  * own cross-subnet view.
442
445
  */
443
- async subnetInvitationList(subnetId, options) {
446
+ async subnetInvitationList(slug, options) {
444
447
  const params = {
445
448
  limit: options?.limit ?? 100,
446
449
  offset: options?.offset ?? 0
447
450
  };
448
451
  if (options?.status !== void 0) params.status = options.status;
449
- return this.get(`/api/v1/subnets/${subnetId}/invitations`, params);
452
+ return this.get(`/api/v1/subnets/${slug}/invitations`, params);
450
453
  }
451
454
  /**
452
455
  * Invitee's cross-subnet pending-invitation list (self only).
@@ -511,6 +514,31 @@ var ACNClient = class {
511
514
  if (options?.consume) params.ack = true;
512
515
  return this.get(`/api/v1/communication/history/${agentId}`, params);
513
516
  }
517
+ /**
518
+ * Precisely acknowledge (remove) specific messages from the inbox.
519
+ *
520
+ * Unlike `getMessageHistory({ consume: true })` which clears the entire inbox,
521
+ * this method removes only the messages whose `route_id` values are listed.
522
+ *
523
+ * @param agentId Must match the authenticated agent's ID.
524
+ * @param routeIds List of `route_id` values to remove (up to 500).
525
+ * @returns Number of messages actually removed.
526
+ */
527
+ async ackInbox(agentId, routeIds) {
528
+ return this.post(`/api/v1/communication/history/${agentId}/ack`, { route_ids: routeIds });
529
+ }
530
+ /**
531
+ * Update the lifecycle status of a specific inbox message.
532
+ *
533
+ * @param agentId Must match the authenticated agent's ID.
534
+ * @param routeId `route_id` of the target message (from inbox listing).
535
+ * @param status New status: `"unread"` | `"read"` | `"processed"`.
536
+ * @returns Object with `agent_id`, `route_id`, and `status`.
537
+ * @throws 404 (`inbox_message_not_found`) if route_id is absent from inbox.
538
+ */
539
+ async updateInboxMessageStatus(agentId, routeId, status) {
540
+ return this.patch(`/api/v1/communication/history/${agentId}/${routeId}`, { status });
541
+ }
514
542
  // ============================================
515
543
  // Manifest Queue (Phase 2/3)
516
544
  // ============================================
@@ -1087,8 +1115,8 @@ var ACNClient = class {
1087
1115
  * Register (or clear) an org-harness webhook URL for a subnet.
1088
1116
  * Pass `harnessUrl: null` to deregister.
1089
1117
  */
1090
- async registerSubnetHarness(subnetId, harnessUrl, harnessSecret) {
1091
- await this.request("PATCH", `/api/v1/subnets/${subnetId}/harness`, {
1118
+ async registerSubnetHarness(slug, harnessUrl, harnessSecret) {
1119
+ await this.request("PATCH", `/api/v1/subnets/${slug}/harness`, {
1092
1120
  body: {
1093
1121
  harness_url: harnessUrl,
1094
1122
  harness_secret: harnessSecret ?? null
@@ -1323,10 +1351,16 @@ var KNOWN_PAYMENT_TASK_STATUSES = [
1323
1351
  "payment_failed",
1324
1352
  "refunded"
1325
1353
  ];
1354
+ var KNOWN_INBOX_MESSAGE_STATUSES = [
1355
+ "unread",
1356
+ "read",
1357
+ "processed"
1358
+ ];
1326
1359
  export {
1327
1360
  ACNClient,
1328
1361
  ACNError,
1329
1362
  ACNRealtime,
1363
+ KNOWN_INBOX_MESSAGE_STATUSES,
1330
1364
  KNOWN_PAYMENT_TASK_STATUSES,
1331
1365
  subscribeToACN
1332
1366
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acn-client",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Official TypeScript/JavaScript client for ACN (Agent Collaboration Network)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",