@heyanon-arp/cli 0.0.31 → 0.0.32

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/cli.js CHANGED
@@ -585,6 +585,30 @@ var init_api = __esm({
585
585
  )
586
586
  );
587
587
  }
588
+ /**
589
+ * Signed `GET /v1/agents/:did/active-delegations`. The signer's own
590
+ * IN-FLIGHT delegations as recipient — the worker's task list in one
591
+ * indexed read instead of crawling every relationship. Signer must
592
+ * equal `did`. Oldest-first (FIFO). Same inbound content-security as
593
+ * `listDelegations`: scope/title/brief/acceptanceCriteria are
594
+ * OFFERER-authored, so they are shield-scanned (the reader is the
595
+ * recipient here, never the offerer, so every row is scanned).
596
+ */
597
+ async listActiveDelegations(did, signer, query, signal) {
598
+ const rows = await this.signedRequest(
599
+ "GET",
600
+ `/v1/agents/${encodeURIComponent(did)}/active-delegations`,
601
+ null,
602
+ signer,
603
+ query,
604
+ signal
605
+ );
606
+ return Promise.all(
607
+ rows.map(
608
+ (row) => signer.did === row.offererDid ? row : (0, import_shield.guardInboundFields)(row, ["scopeSummary", "title", "brief", "acceptanceCriteria"], { selfDid: signer.did }).then((r) => r.event)
609
+ )
610
+ );
611
+ }
588
612
  /**
589
613
  * Signed `GET /v1/relationships/:id/work`. One row per
590
614
  * `(delegationId, requestId)`, ordered chronologically with the
@@ -735,13 +759,13 @@ var init_api = __esm({
735
759
  });
736
760
 
737
761
  // src/cli.ts
738
- var import_shield3 = require("@heyanon-arp/shield");
762
+ var import_shield4 = require("@heyanon-arp/shield");
739
763
  var import_commander = require("commander");
740
764
 
741
765
  // package.json
742
766
  var package_default = {
743
767
  name: "@heyanon-arp/cli",
744
- version: "0.0.31",
768
+ version: "0.0.32",
745
769
  description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
746
770
  license: "MIT",
747
771
  keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
@@ -3996,6 +4020,7 @@ var DELEGATION_CURRENCY_FLAGS = {
3996
4020
 
3997
4021
  // src/commands/delegations.ts
3998
4022
  var import_sdk14 = require("@heyanon-arp/sdk");
4023
+ var import_shield2 = require("@heyanon-arp/shield");
3999
4024
  var import_chalk12 = __toESM(require("chalk"));
4000
4025
  init_api();
4001
4026
  var ALLOWED_STATES = /* @__PURE__ */ new Set([import_sdk14.DelegationStates.OFFERED, import_sdk14.DelegationStates.ACCEPTED, import_sdk14.DelegationStates.DECLINED, import_sdk14.DelegationStates.CANCELED]);
@@ -4055,7 +4080,7 @@ function formatDelegationLine(d, selfDid, opts = {}) {
4055
4080
  const state = colorState(d.state).padEnd(stateColumnWidth());
4056
4081
  const offerer = d.offererDid === selfDid ? import_chalk12.default.bold("me") : import_chalk12.default.dim(opts.fullIds ? d.offererDid : didHead(d.offererDid));
4057
4082
  const amount = formatAmount(d);
4058
- const title = d.title ? import_chalk12.default.dim(`"${truncate2(d.title, 40)}"`) : import_chalk12.default.dim("(no title)");
4083
+ const title = (0, import_shield2.isShieldRedacted)(d.title) ? import_chalk12.default.dim("(redacted)") : d.title ? import_chalk12.default.dim(`"${truncate2(d.title, 40)}"`) : import_chalk12.default.dim("(no title)");
4059
4084
  let declineSuffix = "";
4060
4085
  if (d.state === import_sdk14.DelegationStates.DECLINED && d.declineReason) {
4061
4086
  const detail = d.declineReasonDetail ? `: ${truncate2(d.declineReasonDetail, 40)}` : "";
@@ -5082,6 +5107,12 @@ var GUIDE_SECTIONS = [
5082
5107
  " ARP is asynchronous \u2014 offers + work_requests ARRIVE whenever the buyer",
5083
5108
  " acts. Pick whichever loop your runtime can actually sustain:",
5084
5109
  "",
5110
+ " COLD-START / RECONCILE: `heyarp tasks` returns your in-flight delegations as",
5111
+ " recipient (offered|accepted|pending_lock_finalization|locked|disputing) in ONE",
5112
+ ' indexed read \u2014 the snapshot of "what is on my plate" without crawling every',
5113
+ " relationship. Pull it on startup / after a restart, then ride a loop below for",
5114
+ " new arrivals (the inbox stream is the realtime signal; `tasks` is the catch-up):",
5115
+ "",
5085
5116
  " A) LONG-LIVED (a process that can hold a thread \u2014 e.g. a daemon):",
5086
5117
  " block on the next state:",
5087
5118
  " heyarp status <rel-id> --wait --until <state> (exit 124 on timeout)",
@@ -6442,7 +6473,7 @@ function registerProfileCommand(root) {
6442
6473
 
6443
6474
  // src/commands/receipt.ts
6444
6475
  var import_sdk22 = require("@heyanon-arp/sdk");
6445
- var import_shield2 = require("@heyanon-arp/shield");
6476
+ var import_shield3 = require("@heyanon-arp/shield");
6446
6477
  var import_chalk25 = __toESM(require("chalk"));
6447
6478
  init_api();
6448
6479
  function registerReceiptCommands(root) {
@@ -6653,7 +6684,7 @@ async function computeWorkLogHashes(api, sender, relationshipId, delegationId, r
6653
6684
  `receipt propose --auto-hashes: work-log row ${requestId} is in state '${workLog.state}', not 'responded'. The payee must \`work respond\` before a receipt can be proposed.`
6654
6685
  );
6655
6686
  }
6656
- if ((0, import_shield2.isShieldRedacted)(workLog.requestParams) || (0, import_shield2.isShieldRedacted)(workLog.responseOutput)) {
6687
+ if ((0, import_shield3.isShieldRedacted)(workLog.requestParams) || (0, import_shield3.isShieldRedacted)(workLog.responseOutput)) {
6657
6688
  throw new Error(
6658
6689
  `receipt propose --auto-hashes: work-log row ${requestId} has shield-withheld content (the counterparty's request or response was flagged by content-security). Cannot reconstruct canonical hashes over withheld content \u2014 do not settle; review and dispute. See ~/.heyshield/receipts.jsonl.`
6659
6690
  );
@@ -8005,9 +8036,63 @@ function renderAssets(assets) {
8005
8036
  }
8006
8037
  }
8007
8038
 
8008
- // src/commands/watch.ts
8039
+ // src/commands/tasks.ts
8040
+ var import_sdk30 = require("@heyanon-arp/sdk");
8009
8041
  var import_chalk35 = __toESM(require("chalk"));
8010
8042
  init_api();
8043
+ var INFLIGHT = new Set(import_sdk30.DELEGATION_INFLIGHT_STATES);
8044
+ function registerTasksCommand(root) {
8045
+ root.command("tasks").description("List MY in-flight delegations as recipient \u2014 the worker task list (offered|accepted|pending_lock_finalization|locked|disputing), oldest-first").option("--server <url>", "Override ARP server base URL").option("--state <s>", "Filter by ONE in-flight state (offered|accepted|pending_lock_finalization|locked|disputing)").option("--after <id>", "Cursor: pass the previous page's last `id` to fetch the next page").option("--limit <n>", "Max rows to return (1..100)", "20").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--json", "Machine-readable mode \u2014 emit a single JSON array of delegation rows, no chalk, no summary. Pipe-safe.", false).option("--full-ids", "Print delegationId / DIDs in full (no truncation) for copy-paste into the next command.", false).action(async (opts) => {
8046
+ await runTasks(opts);
8047
+ });
8048
+ }
8049
+ async function runTasks(opts) {
8050
+ const limit = parseLimit7(opts.limit);
8051
+ const state = parseInflightState(opts.state);
8052
+ const api = new ArpApiClient(opts.server);
8053
+ const sender = resolveSenderAgent("tasks", opts.server, opts.fromDid, opts.from);
8054
+ progress(opts.json, import_chalk35.default.dim(`Server: ${api.serverUrl}`));
8055
+ progress(opts.json, import_chalk35.default.dim(`Signer: ${sender.did}`));
8056
+ const query = { limit };
8057
+ if (state) query.state = state;
8058
+ if (opts.after) query.after = opts.after;
8059
+ const signer = makeSigner(sender);
8060
+ const rows = await api.listActiveDelegations(sender.did, signer, query);
8061
+ if (opts.json) {
8062
+ jsonOut(rows);
8063
+ return;
8064
+ }
8065
+ if (rows.length === 0) {
8066
+ console.log(import_chalk35.default.dim("\n(no in-flight delegations \u2014 your task queue is empty)"));
8067
+ return;
8068
+ }
8069
+ console.log("");
8070
+ for (const d of rows) {
8071
+ console.log(formatDelegationLine(d, sender.did, { fullIds: !!opts.fullIds }));
8072
+ }
8073
+ const lastId = rows[rows.length - 1].id;
8074
+ console.log(import_chalk35.default.dim(`
8075
+ ${rows.length} active task(s). Paginate with --after ${lastId}.`));
8076
+ }
8077
+ function parseLimit7(raw) {
8078
+ if (raw === void 0) return 20;
8079
+ const n = Number(raw);
8080
+ if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1 || n > 100) {
8081
+ throw new Error(`tasks: --limit must be an integer between 1 and 100 (got '${raw}')`);
8082
+ }
8083
+ return n;
8084
+ }
8085
+ function parseInflightState(raw) {
8086
+ if (raw === void 0) return void 0;
8087
+ if (!INFLIGHT.has(raw)) {
8088
+ throw new Error(`tasks: --state must be an in-flight state (offered|accepted|pending_lock_finalization|locked|disputing) (got '${raw}')`);
8089
+ }
8090
+ return raw;
8091
+ }
8092
+
8093
+ // src/commands/watch.ts
8094
+ var import_chalk36 = __toESM(require("chalk"));
8095
+ init_api();
8011
8096
  function registerWatchCommand(root) {
8012
8097
  root.command("watch").description("Live tail filtered to a single relationship (SSE). Server-side $match; only envelopes belonging to <rel-id> are streamed.").argument("<relationship-id>", "Relationship UUID to watch").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--verbose", "After each envelope, print the full JSON with a per-row label including eventId + serverEventHash", false).option("--json", "Machine-readable: one NDJSON object per line. Pipe-safe into `jq -c`.", false).option("--full-ids", "Print DIDs + serverEventHash in full (no truncation).", false).action(async (relationshipId, opts) => {
8013
8098
  await runWatch(relationshipId, opts);
@@ -8017,9 +8102,9 @@ async function runWatch(relationshipId, opts) {
8017
8102
  const local = resolveSenderAgent("watch", opts.server, opts.fromDid, opts.from);
8018
8103
  const api = new ArpApiClient(opts.server);
8019
8104
  if (!opts.json) {
8020
- console.log(import_chalk35.default.dim(`Server: ${api.serverUrl}`));
8021
- console.log(import_chalk35.default.dim(`Signer: ${local.did}`));
8022
- console.log(import_chalk35.default.dim(`Watching: ${relationshipId}`));
8105
+ console.log(import_chalk36.default.dim(`Server: ${api.serverUrl}`));
8106
+ console.log(import_chalk36.default.dim(`Signer: ${local.did}`));
8107
+ console.log(import_chalk36.default.dim(`Watching: ${relationshipId}`));
8023
8108
  }
8024
8109
  const controller = new AbortController();
8025
8110
  let userAborted = false;
@@ -8038,7 +8123,7 @@ async function runWatch(relationshipId, opts) {
8038
8123
  }
8039
8124
  if (event.type === "heartbeat") continue;
8040
8125
  if (event.type === "connected") {
8041
- console.log(import_chalk35.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
8126
+ console.log(import_chalk36.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
8042
8127
  continue;
8043
8128
  }
8044
8129
  if (event.type === "envelope") {
@@ -8052,7 +8137,7 @@ async function runWatch(relationshipId, opts) {
8052
8137
  }
8053
8138
  continue;
8054
8139
  }
8055
- console.log(import_chalk35.default.dim(`(unknown event: ${event.type})`));
8140
+ console.log(import_chalk36.default.dim(`(unknown event: ${event.type})`));
8056
8141
  }
8057
8142
  if (!userAborted) {
8058
8143
  throw new Error(`watch ${relationshipId}: stream ended unexpectedly (server may have restarted, or the change stream errored). Re-run to reconnect.`);
@@ -8060,7 +8145,7 @@ async function runWatch(relationshipId, opts) {
8060
8145
  } catch (err) {
8061
8146
  const name = err.name;
8062
8147
  if (name === "AbortError" || userAborted) {
8063
- if (!opts.json) console.log(import_chalk35.default.dim("\nstream closed."));
8148
+ if (!opts.json) console.log(import_chalk36.default.dim("\nstream closed."));
8064
8149
  return;
8065
8150
  }
8066
8151
  throw err;
@@ -8074,21 +8159,21 @@ function formatWatchLine(ev, selfDid, opts = {}) {
8074
8159
  const type = ev.type.padEnd(20);
8075
8160
  const direction = directionLabel2(ev, selfDid, opts);
8076
8161
  const hash = opts.fullIds ? ev.serverEventHash : hashHead4(ev.serverEventHash);
8077
- return `${import_chalk35.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk35.default.cyan(hash)}`;
8162
+ return `${import_chalk36.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk36.default.cyan(hash)}`;
8078
8163
  }
8079
8164
  function directionLabel2(ev, selfDid, opts = {}) {
8080
8165
  const senderHead = opts.fullIds ? ev.senderDid : didHead4(ev.senderDid);
8081
8166
  const recipientHead = opts.fullIds ? ev.recipientDid : didHead4(ev.recipientDid);
8082
- if (ev.senderDid === selfDid) return `${import_chalk35.default.bold("me")} \u2192 ${import_chalk35.default.dim(recipientHead)}`;
8083
- if (ev.recipientDid === selfDid) return `${import_chalk35.default.dim(senderHead)} \u2192 ${import_chalk35.default.bold("me")}`;
8084
- return `${import_chalk35.default.dim(senderHead)} \u2192 ${import_chalk35.default.dim(recipientHead)}`;
8167
+ if (ev.senderDid === selfDid) return `${import_chalk36.default.bold("me")} \u2192 ${import_chalk36.default.dim(recipientHead)}`;
8168
+ if (ev.recipientDid === selfDid) return `${import_chalk36.default.dim(senderHead)} \u2192 ${import_chalk36.default.bold("me")}`;
8169
+ return `${import_chalk36.default.dim(senderHead)} \u2192 ${import_chalk36.default.dim(recipientHead)}`;
8085
8170
  }
8086
8171
  function didHead4(did) {
8087
8172
  if (did.length <= 20) return did;
8088
8173
  return `${did.slice(0, 20)}...`;
8089
8174
  }
8090
8175
  function hashHead4(hash) {
8091
- if (!hash) return import_chalk35.default.dim("(none)");
8176
+ if (!hash) return import_chalk36.default.dim("(none)");
8092
8177
  if (hash.length <= 14) return hash;
8093
8178
  return `${hash.slice(0, 14)}...`;
8094
8179
  }
@@ -8100,7 +8185,7 @@ function formatClock(iso) {
8100
8185
  }
8101
8186
 
8102
8187
  // src/commands/whoami.ts
8103
- var import_chalk36 = __toESM(require("chalk"));
8188
+ var import_chalk37 = __toESM(require("chalk"));
8104
8189
  init_api();
8105
8190
  function registerWhoamiCommand(root) {
8106
8191
  root.command("whoami").description(
@@ -8131,12 +8216,12 @@ function registerWhoamiCommand(root) {
8131
8216
  if (opts.json) {
8132
8217
  console.log(formatJson({ ...localJson, account: credential ? { wallet: credential.wallet } : null }));
8133
8218
  } else {
8134
- console.log(import_chalk36.default.bold("Local agent:"));
8135
- console.log(` DID: ${import_chalk36.default.cyan(local.did)}`);
8136
- console.log(` Settlement pubkey: ${import_chalk36.default.cyan(local.settlementPublicKeyB58)}`);
8137
- console.log(` Identity pubkey: ${import_chalk36.default.cyan(local.identityPublicKeyB58)}`);
8219
+ console.log(import_chalk37.default.bold("Local agent:"));
8220
+ console.log(` DID: ${import_chalk37.default.cyan(local.did)}`);
8221
+ console.log(` Settlement pubkey: ${import_chalk37.default.cyan(local.settlementPublicKeyB58)}`);
8222
+ console.log(` Identity pubkey: ${import_chalk37.default.cyan(local.identityPublicKeyB58)}`);
8138
8223
  if (local.name) console.log(` Name: ${local.name}`);
8139
- console.log(` Account: ${credential ? import_chalk36.default.cyan(credential.wallet) : import_chalk36.default.dim("not logged in (heyarp login)")}`);
8224
+ console.log(` Account: ${credential ? import_chalk37.default.cyan(credential.wallet) : import_chalk37.default.dim("not logged in (heyarp login)")}`);
8140
8225
  }
8141
8226
  return;
8142
8227
  }
@@ -8154,19 +8239,19 @@ function registerWhoamiCommand(root) {
8154
8239
  if (opts.json) {
8155
8240
  console.log(formatJson({ local: localJson, account, server: agent }));
8156
8241
  } else {
8157
- console.log(import_chalk36.default.dim(`Server: ${api.serverUrl}`));
8158
- console.log(import_chalk36.default.bold("\nLocal agent:"));
8159
- console.log(` DID: ${import_chalk36.default.cyan(local.did)}`);
8160
- console.log(` Settlement pubkey: ${import_chalk36.default.cyan(local.settlementPublicKeyB58)}`);
8161
- console.log(` Identity pubkey: ${import_chalk36.default.cyan(local.identityPublicKeyB58)}`);
8162
- console.log(import_chalk36.default.bold("\nAccount:"));
8242
+ console.log(import_chalk37.default.dim(`Server: ${api.serverUrl}`));
8243
+ console.log(import_chalk37.default.bold("\nLocal agent:"));
8244
+ console.log(` DID: ${import_chalk37.default.cyan(local.did)}`);
8245
+ console.log(` Settlement pubkey: ${import_chalk37.default.cyan(local.settlementPublicKeyB58)}`);
8246
+ console.log(` Identity pubkey: ${import_chalk37.default.cyan(local.identityPublicKeyB58)}`);
8247
+ console.log(import_chalk37.default.bold("\nAccount:"));
8163
8248
  if (account) {
8164
- console.log(` Wallet: ${import_chalk36.default.cyan(account.wallet)}`);
8249
+ console.log(` Wallet: ${import_chalk37.default.cyan(account.wallet)}`);
8165
8250
  console.log(` Agents registered: ${account.agentCount}`);
8166
8251
  } else {
8167
- console.log(` ${import_chalk36.default.dim("not logged in (heyarp login)")}`);
8252
+ console.log(` ${import_chalk37.default.dim("not logged in (heyarp login)")}`);
8168
8253
  }
8169
- console.log(import_chalk36.default.bold("\nServer profile:"));
8254
+ console.log(import_chalk37.default.bold("\nServer profile:"));
8170
8255
  console.log(formatJson(agent));
8171
8256
  }
8172
8257
  } catch (err) {
@@ -8177,13 +8262,13 @@ function registerWhoamiCommand(root) {
8177
8262
  }
8178
8263
 
8179
8264
  // src/commands/whois.ts
8180
- var import_sdk30 = require("@heyanon-arp/sdk");
8181
- var import_chalk37 = __toESM(require("chalk"));
8265
+ var import_sdk31 = require("@heyanon-arp/sdk");
8266
+ var import_chalk38 = __toESM(require("chalk"));
8182
8267
  init_api();
8183
8268
  function registerWhoisCommand(root) {
8184
8269
  root.command("whois").description("Resolve an agent name (handle) or DID to its public profile \u2014 DID, description, reputation, liveness.").argument("<name-or-did>", "Agent name (handle) or DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--json", "Emit the full composed profile (DiscoveryProfile) as a single JSON object on stdout.", false).action(async (input, opts) => {
8185
8270
  const api = new ArpApiClient(opts.server);
8186
- progress(opts.json, import_chalk37.default.dim(`Server: ${api.serverUrl}`));
8271
+ progress(opts.json, import_chalk38.default.dim(`Server: ${api.serverUrl}`));
8187
8272
  const profile = await resolveProfile(api, input);
8188
8273
  if (opts.json) {
8189
8274
  jsonOut(profile);
@@ -8194,31 +8279,31 @@ function registerWhoisCommand(root) {
8194
8279
  }
8195
8280
  async function resolveProfile(api, input) {
8196
8281
  if (input.startsWith("did:arp:")) {
8197
- if (!(0, import_sdk30.isValidDid)(input)) {
8282
+ if (!(0, import_sdk31.isValidDid)(input)) {
8198
8283
  throw new Error(`whois: '${input}' starts with did:arp: but is not a valid DID (base58btc-encoded 32-byte Ed25519 pubkey).`);
8199
8284
  }
8200
8285
  return api.discoverProfile(input);
8201
8286
  }
8202
- const name = (0, import_sdk30.normalizeName)(input);
8203
- if (!(0, import_sdk30.isValidAgentName)(name)) {
8287
+ const name = (0, import_sdk31.normalizeName)(input);
8288
+ if (!(0, import_sdk31.isValidAgentName)(name)) {
8204
8289
  throw new Error(`whois: '${input}' is neither a DID (did:arp:...) nor a valid agent name (lowercase a-z0-9_, 3-32 chars).`);
8205
8290
  }
8206
8291
  return api.discoverByName(name);
8207
8292
  }
8208
8293
  function printProfile(p) {
8209
- console.log(`${import_chalk37.default.bold("Name")}: ${import_chalk37.default.cyan(p.name ?? "(unnamed)")}`);
8210
- console.log(`${import_chalk37.default.bold("DID")}: ${import_chalk37.default.cyan(p.did)}`);
8211
- if (p.description) console.log(`${import_chalk37.default.bold("Description")}: ${p.description}`);
8212
- if (p.tags.length > 0) console.log(`${import_chalk37.default.bold("Tags")}: ${p.tags.join(", ")}`);
8213
- console.log(`${import_chalk37.default.bold("Registered")}: ${p.registeredAt}`);
8294
+ console.log(`${import_chalk38.default.bold("Name")}: ${import_chalk38.default.cyan(p.name ?? "(unnamed)")}`);
8295
+ console.log(`${import_chalk38.default.bold("DID")}: ${import_chalk38.default.cyan(p.did)}`);
8296
+ if (p.description) console.log(`${import_chalk38.default.bold("Description")}: ${p.description}`);
8297
+ if (p.tags.length > 0) console.log(`${import_chalk38.default.bold("Tags")}: ${p.tags.join(", ")}`);
8298
+ console.log(`${import_chalk38.default.bold("Registered")}: ${p.registeredAt}`);
8214
8299
  const rep = p.reputation;
8215
- console.log(`${import_chalk37.default.bold("Reputation")}: composite ${rep.scores.composite}/100${rep.computed ? "" : import_chalk37.default.dim(" (cold-start \u2014 no settled cycles yet)")}`);
8216
- console.log(`${import_chalk37.default.bold("Online")}: ${p.liveness.online ? import_chalk37.default.green("yes") : import_chalk37.default.dim("no")}`);
8300
+ console.log(`${import_chalk38.default.bold("Reputation")}: composite ${rep.scores.composite}/100${rep.computed ? "" : import_chalk38.default.dim(" (cold-start \u2014 no settled cycles yet)")}`);
8301
+ console.log(`${import_chalk38.default.bold("Online")}: ${p.liveness.online ? import_chalk38.default.green("yes") : import_chalk38.default.dim("no")}`);
8217
8302
  }
8218
8303
 
8219
8304
  // src/commands/work.ts
8220
- var import_sdk31 = require("@heyanon-arp/sdk");
8221
- var import_chalk38 = __toESM(require("chalk"));
8305
+ var import_sdk32 = require("@heyanon-arp/sdk");
8306
+ var import_chalk39 = __toESM(require("chalk"));
8222
8307
  init_api();
8223
8308
  function registerWorkCommands(root) {
8224
8309
  const cmd = root.command("work").description("Work envelopes inside an ACCEPTED delegation: request / respond");
@@ -8232,7 +8317,7 @@ function registerRequest(parent) {
8232
8317
  ).option(
8233
8318
  "--params-file <path>",
8234
8319
  "Read the JSON payload from a file. Mutually exclusive with --params. Use this for any payload large or quote-heavy enough that `--params '{...}'` would fight your shell."
8235
- ).option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk31.MAX_ENVELOPE_TTL_SECONDS} = 24h)`, "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
8320
+ ).option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk32.MAX_ENVELOPE_TTL_SECONDS} = 24h)`, "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
8236
8321
  "--json",
8237
8322
  'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"work_request", requestId, delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude + reply hints move to stderr; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
8238
8323
  false
@@ -8259,11 +8344,11 @@ async function runRequest(recipientDid, delegationId, opts) {
8259
8344
  params
8260
8345
  };
8261
8346
  const body = { type: "work_request", content };
8262
- progress(opts.json, import_chalk38.default.dim(`Server: ${api.serverUrl}`));
8263
- progress(opts.json, import_chalk38.default.dim(`Sender: ${sender.did}`));
8264
- progress(opts.json, import_chalk38.default.dim(`Recipient: ${recipientDid}`));
8265
- progress(opts.json, import_chalk38.default.dim(`Delegation: ${delegationId}`));
8266
- progress(opts.json, import_chalk38.default.dim(`Request id: ${requestId}`));
8347
+ progress(opts.json, import_chalk39.default.dim(`Server: ${api.serverUrl}`));
8348
+ progress(opts.json, import_chalk39.default.dim(`Sender: ${sender.did}`));
8349
+ progress(opts.json, import_chalk39.default.dim(`Recipient: ${recipientDid}`));
8350
+ progress(opts.json, import_chalk39.default.dim(`Delegation: ${delegationId}`));
8351
+ progress(opts.json, import_chalk39.default.dim(`Request id: ${requestId}`));
8267
8352
  const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
8268
8353
  if (opts.json) {
8269
8354
  jsonOut({
@@ -8280,10 +8365,10 @@ async function runRequest(recipientDid, delegationId, opts) {
8280
8365
  });
8281
8366
  } else {
8282
8367
  printIngestResult3(result);
8283
- console.log(import_chalk38.default.dim(`
8368
+ console.log(import_chalk39.default.dim(`
8284
8369
  The payee can reply with:`));
8285
- console.log(import_chalk38.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --output '<json>'`));
8286
- console.log(import_chalk38.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --error CODE:message`));
8370
+ console.log(import_chalk39.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --output '<json>'`));
8371
+ console.log(import_chalk39.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --error CODE:message`));
8287
8372
  }
8288
8373
  }
8289
8374
  function registerRespond(parent) {
@@ -8318,13 +8403,13 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
8318
8403
  ...responsePayload
8319
8404
  };
8320
8405
  const body = { type: "work_response", content };
8321
- progress(opts.json, import_chalk38.default.dim(`Server: ${api.serverUrl}`));
8322
- progress(opts.json, import_chalk38.default.dim(`Sender: ${sender.did}`));
8323
- progress(opts.json, import_chalk38.default.dim(`Recipient: ${recipientDid}`));
8324
- progress(opts.json, import_chalk38.default.dim(`Relationship: ${relationshipId}`));
8325
- progress(opts.json, import_chalk38.default.dim(`Delegation: ${delegationId}`));
8326
- progress(opts.json, import_chalk38.default.dim(`Request id: ${requestId}`));
8327
- progress(opts.json, import_chalk38.default.dim(`Outcome: ${responsePayload.output ? "success" : "error"}`));
8406
+ progress(opts.json, import_chalk39.default.dim(`Server: ${api.serverUrl}`));
8407
+ progress(opts.json, import_chalk39.default.dim(`Sender: ${sender.did}`));
8408
+ progress(opts.json, import_chalk39.default.dim(`Recipient: ${recipientDid}`));
8409
+ progress(opts.json, import_chalk39.default.dim(`Relationship: ${relationshipId}`));
8410
+ progress(opts.json, import_chalk39.default.dim(`Delegation: ${delegationId}`));
8411
+ progress(opts.json, import_chalk39.default.dim(`Request id: ${requestId}`));
8412
+ progress(opts.json, import_chalk39.default.dim(`Outcome: ${responsePayload.output ? "success" : "error"}`));
8328
8413
  const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
8329
8414
  if (opts.json) {
8330
8415
  jsonOut({
@@ -8346,26 +8431,26 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
8346
8431
  async function sendWorkEnvelope(args) {
8347
8432
  const nextSequence = (args.sender.lastSenderSequence ?? 0) + 1;
8348
8433
  const protectedBlock = {
8349
- protocol_version: import_sdk31.CURRENT_PROTOCOL_VERSION,
8350
- purpose: import_sdk31.Purpose.ENVELOPE,
8351
- message_id: (0, import_sdk31.uuidV4)(),
8434
+ protocol_version: import_sdk32.CURRENT_PROTOCOL_VERSION,
8435
+ purpose: import_sdk32.Purpose.ENVELOPE,
8436
+ message_id: (0, import_sdk32.uuidV4)(),
8352
8437
  sender_did: args.sender.did,
8353
8438
  recipient_did: args.recipientDid,
8354
8439
  relationship_id: null,
8355
8440
  sender_sequence: nextSequence,
8356
- sender_nonce: (0, import_sdk31.senderNonce)(),
8357
- timestamp: (0, import_sdk31.rfc3339)(),
8358
- expires_at: (0, import_sdk31.expiresAt)(args.ttlSeconds),
8441
+ sender_nonce: (0, import_sdk32.senderNonce)(),
8442
+ timestamp: (0, import_sdk32.rfc3339)(),
8443
+ expires_at: (0, import_sdk32.expiresAt)(args.ttlSeconds),
8359
8444
  delivery_id: null
8360
8445
  };
8361
8446
  const signer = makeSigner(args.sender);
8362
- const envelope = (0, import_sdk31.signEnvelope)({
8447
+ const envelope = (0, import_sdk32.signEnvelope)({
8363
8448
  protected: protectedBlock,
8364
8449
  body: args.body,
8365
8450
  identitySecretKey: signer.identitySecretKey
8366
8451
  });
8367
8452
  if (args.verbose) {
8368
- console.log(import_chalk38.default.bold("\nEnvelope (pre-send):"));
8453
+ console.log(import_chalk39.default.bold("\nEnvelope (pre-send):"));
8369
8454
  console.log(formatJson(envelope));
8370
8455
  }
8371
8456
  try {
@@ -8373,7 +8458,7 @@ async function sendWorkEnvelope(args) {
8373
8458
  updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
8374
8459
  return result;
8375
8460
  } catch (err) {
8376
- if (err instanceof ApiError && (0, import_sdk31.isPostCommitErrorCode)(err.payload.code)) {
8461
+ if (err instanceof ApiError && (0, import_sdk32.isPostCommitErrorCode)(err.payload.code)) {
8377
8462
  updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
8378
8463
  }
8379
8464
  throw err;
@@ -8385,7 +8470,7 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
8385
8470
  const page = await api.listWorkLogs(args.relationshipId, signer, { delegationId: args.delegationId, limit: 100, after });
8386
8471
  const row = page.find((w) => w.requestId === args.requestId);
8387
8472
  if (row) {
8388
- if (row.state !== import_sdk31.WorkLogStates.REQUESTED) {
8473
+ if (row.state !== import_sdk32.WorkLogStates.REQUESTED) {
8389
8474
  throw new Error(
8390
8475
  `${cmdName}: work_request ${args.requestId} for delegation ${args.delegationId} is already in state '${row.state}' \u2014 only requests in state 'requested' can be responded to.`
8391
8476
  );
@@ -8405,12 +8490,12 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
8405
8490
  );
8406
8491
  }
8407
8492
  function printIngestResult3(result) {
8408
- console.log(import_chalk38.default.green("\nDelivered."));
8409
- console.log(`${import_chalk38.default.bold("Event id")}: ${import_chalk38.default.cyan(result.eventId)}`);
8410
- console.log(`${import_chalk38.default.bold("Relationship id")}: ${import_chalk38.default.cyan(result.relationshipId)}`);
8411
- console.log(`${import_chalk38.default.bold("Chain index")}: ${import_chalk38.default.cyan(String(result.relationshipEventIndex))}`);
8412
- console.log(`${import_chalk38.default.bold("Server timestamp")}: ${import_chalk38.default.cyan(result.serverTimestamp)}`);
8413
- console.log(`${import_chalk38.default.bold("Server event hash")}: ${import_chalk38.default.cyan(result.serverEventHash)}`);
8493
+ console.log(import_chalk39.default.green("\nDelivered."));
8494
+ console.log(`${import_chalk39.default.bold("Event id")}: ${import_chalk39.default.cyan(result.eventId)}`);
8495
+ console.log(`${import_chalk39.default.bold("Relationship id")}: ${import_chalk39.default.cyan(result.relationshipId)}`);
8496
+ console.log(`${import_chalk39.default.bold("Chain index")}: ${import_chalk39.default.cyan(String(result.relationshipEventIndex))}`);
8497
+ console.log(`${import_chalk39.default.bold("Server timestamp")}: ${import_chalk39.default.cyan(result.serverTimestamp)}`);
8498
+ console.log(`${import_chalk39.default.bold("Server event hash")}: ${import_chalk39.default.cyan(result.serverEventHash)}`);
8414
8499
  }
8415
8500
  function parseJsonObject(cmdName, flagName, raw) {
8416
8501
  let parsed;
@@ -8502,7 +8587,7 @@ function parseTtl5(cmdName, raw) {
8502
8587
  }
8503
8588
  function parseRequestId(cmdName, raw) {
8504
8589
  if (raw === void 0 || raw === "") {
8505
- return (0, import_sdk31.uuidV4)();
8590
+ return (0, import_sdk32.uuidV4)();
8506
8591
  }
8507
8592
  if (raw.length === 0) {
8508
8593
  throw new Error(`${cmdName}: --request-id must be a non-empty string`);
@@ -8511,10 +8596,10 @@ function parseRequestId(cmdName, raw) {
8511
8596
  }
8512
8597
 
8513
8598
  // src/commands/work-list.ts
8514
- var import_sdk32 = require("@heyanon-arp/sdk");
8515
- var import_chalk39 = __toESM(require("chalk"));
8599
+ var import_sdk33 = require("@heyanon-arp/sdk");
8600
+ var import_chalk40 = __toESM(require("chalk"));
8516
8601
  init_api();
8517
- var ALLOWED_STATES3 = new Set(import_sdk32.WORK_LOG_STATES);
8602
+ var ALLOWED_STATES3 = new Set(import_sdk33.WORK_LOG_STATES);
8518
8603
  function registerWorkListCommand(root) {
8519
8604
  root.command("work-list").description("List work-log rows for a relationship (one row per (delegationId, requestId), oldest-first)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--state <s>", "Filter by exact state (requested|responded)").option("--delegation-id <uuid>", "Narrow to work-logs operating under a specific delegation id").option("--after <id>", "Cursor: pass the previous page's last `id` to fetch the next page").option("--limit <n>", "Max rows to return (1..100)", "20").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option(
8520
8605
  "--verbose",
@@ -8534,14 +8619,14 @@ async function runWorkList(relationshipId, opts) {
8534
8619
  "work-list: --verbose and --json are mutually exclusive. --json already emits the full payload; --verbose adds the framed dump on top of the human summary."
8535
8620
  );
8536
8621
  }
8537
- const limit = parseLimit7(opts.limit);
8622
+ const limit = parseLimit8(opts.limit);
8538
8623
  const state = parseState3(opts.state);
8539
8624
  const api = new ArpApiClient(opts.server);
8540
8625
  const sender = resolveSenderAgent("work-list", opts.server, opts.fromDid, opts.from);
8541
8626
  if (!opts.json) {
8542
- console.log(import_chalk39.default.dim(`Server: ${api.serverUrl}`));
8543
- console.log(import_chalk39.default.dim(`Signer: ${sender.did}`));
8544
- console.log(import_chalk39.default.dim(`Relationship: ${relationshipId}`));
8627
+ console.log(import_chalk40.default.dim(`Server: ${api.serverUrl}`));
8628
+ console.log(import_chalk40.default.dim(`Signer: ${sender.did}`));
8629
+ console.log(import_chalk40.default.dim(`Relationship: ${relationshipId}`));
8545
8630
  }
8546
8631
  const query = { limit };
8547
8632
  if (state) query.state = state;
@@ -8554,7 +8639,7 @@ async function runWorkList(relationshipId, opts) {
8554
8639
  return;
8555
8640
  }
8556
8641
  if (rows.length === 0) {
8557
- console.log(import_chalk39.default.dim("\n(no work-logs for this relationship)"));
8642
+ console.log(import_chalk40.default.dim("\n(no work-logs for this relationship)"));
8558
8643
  return;
8559
8644
  }
8560
8645
  console.log("");
@@ -8571,36 +8656,36 @@ async function runWorkList(relationshipId, opts) {
8571
8656
  }));
8572
8657
  }
8573
8658
  const lastId = rows[rows.length - 1].id;
8574
- console.log(import_chalk39.default.dim(`
8659
+ console.log(import_chalk40.default.dim(`
8575
8660
  ${rows.length} work-log row(s). Paginate with --after ${lastId}.`));
8576
8661
  }
8577
8662
  function formatWorkLogLine(w, selfDid, opts = {}) {
8578
8663
  const delegationPart = opts.fullIds ? w.delegationId : idHead3(w.delegationId);
8579
8664
  const requestPart = opts.fullIds ? w.requestId : truncate3(w.requestId, 16);
8580
- const id = import_chalk39.default.bold(`${delegationPart}/${requestPart}`);
8665
+ const id = import_chalk40.default.bold(`${delegationPart}/${requestPart}`);
8581
8666
  const state = colorState2(w.state).padEnd(stateColumnWidth2());
8582
8667
  const peerCallerHead = opts.fullIds ? w.callerDid : didHead5(w.callerDid);
8583
8668
  const peerPayeeHead = opts.fullIds ? w.payeeDid : didHead5(w.payeeDid);
8584
- const direction = w.callerDid === selfDid ? `${import_chalk39.default.bold("me")} \u2192 ${import_chalk39.default.dim(peerPayeeHead)}` : `${import_chalk39.default.dim(peerCallerHead)} \u2192 ${import_chalk39.default.bold("me")}`;
8669
+ const direction = w.callerDid === selfDid ? `${import_chalk40.default.bold("me")} \u2192 ${import_chalk40.default.dim(peerPayeeHead)}` : `${import_chalk40.default.dim(peerCallerHead)} \u2192 ${import_chalk40.default.bold("me")}`;
8585
8670
  const outcome = formatOutcome(w);
8586
8671
  return `${id} ${state} ${direction} ${outcome}`;
8587
8672
  }
8588
8673
  function colorState2(s) {
8589
8674
  switch (s) {
8590
- case import_sdk32.WorkLogStates.REQUESTED:
8591
- return import_chalk39.default.yellow("requested");
8592
- case import_sdk32.WorkLogStates.RESPONDED:
8593
- return import_chalk39.default.green("responded");
8675
+ case import_sdk33.WorkLogStates.REQUESTED:
8676
+ return import_chalk40.default.yellow("requested");
8677
+ case import_sdk33.WorkLogStates.RESPONDED:
8678
+ return import_chalk40.default.green("responded");
8594
8679
  }
8595
8680
  }
8596
8681
  function stateColumnWidth2() {
8597
8682
  return 9;
8598
8683
  }
8599
8684
  function formatOutcome(w) {
8600
- if (w.state === import_sdk32.WorkLogStates.REQUESTED) return import_chalk39.default.dim("(in flight)");
8601
- if (w.responseError) return import_chalk39.default.red(`error ${w.responseError.code}: ${truncate3(w.responseError.message, 32)}`);
8602
- if (w.responseOutput) return import_chalk39.default.cyan("ok");
8603
- return import_chalk39.default.dim("(empty response)");
8685
+ if (w.state === import_sdk33.WorkLogStates.REQUESTED) return import_chalk40.default.dim("(in flight)");
8686
+ if (w.responseError) return import_chalk40.default.red(`error ${w.responseError.code}: ${truncate3(w.responseError.message, 32)}`);
8687
+ if (w.responseOutput) return import_chalk40.default.cyan("ok");
8688
+ return import_chalk40.default.dim("(empty response)");
8604
8689
  }
8605
8690
  function idHead3(id) {
8606
8691
  if (id.length <= 12) return id;
@@ -8621,7 +8706,7 @@ function parseState3(raw) {
8621
8706
  }
8622
8707
  return raw;
8623
8708
  }
8624
- function parseLimit7(raw) {
8709
+ function parseLimit8(raw) {
8625
8710
  if (raw === void 0) return 20;
8626
8711
  const n = Number(raw);
8627
8712
  if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1 || n > 100) {
@@ -8798,6 +8883,7 @@ async function main() {
8798
8883
  registerEnvelopeCommand(program);
8799
8884
  registerDelegationCommands(program);
8800
8885
  registerDelegationsCommand(program);
8886
+ registerTasksCommand(program);
8801
8887
  registerWorkCommands(program);
8802
8888
  registerWorkListCommand(program);
8803
8889
  registerReceiptCommands(program);
@@ -8805,7 +8891,7 @@ async function main() {
8805
8891
  registerReputationCommand(program);
8806
8892
  registerStatsCommand(program);
8807
8893
  registerWalletCommands(program);
8808
- (0, import_shield3.installMiddleware)(program);
8894
+ (0, import_shield4.installMiddleware)(program);
8809
8895
  try {
8810
8896
  await program.parseAsync(process.argv);
8811
8897
  } catch (err) {