@heyanon-arp/cli 0.0.17 → 0.0.19

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 (3) hide show
  1. package/dist/cli.js +999 -1078
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -345,6 +345,10 @@ var init_api = __esm({
345
345
  async discoverProfile(did) {
346
346
  return this.get(`/v1/discovery/agents/${encodeURIComponent(did)}/profile`);
347
347
  }
348
+ /** Public `GET /v1/discovery/agents/by-name/:name`. Resolves a unique name → composed profile (incl. DID). 404 if unknown. */
349
+ async discoverByName(name) {
350
+ return this.get(`/v1/discovery/agents/by-name/${encodeURIComponent(name)}`);
351
+ }
348
352
  /**
349
353
  * Public `GET /v1/escrow/config`. Returns the live on-chain V2
350
354
  * Config PDA (fees / pause / stakes / windows). No auth.
@@ -613,6 +617,14 @@ var init_api = __esm({
613
617
  query
614
618
  );
615
619
  }
620
+ /**
621
+ * Signed `GET /v1/escrow/disputes/:delegationId`. The autonomous arbiter's
622
+ * verdict for a disputed delegation — winner + DID, evaluator source,
623
+ * reasoning, status, and the on-chain resolve signature. Parties only.
624
+ */
625
+ async getDisputeResolution(delegationId, signer) {
626
+ return this.signedRequest("GET", `/v1/escrow/disputes/${encodeURIComponent(delegationId)}`, null, signer);
627
+ }
616
628
  /**
617
629
  * Build the same canonical-JSON signing input the arp-server's
618
630
  * `SignedRequestGuard` recomputes (`{ method, path, query, body }`),
@@ -722,7 +734,7 @@ var import_simple_update_notifier = __toESM(require("simple-update-notifier"));
722
734
  // package.json
723
735
  var package_default = {
724
736
  name: "@heyanon-arp/cli",
725
- version: "0.0.17",
737
+ version: "0.0.19",
726
738
  description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
727
739
  license: "MIT",
728
740
  keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
@@ -767,7 +779,7 @@ var package_default = {
767
779
  };
768
780
 
769
781
  // src/commands/agents.ts
770
- var import_sdk2 = require("@heyanon-arp/sdk");
782
+ var import_sdk3 = require("@heyanon-arp/sdk");
771
783
  var import_chalk3 = __toESM(require("chalk"));
772
784
  init_api();
773
785
 
@@ -912,6 +924,7 @@ function formatAgentsTable(rows) {
912
924
  // src/state.ts
913
925
  var import_node_fs3 = require("fs");
914
926
  var import_node_path4 = require("path");
927
+ var import_sdk2 = require("@heyanon-arp/sdk");
915
928
  init_api();
916
929
 
917
930
  // src/credentials.ts
@@ -1137,13 +1150,35 @@ function warnIfForeignOwner(agent, serverUrl) {
1137
1150
  `
1138
1151
  );
1139
1152
  }
1140
- function resolveSenderAgent(cmdName, serverOverride, explicitFromDid) {
1153
+ function resolveSenderAgent(cmdName, serverOverride, explicitFromDid, explicitFromName) {
1141
1154
  const resolvedServerUrl = resolveServerUrl(serverOverride);
1155
+ if (explicitFromDid && explicitFromName) {
1156
+ throw new Error(`${cmdName}: pass either --from <name> OR --from-did <did>, not both.`);
1157
+ }
1142
1158
  if (explicitFromDid) {
1159
+ if (!explicitFromDid.startsWith("did:arp:")) {
1160
+ throw new Error(`${cmdName}: --from-did expects a did:arp:<...> DID \u2014 for an agent name use '--from ${explicitFromDid}'.`);
1161
+ }
1143
1162
  const agent = loadAgentOrThrow(serverOverride, explicitFromDid);
1144
1163
  warnIfForeignOwner(agent, resolvedServerUrl);
1145
1164
  return agent;
1146
1165
  }
1166
+ if (explicitFromName) {
1167
+ const wanted = (0, import_sdk2.normalizeName)(explicitFromName);
1168
+ const named = listAgents().filter((row) => row.serverUrl === resolvedServerUrl && row.agent.name === wanted);
1169
+ if (named.length === 1) {
1170
+ warnIfForeignOwner(named[0].agent, resolvedServerUrl);
1171
+ return named[0].agent;
1172
+ }
1173
+ if (named.length === 0) {
1174
+ throw new Error(`${cmdName}: no local agent named '${wanted}' for ${resolvedServerUrl}. Pass its --from-did <did>, or register/recover that agent locally first.`);
1175
+ }
1176
+ const dups = named.map((row) => ` ${row.agent.did}`).join("\n");
1177
+ throw new Error(
1178
+ `${cmdName}: ${named.length} local agents share the name '${wanted}' for ${resolvedServerUrl} \u2014 ambiguous. Pass --from-did <did> instead. Candidates:
1179
+ ${dups}`
1180
+ );
1181
+ }
1147
1182
  const onServer = listAgents().filter((row) => row.serverUrl === resolvedServerUrl);
1148
1183
  if (onServer.length === 1) {
1149
1184
  warnIfForeignOwner(onServer[0].agent, resolvedServerUrl);
@@ -1154,7 +1189,7 @@ function resolveSenderAgent(cmdName, serverOverride, explicitFromDid) {
1154
1189
  }
1155
1190
  const list = onServer.map((row) => ` ${row.agent.did}${row.agent.name ? ` (${row.agent.name})` : ""}`).join("\n");
1156
1191
  throw new Error(
1157
- `${cmdName}: ${onServer.length} agents registered for ${resolvedServerUrl} \u2014 refusing to silently sign as one of them. Pass --from-did <did> to disambiguate. Candidates:
1192
+ `${cmdName}: ${onServer.length} agents registered for ${resolvedServerUrl} \u2014 refusing to silently sign as one of them. Pass --from <name> or --from-did <did> to disambiguate. Candidates:
1158
1193
  ${list}`
1159
1194
  );
1160
1195
  }
@@ -1173,16 +1208,16 @@ function listAgents() {
1173
1208
  var import_chalk2 = __toESM(require("chalk"));
1174
1209
  init_api();
1175
1210
  function registerLifecycleCommands(root) {
1176
- root.command("update").description("Update an agent profile (name / description / tags). At least one flag is required.").argument("[did]", "Agent DID (did:arp:...) \u2014 optional when --from-did is given OR exactly one agent is registered for the resolved server.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Alias for the positional <did> \u2014 accepted for consistency with other signed commands. Must match the positional if both are given.").option("--name <s>", "New display name").option("--description <s>", "New description").option("--tag <s>", "Capability tag \u2014 REPLACES the existing list. Repeatable: --tag translation --tag fr", accumulate, []).option("--clear-tags", "Drop all tags (cannot be combined with --tag)", false).option("--json", "Machine-readable mode \u2014 emit the updated profile as a single JSON object on stdout (AgentPublic). Prelude moves to stderr. ", false).action(
1211
+ root.command("update").description("Update an agent profile (description / tags). At least one flag is required. The agent name is immutable and cannot be changed.").argument("[did]", "Agent DID (did:arp:...) \u2014 optional when --from-did is given OR exactly one agent is registered for the resolved server.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Alias for the positional <did> \u2014 accepted for consistency with other signed commands. Must match the positional if both are given.").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--description <s>", "New description").option("--tag <s>", "Capability tag \u2014 REPLACES the existing list. Repeatable: --tag translation --tag fr", accumulate, []).option("--clear-tags", "Drop all tags (cannot be combined with --tag)", false).option("--json", "Machine-readable mode \u2014 emit the updated profile as a single JSON object on stdout (AgentPublic). Prelude moves to stderr. ", false).action(
1177
1212
  async (did, opts) => {
1178
1213
  if (did !== void 0 && opts.fromDid !== void 0 && did !== opts.fromDid) {
1179
1214
  throw new Error(`update: positional <did> (${did}) and --from-did (${opts.fromDid}) disagree \u2014 pass only one`);
1180
1215
  }
1181
1216
  const explicitDid = did ?? opts.fromDid;
1182
- const targetDid = (explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("update", opts.server, void 0)).did;
1217
+ const targetDid = (explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("update", opts.server, void 0, opts.from)).did;
1183
1218
  const body = buildUpdateBody(opts);
1184
1219
  if (Object.keys(body).length === 0) {
1185
- throw new Error("update: pass at least one of --name / --description / --tag / --clear-tags");
1220
+ throw new Error("update: pass at least one of --description / --tag / --clear-tags");
1186
1221
  }
1187
1222
  const agent = await actSigned(targetDid, opts.server, opts.json, (api, signer) => api.updateAgent(targetDid, body, signer));
1188
1223
  updateAgentLocal(opts.server, targetDid, {
@@ -1206,7 +1241,6 @@ function buildUpdateBody(opts) {
1206
1241
  throw new Error("update: --clear-tags cannot be combined with --tag");
1207
1242
  }
1208
1243
  const body = {};
1209
- if (opts.name !== void 0) body.name = opts.name;
1210
1244
  if (opts.description !== void 0) body.description = opts.description;
1211
1245
  if (opts.clearTags) {
1212
1246
  body.tags = [];
@@ -1265,10 +1299,10 @@ function registerAgentsCommand(root) {
1265
1299
  }
1266
1300
  async function runAgents(opts) {
1267
1301
  const limit = parseLimit(opts.limit);
1268
- if (opts.sort && opts.sort !== import_sdk2.DiscoverySorts.REPUTATION && opts.sort !== import_sdk2.DiscoverySorts.RECENT && opts.sort !== import_sdk2.DiscoverySorts.CREATED) {
1302
+ if (opts.sort && opts.sort !== import_sdk3.DiscoverySorts.REPUTATION && opts.sort !== import_sdk3.DiscoverySorts.RECENT && opts.sort !== import_sdk3.DiscoverySorts.CREATED) {
1269
1303
  throw new Error(`agents: --sort must be 'reputation', 'recent', or 'created' (got '${opts.sort}')`);
1270
1304
  }
1271
- const sort = opts.sort === import_sdk2.DiscoverySorts.RECENT ? import_sdk2.DiscoverySorts.RECENT : opts.sort === import_sdk2.DiscoverySorts.CREATED ? import_sdk2.DiscoverySorts.CREATED : import_sdk2.DiscoverySorts.REPUTATION;
1305
+ const sort = opts.sort === import_sdk3.DiscoverySorts.RECENT ? import_sdk3.DiscoverySorts.RECENT : opts.sort === import_sdk3.DiscoverySorts.CREATED ? import_sdk3.DiscoverySorts.CREATED : import_sdk3.DiscoverySorts.REPUTATION;
1272
1306
  const api = new ArpApiClient(opts.server);
1273
1307
  progress(opts.json, import_chalk3.default.dim(`Server: ${api.serverUrl}`));
1274
1308
  const query = { limit, sort };
@@ -1277,7 +1311,7 @@ async function runAgents(opts) {
1277
1311
  if (opts.accountId) query.accountId = opts.accountId;
1278
1312
  if (opts.accepts) query.accepts = resolveAcceptsAsset(opts.accepts);
1279
1313
  if (opts.online) query.online = true;
1280
- if (sort === import_sdk2.DiscoverySorts.CREATED) {
1314
+ if (sort === import_sdk3.DiscoverySorts.CREATED) {
1281
1315
  if (opts.after) query.after = opts.after;
1282
1316
  } else {
1283
1317
  query.page = parsePage(opts.page);
@@ -1316,10 +1350,10 @@ ${rule}`);
1316
1350
  `);
1317
1351
  }
1318
1352
  if (pagination.hasMore) {
1319
- if (sort === import_sdk2.DiscoverySorts.CREATED && pagination.nextCursor) {
1353
+ if (sort === import_sdk3.DiscoverySorts.CREATED && pagination.nextCursor) {
1320
1354
  console.log(import_chalk3.default.dim(`
1321
1355
  Next page: re-run with --after ${pagination.nextCursor}`));
1322
- } else if (sort !== import_sdk2.DiscoverySorts.CREATED) {
1356
+ } else if (sort !== import_sdk3.DiscoverySorts.CREATED) {
1323
1357
  console.log(import_chalk3.default.dim(`
1324
1358
  Next page: re-run with --page ${parsePage(opts.page) + 1}`));
1325
1359
  }
@@ -1358,7 +1392,7 @@ function parsePage(raw) {
1358
1392
  return n;
1359
1393
  }
1360
1394
  function resolveAcceptsAsset(input) {
1361
- const resolved = (0, import_sdk2.resolveAsset)(input);
1395
+ const resolved = (0, import_sdk3.resolveAsset)(input);
1362
1396
  if (!resolved) {
1363
1397
  throw new Error(`agents: --accepts '${input}' is not a known asset shorthand or a valid CAIP-19 id.`);
1364
1398
  }
@@ -1394,9 +1428,9 @@ function registerAcceptPrefsCommands(agents) {
1394
1428
  });
1395
1429
  prefs.command("show").description(
1396
1430
  "Read an agent's published accept-prefs (any DID \u2014 the read is signed with YOUR local agent key; any registered agent may read). Buyers: run this BEFORE `delegation offer` so the offer matches"
1397
- ).argument("<did>", "Agent DID to inspect (any agent, not just your own)").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("--json", "Emit only the AcceptPrefs JSON (or null) on stdout \u2014 jq-pipeable", false).action(async (did, _opts, cmd) => {
1431
+ ).argument("<did>", "Agent DID to inspect (any agent, not just your own)").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("--json", "Emit only the AcceptPrefs JSON (or null) on stdout \u2014 jq-pipeable", false).action(async (did, _opts, cmd) => {
1398
1432
  const opts = cmd.optsWithGlobals();
1399
- const sender = resolveSenderAgent("agents accept-prefs show", opts.server, opts.fromDid);
1433
+ const sender = resolveSenderAgent("agents accept-prefs show", opts.server, opts.fromDid, opts.from);
1400
1434
  const api = new ArpApiClient(opts.server);
1401
1435
  progress(opts.json, import_chalk3.default.dim(`Server: ${api.serverUrl}`));
1402
1436
  progress(opts.json, import_chalk3.default.dim(`Signer: ${sender.did}`));
@@ -1487,11 +1521,11 @@ function printAcceptPrefs(prefs) {
1487
1521
  }
1488
1522
 
1489
1523
  // src/commands/assets.ts
1490
- var import_sdk3 = require("@heyanon-arp/sdk");
1524
+ var import_sdk4 = require("@heyanon-arp/sdk");
1491
1525
  var import_chalk4 = __toESM(require("chalk"));
1492
1526
  function renderAssetsText() {
1493
1527
  const lines = [];
1494
- for (const [cluster, assets] of Object.entries(import_sdk3.ASSET_WHITELIST)) {
1528
+ for (const [cluster, assets] of Object.entries(import_sdk4.ASSET_WHITELIST)) {
1495
1529
  lines.push(import_chalk4.default.bold(cluster));
1496
1530
  for (const a of assets) {
1497
1531
  const key = `${a.symbol}:${cluster}`;
@@ -1507,7 +1541,7 @@ function renderAssetsText() {
1507
1541
  function registerAssetsCommand(root) {
1508
1542
  root.command("assets").description("List the payment-asset whitelist (per cluster) \u2014 currencies the server accepts for delegations").option("--json", "machine-readable output (the per-cluster whitelist table)").action((opts) => {
1509
1543
  if (opts.json) {
1510
- console.log(formatJson(import_sdk3.ASSET_WHITELIST));
1544
+ console.log(formatJson(import_sdk4.ASSET_WHITELIST));
1511
1545
  return;
1512
1546
  }
1513
1547
  console.log(renderAssetsText());
@@ -1515,26 +1549,26 @@ function registerAssetsCommand(root) {
1515
1549
  }
1516
1550
 
1517
1551
  // src/commands/block.ts
1518
- var import_sdk4 = require("@heyanon-arp/sdk");
1552
+ var import_sdk5 = require("@heyanon-arp/sdk");
1519
1553
  var import_chalk5 = __toESM(require("chalk"));
1520
1554
  init_api();
1521
1555
  function resolveSigningAgent(opts) {
1522
- return opts.fromDid !== void 0 ? loadAgentOrThrow(opts.server, opts.fromDid) : resolveSenderAgent("block", opts.server, void 0);
1556
+ return opts.fromDid !== void 0 ? loadAgentOrThrow(opts.server, opts.fromDid) : resolveSenderAgent("block", opts.server, void 0, opts.from);
1523
1557
  }
1524
1558
  function formatBlockRow(b) {
1525
- const scope = b.scope === import_sdk4.InboxBlockScopes.ACCOUNT ? import_chalk5.default.yellow("account") : import_chalk5.default.cyan("did");
1559
+ const scope = b.scope === import_sdk5.InboxBlockScopes.ACCOUNT ? import_chalk5.default.yellow("account") : import_chalk5.default.cyan("did");
1526
1560
  const reason = b.reason ? import_chalk5.default.dim(` \u2014 ${b.reason}`) : "";
1527
1561
  return `${scope.padEnd(7)} ${b.did}${reason} ${import_chalk5.default.dim(b.blockedAt)}`;
1528
1562
  }
1529
1563
  function registerBlockCommand(root) {
1530
1564
  const block = root.command("block").description("Manage your inbox blocklist \u2014 refuse inbound messages from an agent (and, by default, its whole owner account).");
1531
- block.command("add <did>").description("Block an agent. Default blocks the target\u2019s ENTIRE owner account (every sibling agent); --did-only blocks just this DID. You cannot block your own account.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Which of your agents signs (defaults to your sole local agent). The block applies account-wide regardless of which signs.").option("--did-only", "Block only this exact DID, not the whole owner account", false).option("--reason <text>", "Private note (max 512 chars), visible only to you").option("--json", "Machine-readable output", false).action(async (did, opts) => {
1565
+ block.command("add <did>").description("Block an agent. Default blocks the target\u2019s ENTIRE owner account (every sibling agent); --did-only blocks just this DID. You cannot block your own account.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Which of your agents signs (defaults to your sole local agent). The block applies account-wide regardless of which signs.").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--did-only", "Block only this exact DID, not the whole owner account", false).option("--reason <text>", "Private note (max 512 chars), visible only to you").option("--json", "Machine-readable output", false).action(async (did, opts) => {
1532
1566
  await runAdd(did, opts);
1533
1567
  });
1534
- block.command("remove <did>").alias("rm").description("Remove a block. Pass the same DID (+ --did-only flag) you blocked with.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Which of your agents signs (defaults to your sole local agent).").option("--did-only", "The original block was DID-level (didOnly)", false).option("--json", "Machine-readable output", false).action(async (did, opts) => {
1568
+ block.command("remove <did>").alias("rm").description("Remove a block. Pass the same DID (+ --did-only flag) you blocked with.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Which of your agents signs (defaults to your sole local agent).").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--did-only", "The original block was DID-level (didOnly)", false).option("--json", "Machine-readable output", false).action(async (did, opts) => {
1535
1569
  await runRemove(did, opts);
1536
1570
  });
1537
- block.command("list").description("List your account\u2019s blocks. Each row shows the DID you named + scope \u2014 never the resolved owner account or its other agents.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Which of your agents signs (defaults to your sole local agent).").option("--json", "Machine-readable output \u2014 a JSON array.", false).action(async (opts) => {
1571
+ block.command("list").description("List your account\u2019s blocks. Each row shows the DID you named + scope \u2014 never the resolved owner account or its other agents.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Which of your agents signs (defaults to your sole local agent).").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--json", "Machine-readable output \u2014 a JSON array.", false).action(async (opts) => {
1538
1572
  await runList(opts);
1539
1573
  });
1540
1574
  }
@@ -1547,7 +1581,7 @@ async function runAdd(did, opts) {
1547
1581
  jsonOut(result);
1548
1582
  return;
1549
1583
  }
1550
- const what = result.scope === import_sdk4.InboxBlockScopes.ACCOUNT ? `the owner account of ${did} (all its agents)` : did;
1584
+ const what = result.scope === import_sdk5.InboxBlockScopes.ACCOUNT ? `the owner account of ${did} (all its agents)` : did;
1551
1585
  console.log(import_chalk5.default.green(`\u2713 Blocked ${what}.`));
1552
1586
  }
1553
1587
  async function runRemove(did, opts) {
@@ -1663,15 +1697,15 @@ function unknownKey(key) {
1663
1697
 
1664
1698
  // src/commands/delegation.ts
1665
1699
  var import_node_fs4 = require("fs");
1666
- var import_sdk10 = require("@heyanon-arp/sdk");
1667
- var import_chalk8 = __toESM(require("chalk"));
1700
+ var import_sdk12 = require("@heyanon-arp/sdk");
1701
+ var import_chalk9 = __toESM(require("chalk"));
1668
1702
  init_api();
1669
1703
 
1670
1704
  // src/id-format.ts
1671
- var import_sdk5 = require("@heyanon-arp/sdk");
1705
+ var import_sdk6 = require("@heyanon-arp/sdk");
1672
1706
  var UUID_RE = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
1673
1707
  var OBJECT_ID_24_HEX_RE = /^[0-9a-f]{24}$/;
1674
- var SHA256_PREFIX_RE = import_sdk5.SHA256_HEX_RE;
1708
+ var SHA256_PREFIX_RE = import_sdk6.SHA256_HEX_RE;
1675
1709
  var UUID_NO_DASHES_RE = /^[a-fA-F0-9]{32}$/;
1676
1710
  function describeNonUuidShape(raw) {
1677
1711
  if (raw === "") return "empty string";
@@ -1702,10 +1736,31 @@ function requireUuid(cmdName, raw, label) {
1702
1736
  throw new Error(hint ? `${base} \u2014 ${hint}` : base);
1703
1737
  }
1704
1738
 
1705
- // src/commands/status.ts
1706
- var import_sdk6 = require("@heyanon-arp/sdk");
1739
+ // src/resolve-recipient.ts
1740
+ var import_sdk7 = require("@heyanon-arp/sdk");
1707
1741
  var import_chalk7 = __toESM(require("chalk"));
1708
1742
  init_api();
1743
+ async function resolveRecipient(serverOverride, cmdName, input, opts = {}) {
1744
+ if (input.startsWith("did:arp:")) {
1745
+ if (!(0, import_sdk7.isValidDid)(input)) {
1746
+ throw new Error(`${cmdName}: '${input}' starts with did:arp: but is not a valid DID (base58btc-encoded 32-byte Ed25519 pubkey).`);
1747
+ }
1748
+ return input;
1749
+ }
1750
+ const name = (0, import_sdk7.normalizeName)(input);
1751
+ if (!(0, import_sdk7.isValidAgentName)(name)) {
1752
+ throw new Error(`${cmdName}: '${input}' is neither a DID (did:arp:...) nor a valid agent name (lowercase a-z0-9_, 3-32 chars).`);
1753
+ }
1754
+ const api = new ArpApiClient(serverOverride);
1755
+ const profile = await api.discoverByName(name);
1756
+ warn(opts.json, import_chalk7.default.dim(`Resolved ${import_chalk7.default.cyan(name)} \u2192 ${profile.did}${profile.description ? ` (${profile.description})` : ""}`));
1757
+ return profile.did;
1758
+ }
1759
+
1760
+ // src/commands/status.ts
1761
+ var import_sdk8 = require("@heyanon-arp/sdk");
1762
+ var import_chalk8 = __toESM(require("chalk"));
1763
+ init_api();
1709
1764
  var UNTIL_PHASES = [
1710
1765
  "delegation.offered",
1711
1766
  "delegation.accepted",
@@ -1726,7 +1781,7 @@ var UNTIL_PHASES = [
1726
1781
  var WAIT_DEFAULT_INTERVAL_SEC = 3;
1727
1782
  var WAIT_DEFAULT_TIMEOUT_SEC = 300;
1728
1783
  function registerStatusCommand(root) {
1729
- root.command("status").description("Where am I in the work cycle? FSM state + next-action hint for ONE relationship (signed reads)").argument("<relationship-id>", "Relationship UUID").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("--json", "Machine-readable: single JSON object with the composed summary. Pipe-safe.", false).option(
1784
+ root.command("status").description("Where am I in the work cycle? FSM state + next-action hint for ONE relationship (signed reads)").argument("<relationship-id>", "Relationship UUID").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("--json", "Machine-readable: single JSON object with the composed summary. Pipe-safe.", false).option(
1730
1785
  "--wait",
1731
1786
  `Block and poll until you can act (\`nextActionOwner === 'me'\` OR \`nextActionOwner === 'either' AND relationshipState === 'active'\`) OR the cycle terminates (COMPLETE / closed / not_found). Exits immediately if either condition is already true at first read. Default cadence ${WAIT_DEFAULT_INTERVAL_SEC}s, --wait-timeout ${WAIT_DEFAULT_TIMEOUT_SEC}s. Pairs with --json so a wrapping script can branch on the new state. Exit code 124 on timeout (unix \`timeout\` convention). Combine with --wait-verbose to see per-tick state snapshots during long waits \u2014 useful for "is it alive or stuck?" diagnosis without spawning a separate \`inbox --tail\` shell.`,
1732
1787
  false
@@ -1751,11 +1806,11 @@ function registerStatusCommand(root) {
1751
1806
  }
1752
1807
  async function runStatus(relationshipId, opts) {
1753
1808
  const api = new ArpApiClient(opts.server);
1754
- const sender = resolveSenderAgent("status", opts.server, opts.fromDid);
1809
+ const sender = resolveSenderAgent("status", opts.server, opts.fromDid, opts.from);
1755
1810
  if (!opts.json) {
1756
- console.log(import_chalk7.default.dim(`Server: ${api.serverUrl}`));
1757
- console.log(import_chalk7.default.dim(`Signer: ${sender.did}`));
1758
- console.log(import_chalk7.default.dim(`Relationship: ${relationshipId}`));
1811
+ console.log(import_chalk8.default.dim(`Server: ${api.serverUrl}`));
1812
+ console.log(import_chalk8.default.dim(`Signer: ${sender.did}`));
1813
+ console.log(import_chalk8.default.dim(`Relationship: ${relationshipId}`));
1759
1814
  }
1760
1815
  const signer = makeSigner(sender);
1761
1816
  if (!opts.wait) {
@@ -1787,7 +1842,7 @@ async function runStatus(relationshipId, opts) {
1787
1842
  async function awaitFsmTransitionAfterAction(input) {
1788
1843
  const { api, signerDid, signer, relationshipId, untilPhase, waitIntervalSec, waitTimeoutSec, waitVerbose, json } = input;
1789
1844
  if (!json) {
1790
- console.log(import_chalk7.default.dim(`
1845
+ console.log(import_chalk8.default.dim(`
1791
1846
  [--wait-until ${untilPhase}] polling relationship ${relationshipId} (interval=${waitIntervalSec}s timeout=${waitTimeoutSec}s)`));
1792
1847
  }
1793
1848
  const outcome = await runWaitLoop({
@@ -1804,13 +1859,13 @@ async function awaitFsmTransitionAfterAction(input) {
1804
1859
  }
1805
1860
  }
1806
1861
  async function runWaitLoop(opts) {
1807
- const isTerminal = (s) => s.cycleComplete || s.relationshipState === import_sdk6.RelationshipStates.CLOSED || s.relationshipState === "not_found";
1862
+ const isTerminal = (s) => s.cycleComplete || s.relationshipState === import_sdk8.RelationshipStates.CLOSED || s.relationshipState === "not_found";
1808
1863
  const isActionable = (s) => {
1809
1864
  if (s.nextActionOwner === "me") {
1810
1865
  if (s.relationshipState === "unknown") return false;
1811
1866
  return true;
1812
1867
  }
1813
- if (s.nextActionOwner === "either" && s.relationshipState === import_sdk6.RelationshipStates.ACTIVE) {
1868
+ if (s.nextActionOwner === "either" && s.relationshipState === import_sdk8.RelationshipStates.ACTIVE) {
1814
1869
  return true;
1815
1870
  }
1816
1871
  return false;
@@ -1826,7 +1881,7 @@ async function runWaitLoop(opts) {
1826
1881
  }
1827
1882
  if (isUntilReached !== null && isUntilReached(initial)) {
1828
1883
  if (opts.json) opts.log(JSON.stringify(initial));
1829
- else opts.log(import_chalk7.default.dim(`
1884
+ else opts.log(import_chalk8.default.dim(`
1830
1885
  [--wait] Phase '${opts.until}' already reached \u2014 exiting without polling.`));
1831
1886
  return { timedOut: false, last: initial };
1832
1887
  }
@@ -1837,13 +1892,13 @@ async function runWaitLoop(opts) {
1837
1892
  else {
1838
1893
  if (opts.until !== void 0) {
1839
1894
  opts.log(
1840
- import_chalk7.default.yellow(
1895
+ import_chalk8.default.yellow(
1841
1896
  `
1842
1897
  [--wait] Terminal state (${initial.relationshipState}, cycleComplete=${initial.cycleComplete}) reached before phase '${opts.until}' \u2014 exiting; phase unreachable.`
1843
1898
  )
1844
1899
  );
1845
1900
  } else {
1846
- opts.log(import_chalk7.default.dim(`
1901
+ opts.log(import_chalk8.default.dim(`
1847
1902
  [--wait] Already terminal \u2014 exiting.`));
1848
1903
  }
1849
1904
  }
@@ -1851,15 +1906,15 @@ async function runWaitLoop(opts) {
1851
1906
  }
1852
1907
  if (opts.until === void 0 && isActionable(initial)) {
1853
1908
  if (opts.json) opts.log(JSON.stringify(initial));
1854
- else opts.log(import_chalk7.default.dim(`
1909
+ else opts.log(import_chalk8.default.dim(`
1855
1910
  [--wait] Your turn already (nextActionOwner=${initial.nextActionOwner}) \u2014 exiting without polling.`));
1856
1911
  return { timedOut: false, last: initial };
1857
1912
  }
1858
1913
  if (!opts.json) {
1859
1914
  const blockerLabel = opts.until !== void 0 ? `Awaiting phase '${opts.until}'` : initial.nextActionOwner === "counterparty" ? "Counterparty owes the next move" : initial.nextActionOwner === "either" ? "Either side may act" : `Awaiting state change (currently ${initial.relationshipState}, nextActionOwner=${initial.nextActionOwner})`;
1860
- opts.log(import_chalk7.default.dim(`
1915
+ opts.log(import_chalk8.default.dim(`
1861
1916
  [--wait] ${blockerLabel}. Polling every ${opts.waitIntervalSec}s, timeout ${opts.waitTimeoutSec}s.`));
1862
- opts.log(import_chalk7.default.dim(`[--wait] Initial hint: ${initial.nextActionHint}`));
1917
+ opts.log(import_chalk8.default.dim(`[--wait] Initial hint: ${initial.nextActionHint}`));
1863
1918
  }
1864
1919
  const startedAt = localNow();
1865
1920
  const deadline = startedAt + opts.waitTimeoutSec * 1e3;
@@ -1879,7 +1934,7 @@ async function runWaitLoop(opts) {
1879
1934
  } else {
1880
1935
  target = `nextActionOwner=${next.nextActionOwner}`;
1881
1936
  }
1882
- opts.log(import_chalk7.default.dim(`[--wait tick ${tickIndex}/${maxTicks}] state=${next.relationshipState}, ${formatPhaseSnapshot(next)} (${target})`));
1937
+ opts.log(import_chalk8.default.dim(`[--wait tick ${tickIndex}/${maxTicks}] state=${next.relationshipState}, ${formatPhaseSnapshot(next)} (${target})`));
1883
1938
  }
1884
1939
  if (exitPredicate(next)) {
1885
1940
  const phaseReached = isUntilReached !== null ? isUntilReached(next) : false;
@@ -1889,16 +1944,16 @@ async function runWaitLoop(opts) {
1889
1944
  opts.log("");
1890
1945
  if (opts.until !== void 0) {
1891
1946
  if (phaseReached) {
1892
- opts.log(import_chalk7.default.green(`[--wait] Phase '${opts.until}' reached.`));
1947
+ opts.log(import_chalk8.default.green(`[--wait] Phase '${opts.until}' reached.`));
1893
1948
  } else {
1894
1949
  opts.log(
1895
- import_chalk7.default.yellow(
1950
+ import_chalk8.default.yellow(
1896
1951
  `[--wait] Terminal state (${next.relationshipState}, cycleComplete=${next.cycleComplete}) reached before phase '${opts.until}' \u2014 phase unreachable.`
1897
1952
  )
1898
1953
  );
1899
1954
  }
1900
1955
  } else {
1901
- opts.log(import_chalk7.default.green(`[--wait] ${isTerminal(next) ? "Cycle terminated" : `Your turn (owner=${next.nextActionOwner})`}.`));
1956
+ opts.log(import_chalk8.default.green(`[--wait] ${isTerminal(next) ? "Cycle terminated" : `Your turn (owner=${next.nextActionOwner})`}.`));
1902
1957
  }
1903
1958
  opts.log(formatStatusReport(next));
1904
1959
  }
@@ -1911,14 +1966,14 @@ async function runWaitLoop(opts) {
1911
1966
  } else {
1912
1967
  if (opts.until !== void 0) {
1913
1968
  opts.log(
1914
- import_chalk7.default.yellow(
1969
+ import_chalk8.default.yellow(
1915
1970
  `
1916
1971
  [--wait] Timed out after ${opts.waitTimeoutSec}s without reaching phase '${opts.until}' (latest state: ${last.relationshipState}, hint: ${last.nextActionHint}).`
1917
1972
  )
1918
1973
  );
1919
1974
  } else {
1920
1975
  opts.log(
1921
- import_chalk7.default.yellow(`
1976
+ import_chalk8.default.yellow(`
1922
1977
  [--wait] Timed out after ${opts.waitTimeoutSec}s without an actionable or terminal transition (your turn never came, cycle still in flight).`)
1923
1978
  );
1924
1979
  }
@@ -1946,41 +2001,41 @@ function parseUntilPhase(raw) {
1946
2001
  function isPhaseTerminallyUnreachable(phase, s) {
1947
2002
  if (untilPhaseMatched(phase, s)) return false;
1948
2003
  if (s.relationshipState === "not_found") return true;
1949
- if (s.relationshipState === import_sdk6.RelationshipStates.CLOSED && phase !== "relationship.closed") return true;
2004
+ if (s.relationshipState === import_sdk8.RelationshipStates.CLOSED && phase !== "relationship.closed") return true;
1950
2005
  return false;
1951
2006
  }
1952
2007
  function untilPhaseMatched(phase, s) {
1953
2008
  switch (phase) {
1954
2009
  case "delegation.offered":
1955
- return s.latestDelegation?.state === import_sdk6.DelegationStates.OFFERED;
2010
+ return s.latestDelegation?.state === import_sdk8.DelegationStates.OFFERED;
1956
2011
  case "delegation.accepted":
1957
- return s.latestDelegation?.state === import_sdk6.DelegationStates.ACCEPTED;
2012
+ return s.latestDelegation?.state === import_sdk8.DelegationStates.ACCEPTED;
1958
2013
  case "delegation.locked":
1959
- return s.latestDelegation?.state === import_sdk6.DelegationStates.LOCKED;
2014
+ return s.latestDelegation?.state === import_sdk8.DelegationStates.LOCKED;
1960
2015
  case "delegation.disputing":
1961
- return s.latestDelegation?.state === import_sdk6.DelegationStates.DISPUTING;
2016
+ return s.latestDelegation?.state === import_sdk8.DelegationStates.DISPUTING;
1962
2017
  case "delegation.canceled":
1963
- return s.latestDelegation?.state === import_sdk6.DelegationStates.CANCELED;
2018
+ return s.latestDelegation?.state === import_sdk8.DelegationStates.CANCELED;
1964
2019
  case "delegation.declined":
1965
- return s.latestDelegation?.state === import_sdk6.DelegationStates.DECLINED;
2020
+ return s.latestDelegation?.state === import_sdk8.DelegationStates.DECLINED;
1966
2021
  case "work.requested":
1967
- return s.latestWorkLog?.state === import_sdk6.WorkLogStates.REQUESTED;
2022
+ return s.latestWorkLog?.state === import_sdk8.WorkLogStates.REQUESTED;
1968
2023
  case "work.responded":
1969
- return s.latestWorkLog?.state === import_sdk6.WorkLogStates.RESPONDED;
2024
+ return s.latestWorkLog?.state === import_sdk8.WorkLogStates.RESPONDED;
1970
2025
  case "receipt.proposed":
1971
2026
  return s.latestReceipt != null;
1972
2027
  case "relationship.pending":
1973
- return s.relationshipState === import_sdk6.RelationshipStates.PENDING;
2028
+ return s.relationshipState === import_sdk8.RelationshipStates.PENDING;
1974
2029
  case "relationship.active":
1975
- return s.relationshipState === import_sdk6.RelationshipStates.ACTIVE;
2030
+ return s.relationshipState === import_sdk8.RelationshipStates.ACTIVE;
1976
2031
  case "relationship.paused":
1977
- return s.relationshipState === import_sdk6.RelationshipStates.PAUSED;
2032
+ return s.relationshipState === import_sdk8.RelationshipStates.PAUSED;
1978
2033
  case "relationship.closed":
1979
- return s.relationshipState === import_sdk6.RelationshipStates.CLOSED;
2034
+ return s.relationshipState === import_sdk8.RelationshipStates.CLOSED;
1980
2035
  case "cycle.complete":
1981
2036
  return s.cycleComplete;
1982
2037
  case "cycle.released":
1983
- return s.latestDelegation?.state === import_sdk6.DelegationStates.COMPLETED;
2038
+ return s.latestDelegation?.state === import_sdk8.DelegationStates.COMPLETED;
1984
2039
  }
1985
2040
  }
1986
2041
  function parseWaitInterval(raw) {
@@ -2031,7 +2086,7 @@ async function composeStatus(api, signerDid, relationshipId, signer) {
2031
2086
  const relationship = relationships.find((r) => r.relationshipId === relationshipId);
2032
2087
  const counterpartyDid = relationship ? relationship.pairDidA === signerDid ? relationship.pairDidB : relationship.pairDidA : inferCounterpartyFromEntities(signerDid, allDelegations);
2033
2088
  const delegations = allDelegations;
2034
- const latestDelegation = pickLatestLive(delegations, [...import_sdk6.DELEGATION_ACTIVE_STATES]);
2089
+ const latestDelegation = pickLatestLive(delegations, [...import_sdk8.DELEGATION_ACTIVE_STATES]);
2035
2090
  const [workLogs, receipts] = await Promise.all([
2036
2091
  latestDelegation ? fetchAllPages(
2037
2092
  (after) => api.listWorkLogs(relationshipId, signer, { limit: 100, delegationId: latestDelegation.delegationId, ...after ? { after } : {} })
@@ -2095,8 +2150,8 @@ function findReceiptForWorkLog(receipts, workLog, allWorkLogs = [workLog]) {
2095
2150
  };
2096
2151
  const responseBody = workLog.responseOutput !== void 0 ? { type: "work_response", content: { delegation_id: workLog.delegationId, request_id: workLog.requestId, output: workLog.responseOutput } } : workLog.responseError !== void 0 ? { type: "work_response", content: { delegation_id: workLog.delegationId, request_id: workLog.requestId, error: workLog.responseError } } : null;
2097
2152
  if (!responseBody) return null;
2098
- const expectedRequestHash = (0, import_sdk6.canonicalSha256Hex)(requestBody);
2099
- const expectedResponseHash = (0, import_sdk6.canonicalSha256Hex)(responseBody);
2153
+ const expectedRequestHash = (0, import_sdk8.canonicalSha256Hex)(requestBody);
2154
+ const expectedResponseHash = (0, import_sdk8.canonicalSha256Hex)(responseBody);
2100
2155
  const matches = receipts.filter((r) => r.requestHash === expectedRequestHash && r.responseHash === expectedResponseHash);
2101
2156
  if (matches.length > 0) return pickLatest(matches);
2102
2157
  const respondedSiblings = allWorkLogs.filter((wl) => wl.delegationId === workLog.delegationId && (wl.responseOutput !== void 0 || wl.responseError !== void 0)).length;
@@ -2138,49 +2193,49 @@ function nextAction(input) {
2138
2193
  complete: false
2139
2194
  };
2140
2195
  }
2141
- if (relationship.state === import_sdk6.RelationshipStates.PENDING) {
2196
+ if (relationship.state === import_sdk8.RelationshipStates.PENDING) {
2142
2197
  return {
2143
2198
  hint: "Relationship is PENDING \u2014 one side owes `heyarp send-handshake-response <peer> --decision accept | decline`",
2144
2199
  owner: "either",
2145
2200
  complete: false
2146
2201
  };
2147
2202
  }
2148
- if (relationship.state === import_sdk6.RelationshipStates.PAUSED) {
2203
+ if (relationship.state === import_sdk8.RelationshipStates.PAUSED) {
2149
2204
  return { hint: "Relationship is PAUSED \u2014 owner must `heyarp unpause` before any envelopes flow", owner: "either", complete: false };
2150
2205
  }
2151
- if (relationship.state === import_sdk6.RelationshipStates.CLOSED) {
2206
+ if (relationship.state === import_sdk8.RelationshipStates.CLOSED) {
2152
2207
  return { hint: "Relationship is CLOSED \u2014 terminal state, no further action possible. Start a fresh handshake to reopen.", owner: "none", complete: false };
2153
2208
  }
2154
- if (!latestDelegation || latestDelegation.state === import_sdk6.DelegationStates.DECLINED || latestDelegation.state === import_sdk6.DelegationStates.CANCELED) {
2209
+ if (!latestDelegation || latestDelegation.state === import_sdk8.DelegationStates.DECLINED || latestDelegation.state === import_sdk8.DelegationStates.CANCELED) {
2155
2210
  return {
2156
2211
  hint: "No live delegation \u2014 buyer offers (terms only, no lock) `heyarp delegation offer <peer> --delegation-id <new-uuid> --title \u2026 --scope \u2026 --amount \u2026 --currency SOL:solana-devnet --deadline \u2026`, then funds the escrow lock AFTER the worker accepts via `heyarp delegation fund <del-id> --escrow-lock-from-file <path>`",
2157
2212
  owner: "either",
2158
2213
  complete: false
2159
2214
  };
2160
2215
  }
2161
- if (latestDelegation.state === import_sdk6.DelegationStates.DISPUTING) {
2216
+ if (latestDelegation.state === import_sdk8.DelegationStates.DISPUTING) {
2162
2217
  return {
2163
2218
  hint: `Delegation ${latestDelegation.delegationId} is DISPUTING \u2014 the buyer opened an on-chain dispute (their stake is escrowed too). The operator may rule until the dispute window lapses; after that either party closes with \`heyarp escrow dispute close ${latestDelegation.delegationId}\` (escrow returns to the buyer, both stakes return). Deadline: \`heyarp escrow show ${latestDelegation.delegationId}\`. No envelopes to send meanwhile.`,
2164
2219
  owner: "none",
2165
2220
  complete: false
2166
2221
  };
2167
2222
  }
2168
- if (latestDelegation.state === import_sdk6.DelegationStates.COMPLETED) {
2223
+ if (latestDelegation.state === import_sdk8.DelegationStates.COMPLETED) {
2169
2224
  return {
2170
2225
  hint: "Cycle COMPLETE \u2014 payment claimed on chain (lock paid; the receipt carries releaseStatus=paid)",
2171
2226
  owner: "none",
2172
2227
  complete: true
2173
2228
  };
2174
2229
  }
2175
- if (latestDelegation.state === import_sdk6.DelegationStates.FAILED || latestDelegation.state === import_sdk6.DelegationStates.REFUNDED || latestDelegation.state === import_sdk6.DelegationStates.DISPUTE_RESOLVED) {
2230
+ if (latestDelegation.state === import_sdk8.DelegationStates.FAILED || latestDelegation.state === import_sdk8.DelegationStates.REFUNDED || latestDelegation.state === import_sdk8.DelegationStates.DISPUTE_RESOLVED) {
2176
2231
  const stateLabel = latestDelegation.state.toUpperCase();
2177
- const reason = latestDelegation.state === import_sdk6.DelegationStates.FAILED ? "on-chain escrow lock failed to finalise (typical causes: insufficient payer funds, wrong program-id, ProgramState PDA uninitialised \u2014 check `heyarp delegations <rel-id> --json | jq .[].escrowError` for the worker-side reason)" : latestDelegation.state === import_sdk6.DelegationStates.REFUNDED ? (
2232
+ const reason = latestDelegation.state === import_sdk8.DelegationStates.FAILED ? "on-chain escrow lock failed to finalise (typical causes: insufficient payer funds, wrong program-id, ProgramState PDA uninitialised \u2014 check `heyarp delegations <rel-id> --json | jq .[].escrowError` for the worker-side reason)" : latestDelegation.state === import_sdk8.DelegationStates.REFUNDED ? (
2178
2233
  // Keyed on the DELEGATION row's releaseStatus, not the
2179
2234
  // receipt's: in the claim-expired path the worker never
2180
2235
  // submitted anything, so no receipt row exists to carry
2181
2236
  // the outcome — the delegation copy is always present
2182
2237
  // on indexer-driven terminals.
2183
- latestDelegation.releaseStatus === import_sdk6.LockStates.DISPUTE_CLOSED ? "the dispute window lapsed without an operator ruling and the dispute was closed \u2014 escrow returned to the buyer, both stakes returned (work was delivered but not paid)" : latestDelegation.releaseStatus === import_sdk6.LockStates.REVOKED ? "the work window lapsed without an on-chain submit \u2014 the buyer reclaimed the escrow AND the worker stake (claim_expired_work)" : "lock was refunded after expiry \u2014 no work was delivered against this delegation"
2238
+ latestDelegation.releaseStatus === import_sdk8.LockStates.DISPUTE_CLOSED ? "the dispute window lapsed without an operator ruling and the dispute was closed \u2014 escrow returned to the buyer, both stakes returned (work was delivered but not paid)" : latestDelegation.releaseStatus === import_sdk8.LockStates.REVOKED ? "the work window lapsed without an on-chain submit \u2014 the buyer reclaimed the escrow AND the worker stake (claim_expired_work)" : "lock was refunded after expiry \u2014 no work was delivered against this delegation"
2184
2239
  ) : "admin closed the delegation via the dispute-resolution path";
2185
2240
  return {
2186
2241
  hint: `Delegation ${latestDelegation.delegationId} is ${stateLabel} (terminal) \u2014 ${reason}. Issue a fresh \`heyarp delegation offer <peer> --delegation-id <new-uuid> \u2026\` to retry (FSM does not auto-retry).`,
@@ -2188,7 +2243,7 @@ function nextAction(input) {
2188
2243
  complete: false
2189
2244
  };
2190
2245
  }
2191
- if (latestDelegation.state === import_sdk6.DelegationStates.OFFERED) {
2246
+ if (latestDelegation.state === import_sdk8.DelegationStates.OFFERED) {
2192
2247
  const iAmOfferer = latestDelegation.offererDid === signerDid;
2193
2248
  const stateLabel = "OFFERED";
2194
2249
  return {
@@ -2197,7 +2252,7 @@ function nextAction(input) {
2197
2252
  complete: false
2198
2253
  };
2199
2254
  }
2200
- if (latestDelegation.state === import_sdk6.DelegationStates.ACCEPTED && !latestWorkLog) {
2255
+ if (latestDelegation.state === import_sdk8.DelegationStates.ACCEPTED && !latestWorkLog) {
2201
2256
  const iAmOfferer = latestDelegation.offererDid === signerDid;
2202
2257
  return {
2203
2258
  hint: iAmOfferer ? `Delegation ${latestDelegation.delegationId} is ACCEPTED \u2014 you (buyer) owe \`heyarp wallet create-lock --delegation-id ${latestDelegation.delegationId} --condition-hash <hex> ... > lock.json\` then \`heyarp delegation fund ${latestDelegation.delegationId} --escrow-lock-from-file lock.json\` (fund the escrow lock; work begins once it is LOCKED on chain)` : `Delegation ${latestDelegation.delegationId} is ACCEPTED \u2014 counterparty (the buyer) owes \`heyarp delegation fund\` to lock the escrow; wait for the delegation to reach LOCKED before working`,
@@ -2205,7 +2260,7 @@ function nextAction(input) {
2205
2260
  complete: false
2206
2261
  };
2207
2262
  }
2208
- if (latestDelegation.state === import_sdk6.DelegationStates.PENDING_LOCK_FINALIZATION && !latestWorkLog) {
2263
+ if (latestDelegation.state === import_sdk8.DelegationStates.PENDING_LOCK_FINALIZATION && !latestWorkLog) {
2209
2264
  return {
2210
2265
  hint: `Delegation ${latestDelegation.delegationId} is PENDING_LOCK_FINALIZATION \u2014 the escrow lock was funded and is awaiting on-chain confirmation; both sides wait (auto-advances to LOCKED). Poll with \`heyarp status ${relationship.relationshipId} --wait --until delegation.locked\`.`,
2211
2266
  owner: "none",
@@ -2220,7 +2275,7 @@ function nextAction(input) {
2220
2275
  complete: false
2221
2276
  };
2222
2277
  }
2223
- if (latestWorkLog.state === import_sdk6.WorkLogStates.REQUESTED) {
2278
+ if (latestWorkLog.state === import_sdk8.WorkLogStates.REQUESTED) {
2224
2279
  const iAmPayee = latestWorkLog.payeeDid === signerDid;
2225
2280
  return {
2226
2281
  hint: iAmPayee ? `work_request ${latestWorkLog.requestId} is REQUESTED \u2014 you owe \`heyarp work respond\` (output OR --error)` : `work_request ${latestWorkLog.requestId} is REQUESTED \u2014 counterparty (payee) owes \`heyarp work respond\``,
@@ -2272,349 +2327,84 @@ function formatStatusReport(s) {
2272
2327
  const lines = [];
2273
2328
  lines.push(cycleHeadline(s));
2274
2329
  lines.push("");
2275
- lines.push(import_chalk7.default.bold("Relationship"));
2330
+ lines.push(import_chalk8.default.bold("Relationship"));
2276
2331
  lines.push(` state: ${stateColor(s.relationshipState)}`);
2277
- if (s.counterpartyDid) lines.push(` counterparty: ${import_chalk7.default.cyan(s.counterpartyDid)}`);
2332
+ if (s.counterpartyDid) lines.push(` counterparty: ${import_chalk8.default.cyan(s.counterpartyDid)}`);
2278
2333
  lines.push("");
2279
- lines.push(import_chalk7.default.bold("Latest delegation"));
2334
+ lines.push(import_chalk8.default.bold("Latest delegation"));
2280
2335
  if (s.latestDelegation) {
2281
2336
  lines.push(` ${s.latestDelegation.delegationId} state=${stateColor(s.latestDelegation.state)}`);
2282
- lines.push(` offerer: ${import_chalk7.default.cyan(s.latestDelegation.offererDid)}`);
2337
+ lines.push(` offerer: ${import_chalk8.default.cyan(s.latestDelegation.offererDid)}`);
2283
2338
  if (s.latestDelegation.title) lines.push(` title: ${s.latestDelegation.title}`);
2284
2339
  if (s.latestDelegation.scopeSummary) lines.push(` scope: ${s.latestDelegation.scopeSummary}`);
2285
2340
  } else {
2286
- lines.push(import_chalk7.default.dim(" (none)"));
2341
+ lines.push(import_chalk8.default.dim(" (none)"));
2287
2342
  }
2288
2343
  lines.push("");
2289
- lines.push(import_chalk7.default.bold("Latest work_log"));
2344
+ lines.push(import_chalk8.default.bold("Latest work_log"));
2290
2345
  if (s.latestWorkLog) {
2291
2346
  lines.push(` request_id=${s.latestWorkLog.requestId} state=${stateColor(s.latestWorkLog.state)}`);
2292
2347
  } else {
2293
- lines.push(import_chalk7.default.dim(" (none)"));
2348
+ lines.push(import_chalk8.default.dim(" (none)"));
2294
2349
  }
2295
2350
  lines.push("");
2296
- lines.push(import_chalk7.default.bold("Latest receipt"));
2351
+ lines.push(import_chalk8.default.bold("Latest receipt"));
2297
2352
  if (s.latestReceipt) {
2298
2353
  lines.push(` ${stateColor("proposed")} verdict=${s.latestReceipt.verdictProposed}`);
2299
2354
  } else {
2300
- lines.push(import_chalk7.default.dim(" (none)"));
2355
+ lines.push(import_chalk8.default.dim(" (none)"));
2301
2356
  }
2302
2357
  lines.push("");
2303
- lines.push(import_chalk7.default.bold("Next action"));
2304
- const ownerLabel = s.nextActionOwner === "me" ? import_chalk7.default.green("me") : s.nextActionOwner === "counterparty" ? import_chalk7.default.yellow("counterparty") : s.nextActionOwner === "either" ? import_chalk7.default.cyan("either side") : import_chalk7.default.dim("\u2014");
2358
+ lines.push(import_chalk8.default.bold("Next action"));
2359
+ const ownerLabel = s.nextActionOwner === "me" ? import_chalk8.default.green("me") : s.nextActionOwner === "counterparty" ? import_chalk8.default.yellow("counterparty") : s.nextActionOwner === "either" ? import_chalk8.default.cyan("either side") : import_chalk8.default.dim("\u2014");
2305
2360
  lines.push(` whose turn: ${ownerLabel}`);
2306
2361
  lines.push(` hint: ${s.nextActionHint}`);
2307
- if (s.cycleComplete) lines.push(` ${import_chalk7.default.green("\u2713 Cycle complete.")}`);
2362
+ if (s.cycleComplete) lines.push(` ${import_chalk8.default.green("\u2713 Cycle complete.")}`);
2308
2363
  return lines.join("\n");
2309
2364
  }
2310
2365
  function cycleHeadline(s) {
2311
2366
  if (s.cycleComplete) {
2312
- return `${import_chalk7.default.bold("Cycle:")} ${import_chalk7.default.green.bold("COMPLETE")} ${import_chalk7.default.dim("\u2014 payment proven on chain")}`;
2367
+ return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.green.bold("COMPLETE")} ${import_chalk8.default.dim("\u2014 payment proven on chain")}`;
2313
2368
  }
2314
2369
  switch (s.relationshipState) {
2315
2370
  case "not_found":
2316
- return `${import_chalk7.default.bold("Cycle:")} ${import_chalk7.default.red.bold("NOT FOUND")} ${import_chalk7.default.dim("\u2014 relationship missing or signer is not a member")}`;
2371
+ return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.red.bold("NOT FOUND")} ${import_chalk8.default.dim("\u2014 relationship missing or signer is not a member")}`;
2317
2372
  case "unknown":
2318
- return `${import_chalk7.default.bold("Cycle:")} ${import_chalk7.default.yellow.bold("UNKNOWN")} ${import_chalk7.default.dim("\u2014 state probe inconclusive; hint below is advisory")}`;
2319
- case import_sdk6.RelationshipStates.CLOSED:
2320
- return `${import_chalk7.default.bold("Cycle:")} ${import_chalk7.default.red.bold("CLOSED")} ${import_chalk7.default.dim("\u2014 relationship terminal, no further protocol action")}`;
2321
- case import_sdk6.RelationshipStates.PAUSED:
2322
- return `${import_chalk7.default.bold("Cycle:")} ${import_chalk7.default.yellow.bold("PAUSED")} ${import_chalk7.default.dim("\u2014 relationship soft-disabled, resume to continue")}`;
2323
- case import_sdk6.RelationshipStates.PENDING:
2324
- return `${import_chalk7.default.bold("Cycle:")} ${import_chalk7.default.yellow.bold("PENDING")} ${import_chalk7.default.dim("\u2014 awaiting handshake_response")}`;
2325
- case import_sdk6.RelationshipStates.ACTIVE:
2373
+ return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.yellow.bold("UNKNOWN")} ${import_chalk8.default.dim("\u2014 state probe inconclusive; hint below is advisory")}`;
2374
+ case import_sdk8.RelationshipStates.CLOSED:
2375
+ return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.red.bold("CLOSED")} ${import_chalk8.default.dim("\u2014 relationship terminal, no further protocol action")}`;
2376
+ case import_sdk8.RelationshipStates.PAUSED:
2377
+ return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.yellow.bold("PAUSED")} ${import_chalk8.default.dim("\u2014 relationship soft-disabled, resume to continue")}`;
2378
+ case import_sdk8.RelationshipStates.PENDING:
2379
+ return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.yellow.bold("PENDING")} ${import_chalk8.default.dim("\u2014 awaiting handshake_response")}`;
2380
+ case import_sdk8.RelationshipStates.ACTIVE:
2326
2381
  default:
2327
- return `${import_chalk7.default.bold("Cycle:")} ${import_chalk7.default.cyan.bold("ACTIVE")} ${import_chalk7.default.dim('\u2014 work in progress; see "Next action" below')}`;
2382
+ return `${import_chalk8.default.bold("Cycle:")} ${import_chalk8.default.cyan.bold("ACTIVE")} ${import_chalk8.default.dim('\u2014 work in progress; see "Next action" below')}`;
2328
2383
  }
2329
2384
  }
2330
2385
  function stateColor(state) {
2331
- const c = state === "active" || state === "accepted" || state === "locked" || state === "responded" || state === "completed" ? import_chalk7.default.green : state === "pending" || state === "requested" || state === "offered" || state === "pending_lock_finalization" ? import_chalk7.default.yellow : state === "closed" || state === "declined" || state === "canceled" || state === "replaced" || state === "not_found" || // Terminal failure states deserve the same red
2386
+ const c = state === "active" || state === "accepted" || state === "locked" || state === "responded" || state === "completed" ? import_chalk8.default.green : state === "pending" || state === "requested" || state === "offered" || state === "pending_lock_finalization" ? import_chalk8.default.yellow : state === "closed" || state === "declined" || state === "canceled" || state === "replaced" || state === "not_found" || // Terminal failure states deserve the same red
2332
2387
  // treatment as declined/canceled so an operator
2333
2388
  // scanning `heyarp status` immediately sees
2334
2389
  // "this is dead, don't follow the hint blindly".
2335
- state === "failed" || state === "refunded" || state === "dispute_resolved" ? import_chalk7.default.red : import_chalk7.default.cyan;
2390
+ state === "failed" || state === "refunded" || state === "dispute_resolved" ? import_chalk8.default.red : import_chalk8.default.cyan;
2336
2391
  return c(state);
2337
2392
  }
2338
2393
 
2339
2394
  // src/commands/wallet.ts
2340
- var import_sdk9 = require("@heyanon-arp/sdk");
2395
+ var import_sdk11 = require("@heyanon-arp/sdk");
2341
2396
  var import_utils = require("@noble/hashes/utils");
2342
- var import_web32 = require("@solana/web3.js");
2397
+ var import_web3 = require("@solana/web3.js");
2343
2398
  init_api();
2344
2399
  init_config();
2345
2400
 
2346
2401
  // src/solana/escrow-ix.ts
2347
- var import_sdk7 = require("@heyanon-arp/sdk");
2348
- var import_web3 = require("@solana/web3.js");
2349
- var SPL_TOKEN_PROGRAM_ID = new import_web3.PublicKey(import_sdk7.SPL_TOKEN_PROGRAM_ID_BASE58);
2350
- var ASSOCIATED_TOKEN_PROGRAM_ID = new import_web3.PublicKey(import_sdk7.ASSOCIATED_TOKEN_PROGRAM_ID_BASE58);
2351
- var NATIVE_SOL_MINT = new import_web3.PublicKey(import_sdk7.NATIVE_SOL_MINT_BASE58);
2352
- function deriveLockPda(programId, lockId) {
2353
- return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk7.ESCROW_PDA_SEEDS.LOCK), Buffer.from(lockId)], programId)[0];
2354
- }
2355
- function deriveEscrowPda(programId, lockId) {
2356
- return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk7.ESCROW_PDA_SEEDS.ESCROW), Buffer.from(lockId)], programId)[0];
2357
- }
2358
- function deriveConfigPda(programId) {
2359
- return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk7.ESCROW_PDA_SEEDS.CONFIG)], programId)[0];
2360
- }
2361
- function deriveStakeVaultPda(programId) {
2362
- return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk7.ESCROW_PDA_SEEDS.STAKE_VAULT)], programId)[0];
2363
- }
2364
- function deriveCollateralConfigPda(programId, mint) {
2365
- return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk7.ESCROW_PDA_SEEDS.COLLATERAL), mint.toBuffer()], programId)[0];
2366
- }
2367
- function deriveDisputeResolutionPda(programId, lockId) {
2368
- return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk7.ESCROW_PDA_SEEDS.DISPUTE_RESOLUTION), Buffer.from(lockId)], programId)[0];
2369
- }
2370
- function deriveOperatorAuthPda(programId, operator) {
2371
- return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk7.ESCROW_PDA_SEEDS.OPERATOR_AUTH), operator.toBuffer()], programId)[0];
2372
- }
2373
- function deriveEventAuthorityPda(programId) {
2374
- return import_web3.PublicKey.findProgramAddressSync([Buffer.from(import_sdk7.ESCROW_PDA_SEEDS.EVENT_AUTHORITY)], programId)[0];
2375
- }
2376
- function deriveAta(owner, mint) {
2377
- return import_web3.PublicKey.findProgramAddressSync([owner.toBuffer(), SPL_TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
2378
- }
2379
- function eventCpiTail(programId) {
2380
- return [
2381
- { pubkey: deriveEventAuthorityPda(programId), isSigner: false, isWritable: false },
2382
- { pubkey: programId, isSigner: false, isWritable: false }
2383
- ];
2384
- }
2385
- function meta(pubkey, opts = {}) {
2386
- return { pubkey, isSigner: opts.signer === true, isWritable: opts.writable === true };
2387
- }
2388
- function noArgIx(programId, name, keys) {
2389
- return new import_web3.TransactionInstruction({ programId, keys, data: Buffer.from((0, import_sdk7.buildLifecycleIxData)(name)) });
2390
- }
2391
- function buildCreateLockIx(input) {
2392
- const { programId, lockId } = input;
2393
- const native = input.mint === null;
2394
- const data = Buffer.from((0, import_sdk7.buildCreateLockIxData)({ lockId, amount: input.amount, conditionHash: input.conditionHash }, { native }));
2395
- const head = [
2396
- meta(input.payer, { signer: true, writable: true }),
2397
- meta(input.payee),
2398
- meta(deriveConfigPda(programId)),
2399
- meta(deriveLockPda(programId, lockId), { writable: true }),
2400
- meta(deriveCollateralConfigPda(programId, input.mint ?? NATIVE_SOL_MINT))
2401
- ];
2402
- const keys = native ? [...head, meta(deriveEscrowPda(programId, lockId), { writable: true }), meta(import_web3.SystemProgram.programId), ...eventCpiTail(programId)] : [
2403
- ...head,
2404
- meta(input.mint),
2405
- meta(deriveAta(input.payer, input.mint), { writable: true }),
2406
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2407
- meta(import_web3.SystemProgram.programId),
2408
- meta(SPL_TOKEN_PROGRAM_ID),
2409
- ...eventCpiTail(programId)
2410
- ];
2411
- return new import_web3.TransactionInstruction({ programId, keys, data });
2412
- }
2413
- function buildAcceptLockIx(input) {
2414
- const { programId, lockId } = input;
2415
- return noArgIx(programId, "accept_lock", [
2416
- meta(input.payee, { signer: true, writable: true }),
2417
- meta(deriveConfigPda(programId)),
2418
- meta(deriveStakeVaultPda(programId), { writable: true }),
2419
- meta(deriveLockPda(programId, lockId), { writable: true }),
2420
- meta(import_web3.SystemProgram.programId),
2421
- ...eventCpiTail(programId)
2422
- ]);
2423
- }
2424
- function buildSubmitWorkIx(input) {
2425
- const { programId, lockId } = input;
2426
- return noArgIx(programId, "submit_work", [
2427
- meta(input.payee, { signer: true }),
2428
- meta(deriveConfigPda(programId)),
2429
- meta(deriveLockPda(programId, lockId), { writable: true }),
2430
- ...eventCpiTail(programId)
2431
- ]);
2432
- }
2433
- function buildClaimWorkPaymentIx(input) {
2434
- const { programId, lockId } = input;
2435
- if (input.mint === null) {
2436
- return noArgIx(programId, "claim_work_payment_native", [
2437
- meta(input.authority, { signer: true, writable: true }),
2438
- meta(deriveStakeVaultPda(programId), { writable: true }),
2439
- meta(deriveLockPda(programId, lockId), { writable: true }),
2440
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2441
- meta(input.payer, { writable: true }),
2442
- meta(input.payee, { writable: true }),
2443
- meta(input.feeRecipient, { writable: true }),
2444
- meta(import_web3.SystemProgram.programId),
2445
- ...eventCpiTail(programId)
2446
- ]);
2447
- }
2448
- return noArgIx(programId, "claim_work_payment", [
2449
- meta(input.authority, { signer: true, writable: true }),
2450
- meta(deriveConfigPda(programId)),
2451
- meta(deriveStakeVaultPda(programId), { writable: true }),
2452
- meta(deriveLockPda(programId, lockId), { writable: true }),
2453
- meta(input.mint),
2454
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2455
- meta(input.payer, { writable: true }),
2456
- meta(input.payee, { writable: true }),
2457
- meta(deriveAta(input.payee, input.mint), { writable: true }),
2458
- meta(input.feeRecipient),
2459
- meta(deriveAta(input.feeRecipient, input.mint), { writable: true }),
2460
- meta(import_web3.SystemProgram.programId),
2461
- meta(SPL_TOKEN_PROGRAM_ID),
2462
- meta(ASSOCIATED_TOKEN_PROGRAM_ID),
2463
- ...eventCpiTail(programId)
2464
- ]);
2465
- }
2466
- function buildCancelLockIx(input) {
2467
- const { programId, lockId } = input;
2468
- if (input.mint === null) {
2469
- return noArgIx(programId, "cancel_lock_native", [
2470
- meta(input.payer, { signer: true, writable: true }),
2471
- meta(deriveLockPda(programId, lockId), { writable: true }),
2472
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2473
- meta(import_web3.SystemProgram.programId),
2474
- ...eventCpiTail(programId)
2475
- ]);
2476
- }
2477
- return noArgIx(programId, "cancel_lock", [
2478
- meta(input.payer, { signer: true, writable: true }),
2479
- meta(deriveConfigPda(programId)),
2480
- meta(deriveLockPda(programId, lockId), { writable: true }),
2481
- meta(input.mint),
2482
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2483
- meta(deriveAta(input.payer, input.mint), { writable: true }),
2484
- meta(import_web3.SystemProgram.programId),
2485
- meta(SPL_TOKEN_PROGRAM_ID),
2486
- meta(ASSOCIATED_TOKEN_PROGRAM_ID),
2487
- ...eventCpiTail(programId)
2488
- ]);
2489
- }
2490
- function buildClaimExpiredWorkIx(input) {
2491
- const { programId, lockId } = input;
2492
- if (input.mint === null) {
2493
- return noArgIx(programId, "claim_expired_work_native", [
2494
- meta(input.payer, { signer: true, writable: true }),
2495
- meta(deriveStakeVaultPda(programId), { writable: true }),
2496
- meta(deriveLockPda(programId, lockId), { writable: true }),
2497
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2498
- meta(import_web3.SystemProgram.programId),
2499
- ...eventCpiTail(programId)
2500
- ]);
2501
- }
2502
- return noArgIx(programId, "claim_expired_work", [
2503
- meta(input.payer, { signer: true, writable: true }),
2504
- meta(deriveConfigPda(programId)),
2505
- meta(deriveStakeVaultPda(programId), { writable: true }),
2506
- meta(deriveLockPda(programId, lockId), { writable: true }),
2507
- meta(input.mint),
2508
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2509
- meta(deriveAta(input.payer, input.mint), { writable: true }),
2510
- meta(import_web3.SystemProgram.programId),
2511
- meta(SPL_TOKEN_PROGRAM_ID),
2512
- meta(ASSOCIATED_TOKEN_PROGRAM_ID),
2513
- ...eventCpiTail(programId)
2514
- ]);
2515
- }
2516
- function buildOpenDisputeIx(input) {
2517
- const { programId, lockId } = input;
2518
- return noArgIx(programId, "open_dispute", [
2519
- meta(input.payer, { signer: true, writable: true }),
2520
- meta(deriveConfigPda(programId)),
2521
- meta(deriveStakeVaultPda(programId), { writable: true }),
2522
- meta(deriveLockPda(programId, lockId), { writable: true }),
2523
- meta(import_web3.SystemProgram.programId),
2524
- ...eventCpiTail(programId)
2525
- ]);
2526
- }
2527
- function buildResolveDisputeIx(input) {
2528
- const { programId, lockId } = input;
2529
- const native = input.mint === null;
2530
- const data = Buffer.from((0, import_sdk7.buildResolveDisputeIxData)(input.args, { native }));
2531
- if (native) {
2532
- return new import_web3.TransactionInstruction({
2533
- programId,
2534
- data,
2535
- keys: [
2536
- meta(input.operator, { signer: true, writable: true }),
2537
- meta(deriveOperatorAuthPda(programId, input.operator)),
2538
- meta(deriveStakeVaultPda(programId), { writable: true }),
2539
- meta(deriveLockPda(programId, lockId), { writable: true }),
2540
- meta(deriveDisputeResolutionPda(programId, lockId), { writable: true }),
2541
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2542
- meta(input.payer, { writable: true }),
2543
- meta(input.winner, { writable: true }),
2544
- meta(input.feeRecipient, { writable: true }),
2545
- meta(input.treasury, { writable: true }),
2546
- meta(import_web3.SystemProgram.programId),
2547
- ...eventCpiTail(programId)
2548
- ]
2549
- });
2550
- }
2551
- return new import_web3.TransactionInstruction({
2552
- programId,
2553
- data,
2554
- keys: [
2555
- meta(input.operator, { signer: true, writable: true }),
2556
- meta(deriveOperatorAuthPda(programId, input.operator)),
2557
- meta(deriveConfigPda(programId)),
2558
- meta(deriveStakeVaultPda(programId), { writable: true }),
2559
- meta(deriveLockPda(programId, lockId), { writable: true }),
2560
- meta(deriveDisputeResolutionPda(programId, lockId), { writable: true }),
2561
- meta(input.mint),
2562
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2563
- meta(input.payer, { writable: true }),
2564
- meta(input.winner, { writable: true }),
2565
- meta(deriveAta(input.winner, input.mint), { writable: true }),
2566
- meta(input.feeRecipient),
2567
- meta(deriveAta(input.feeRecipient, input.mint), { writable: true }),
2568
- meta(input.treasury, { writable: true }),
2569
- meta(import_web3.SystemProgram.programId),
2570
- meta(SPL_TOKEN_PROGRAM_ID),
2571
- meta(ASSOCIATED_TOKEN_PROGRAM_ID),
2572
- ...eventCpiTail(programId)
2573
- ]
2574
- });
2575
- }
2576
- function buildCloseDisputeIx(input) {
2577
- const { programId, lockId } = input;
2578
- if (input.mint === null) {
2579
- return noArgIx(programId, "close_dispute_native", [
2580
- meta(input.authority, { signer: true, writable: true }),
2581
- meta(deriveStakeVaultPda(programId), { writable: true }),
2582
- meta(deriveLockPda(programId, lockId), { writable: true }),
2583
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2584
- meta(input.payer, { writable: true }),
2585
- meta(input.payee, { writable: true }),
2586
- meta(import_web3.SystemProgram.programId),
2587
- ...eventCpiTail(programId)
2588
- ]);
2589
- }
2590
- return noArgIx(programId, "close_dispute", [
2591
- meta(input.authority, { signer: true, writable: true }),
2592
- meta(deriveConfigPda(programId)),
2593
- meta(deriveStakeVaultPda(programId), { writable: true }),
2594
- meta(deriveLockPda(programId, lockId), { writable: true }),
2595
- meta(input.mint),
2596
- meta(deriveEscrowPda(programId, lockId), { writable: true }),
2597
- meta(input.payer, { writable: true }),
2598
- meta(deriveAta(input.payer, input.mint), { writable: true }),
2599
- meta(input.payee, { writable: true }),
2600
- meta(import_web3.SystemProgram.programId),
2601
- meta(SPL_TOKEN_PROGRAM_ID),
2602
- meta(ASSOCIATED_TOKEN_PROGRAM_ID),
2603
- ...eventCpiTail(programId)
2604
- ]);
2605
- }
2606
- async function fetchLockAccount(conn, programId, delegationId) {
2607
- const lockId = (0, import_sdk7.deriveLockId)(delegationId);
2608
- const lockPda = deriveLockPda(programId, lockId);
2609
- const info = await conn.getAccountInfo(lockPda);
2610
- if (!info) return null;
2611
- return { lockId, lockPda, lock: (0, import_sdk7.decodeLockAccount)(Uint8Array.from(info.data)) };
2612
- }
2402
+ var import_sdk9 = require("@heyanon-arp/sdk");
2613
2403
 
2614
2404
  // src/commands/token-amount.ts
2615
- var import_sdk8 = require("@heyanon-arp/sdk");
2405
+ var import_sdk10 = require("@heyanon-arp/sdk");
2616
2406
  function toBaseUnits(amountDecimal, decimals) {
2617
- if (!(0, import_sdk8.isDecimalAmountString)(amountDecimal)) {
2407
+ if (!(0, import_sdk10.isDecimalAmountString)(amountDecimal)) {
2618
2408
  throw new Error(`amount '${amountDecimal}' is not a non-negative decimal number`);
2619
2409
  }
2620
2410
  if (!Number.isInteger(decimals) || decimals < 0 || decimals > 255) {
@@ -2643,8 +2433,8 @@ function normaliseDelegationId(raw) {
2643
2433
  }
2644
2434
  throw new Error(`wallet: --delegation-id must be either 'del_<uuid>' or a bare canonical-lowercase UUID (got '${raw}')`);
2645
2435
  }
2646
- var SPL_TOKEN_PROGRAM_ID2 = new import_web32.PublicKey(import_sdk9.SPL_TOKEN_PROGRAM_ID_BASE58);
2647
- var ASSOCIATED_TOKEN_PROGRAM_ID2 = new import_web32.PublicKey(import_sdk9.ASSOCIATED_TOKEN_PROGRAM_ID_BASE58);
2436
+ var SPL_TOKEN_PROGRAM_ID2 = new import_web3.PublicKey(import_sdk11.SPL_TOKEN_PROGRAM_ID_BASE58);
2437
+ var ASSOCIATED_TOKEN_PROGRAM_ID2 = new import_web3.PublicKey(import_sdk11.ASSOCIATED_TOKEN_PROGRAM_ID_BASE58);
2648
2438
  var FALLBACK_RPC_URL = "https://api.mainnet-beta.solana.com";
2649
2439
  function resolveRpcUrl(opts) {
2650
2440
  if (opts.rpcUrl !== void 0 && opts.rpcUrl !== "") return opts.rpcUrl;
@@ -2664,7 +2454,7 @@ function redactRpcUrl(url) {
2664
2454
  return "<redacted>";
2665
2455
  }
2666
2456
  }
2667
- var FALLBACK_PROGRAM_ID = import_sdk9.ESCROW_PROGRAM_ID_BASE58;
2457
+ var FALLBACK_PROGRAM_ID = import_sdk11.ESCROW_PROGRAM_ID_BASE58;
2668
2458
  async function resolveProgramIdWithSource(api, opts) {
2669
2459
  if (opts.programId !== void 0 && opts.programId !== "") {
2670
2460
  return { programId: opts.programId, source: "flag" };
@@ -2747,14 +2537,14 @@ function registerDerivePdas(cmd) {
2747
2537
  async function derivePdasHandler(opts) {
2748
2538
  const normalisedDelegationId = normaliseDelegationId(opts.delegationId);
2749
2539
  const api = new ArpApiClient(opts.server);
2750
- const programId = new import_web32.PublicKey(await resolveProgramIdStrict(api, opts, "wallet derive-pdas"));
2751
- const lockIdBytes = (0, import_sdk9.deriveLockId)(normalisedDelegationId);
2540
+ const programId = new import_web3.PublicKey(await resolveProgramIdStrict(api, opts, "wallet derive-pdas"));
2541
+ const lockIdBytes = (0, import_sdk11.deriveLockId)(normalisedDelegationId);
2752
2542
  const lockIdSeed = Buffer.from(lockIdBytes);
2753
2543
  const lockIdHex = Buffer.from(lockIdBytes).toString("hex");
2754
- const [lockPda] = import_web32.PublicKey.findProgramAddressSync([Buffer.from("lock"), lockIdSeed], programId);
2755
- const [escrowPda] = import_web32.PublicKey.findProgramAddressSync([Buffer.from("escrow"), lockIdSeed], programId);
2756
- const [configPda] = import_web32.PublicKey.findProgramAddressSync([Buffer.from("config")], programId);
2757
- const [eventAuthorityPda] = import_web32.PublicKey.findProgramAddressSync([Buffer.from("__event_authority")], programId);
2544
+ const [lockPda] = import_web3.PublicKey.findProgramAddressSync([Buffer.from("lock"), lockIdSeed], programId);
2545
+ const [escrowPda] = import_web3.PublicKey.findProgramAddressSync([Buffer.from("escrow"), lockIdSeed], programId);
2546
+ const [configPda] = import_web3.PublicKey.findProgramAddressSync([Buffer.from("config")], programId);
2547
+ const [eventAuthorityPda] = import_web3.PublicKey.findProgramAddressSync([Buffer.from("__event_authority")], programId);
2758
2548
  return {
2759
2549
  delegation_id: normalisedDelegationId,
2760
2550
  lock_id_hex: lockIdHex,
@@ -2767,11 +2557,11 @@ async function derivePdasHandler(opts) {
2767
2557
  };
2768
2558
  }
2769
2559
  var TERMINAL_METHOD = {
2770
- [import_sdk9.LockStates.PAID]: "claim_work_payment",
2771
- [import_sdk9.LockStates.CANCELED]: "cancel_lock",
2772
- [import_sdk9.LockStates.REVOKED]: "claim_expired_work",
2773
- [import_sdk9.LockStates.DISPUTE_RESOLVED]: "resolve_dispute",
2774
- [import_sdk9.LockStates.DISPUTE_CLOSED]: "close_dispute"
2560
+ [import_sdk11.LockStates.PAID]: "claim_work_payment",
2561
+ [import_sdk11.LockStates.CANCELED]: "cancel_lock",
2562
+ [import_sdk11.LockStates.REVOKED]: "claim_expired_work",
2563
+ [import_sdk11.LockStates.DISPUTE_RESOLVED]: "resolve_dispute",
2564
+ [import_sdk11.LockStates.DISPUTE_CLOSED]: "close_dispute"
2775
2565
  };
2776
2566
  function registerVerifyRelease(cmd) {
2777
2567
  cmd.command("verify-release").description(
@@ -2782,7 +2572,7 @@ function registerVerifyRelease(cmd) {
2782
2572
  ).option(
2783
2573
  "--program-id <pubkey>",
2784
2574
  "Deployed ARP escrow program id. STRICT: flag > ARP_ESCROW_PROGRAM_ID env > GET /v1/escrow/config > FAIL \u2014 a wrong-program read would silently report lock_never_created."
2785
- ).option("--from-did <did>", "Accepted for scripting symmetry with the signing commands; verify-release reads on-chain state only and needs no signer, so this is ignored.").option("--json", "Emit JSON instead of human text. jq-pipeable.", false).action(async (opts) => {
2575
+ ).option("--from-did <did>", "Accepted for scripting symmetry with the signing commands; verify-release reads on-chain state only and needs no signer, so this is ignored.").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option("--json", "Emit JSON instead of human text. jq-pipeable.", false).action(async (opts) => {
2786
2576
  try {
2787
2577
  const out = await verifyReleaseHandler(opts);
2788
2578
  if (opts.json) {
@@ -2813,13 +2603,13 @@ function registerVerifyRelease(cmd) {
2813
2603
  async function verifyReleaseHandler(opts) {
2814
2604
  const normalisedDelegationId = normaliseDelegationId(opts.delegationId);
2815
2605
  const api = new ArpApiClient(opts.server);
2816
- const programId = new import_web32.PublicKey(await resolveProgramIdStrict(api, opts));
2606
+ const programId = new import_web3.PublicKey(await resolveProgramIdStrict(api, opts));
2817
2607
  const rpcUrl = resolveRpcUrlStrict(opts);
2818
- const conn = new import_web32.Connection(rpcUrl, "confirmed");
2819
- const fetched = await fetchLockAccount(conn, programId, normalisedDelegationId);
2820
- const lockId = (0, import_sdk9.deriveLockId)(normalisedDelegationId);
2821
- const lockPda = deriveLockPda(programId, lockId);
2822
- const escrowPda = deriveEscrowPda(programId, lockId);
2608
+ const conn = new import_web3.Connection(rpcUrl, "confirmed");
2609
+ const fetched = await (0, import_sdk9.fetchLockAccount)(conn, programId, normalisedDelegationId);
2610
+ const lockId = (0, import_sdk11.deriveLockId)(normalisedDelegationId);
2611
+ const lockPda = (0, import_sdk9.deriveLockPda)(programId, lockId);
2612
+ const escrowPda = (0, import_sdk9.deriveEscrowPda)(programId, lockId);
2823
2613
  if (!fetched) {
2824
2614
  return {
2825
2615
  delegation_id: normalisedDelegationId,
@@ -2838,7 +2628,7 @@ async function verifyReleaseHandler(opts) {
2838
2628
  lock_pda: lockPda.toBase58(),
2839
2629
  escrow_pda: escrowPda.toBase58(),
2840
2630
  lock_account_exists: true,
2841
- released: status === import_sdk9.LockStates.PAID,
2631
+ released: status === import_sdk11.LockStates.PAID,
2842
2632
  status,
2843
2633
  ...TERMINAL_METHOD[status] !== void 0 ? { release_method: TERMINAL_METHOD[status] } : {},
2844
2634
  lock_state: lock.stateByte,
@@ -2848,23 +2638,23 @@ async function verifyReleaseHandler(opts) {
2848
2638
  }
2849
2639
  function renderStatusLine(status) {
2850
2640
  switch (status) {
2851
- case import_sdk9.LockStates.PAID:
2641
+ case import_sdk11.LockStates.PAID:
2852
2642
  return "\u2713 paid \u2014 claim_work_payment landed (buyer approval or post-review self-claim); the payee was paid net of any protocol fee";
2853
- case import_sdk9.LockStates.CREATED:
2643
+ case import_sdk11.LockStates.CREATED:
2854
2644
  return "\u2717 created \u2014 funded, awaiting the worker accept_lock (stake) \u2014 or a buyer cancel";
2855
- case import_sdk9.LockStates.IN_PROGRESS:
2645
+ case import_sdk11.LockStates.IN_PROGRESS:
2856
2646
  return "\u2717 in_progress \u2014 worker accepted + staked; work window running";
2857
- case import_sdk9.LockStates.SUBMITTED:
2647
+ case import_sdk11.LockStates.SUBMITTED:
2858
2648
  return "\u2717 submitted \u2014 work delivered on-chain; review window running (buyer claims to approve, disputes to refuse; worker self-claims after expiry)";
2859
- case import_sdk9.LockStates.DISPUTING:
2649
+ case import_sdk11.LockStates.DISPUTING:
2860
2650
  return "\u2717 disputing \u2014 buyer disputed; operator has the dispute window to rule, after that either party can close";
2861
- case import_sdk9.LockStates.CANCELED:
2651
+ case import_sdk11.LockStates.CANCELED:
2862
2652
  return "\u2717 canceled \u2014 buyer canceled pre-accept; escrow returned";
2863
- case import_sdk9.LockStates.REVOKED:
2653
+ case import_sdk11.LockStates.REVOKED:
2864
2654
  return "\u2717 revoked \u2014 work window lapsed unsubmitted; buyer reclaimed the escrow + the worker stake";
2865
- case import_sdk9.LockStates.DISPUTE_RESOLVED:
2655
+ case import_sdk11.LockStates.DISPUTE_RESOLVED:
2866
2656
  return "\u2717 dispute_resolved \u2014 operator ruled; winner took the escrow per the on-chain split";
2867
- case import_sdk9.LockStates.DISPUTE_CLOSED:
2657
+ case import_sdk11.LockStates.DISPUTE_CLOSED:
2868
2658
  return "\u2717 dispute_closed \u2014 dispute window lapsed unresolved; escrow returned to the buyer, stakes returned";
2869
2659
  case "lock_never_created":
2870
2660
  return "\u2717 lock_never_created \u2014 no Lock PDA on this cluster/program; create_lock never fired (or wrong --rpc-url/--program-id)";
@@ -2873,7 +2663,7 @@ function renderStatusLine(status) {
2873
2663
  function registerCreateLock(cmd) {
2874
2664
  cmd.command("create-lock").description(
2875
2665
  "Build + sign a create_lock Solana tx (native SOL or an SPL token); output JSON ready for attachments.escrow_lock. This command does NOT submit the tx to chain \u2014 it only signs the blob locally. Run this AFTER the worker accepts your offer; the actual on-chain submission happens inside `heyarp delegation fund <delegation-id> --escrow-lock-from-file <path>` (the server's escrow worker picks up the signed blob from the fund envelope's attachments and posts it). Watch for the `lock_id` appearing on-chain only AFTER `delegation fund` runs, not after this command."
2876
- ).option("--server <url>", "Override server URL for sender-key resolution").option("--from-did <did>", "Sender DID (= payer of the lock). Required when more than one agent on the host.").requiredOption("--delegation-id <id>", "Delegation UUID (drives the lock_id derivation)").requiredOption("--recipient-pubkey <base58>", "Payee Solana pubkey (recipient agent's settlement_pubkey)").option("--amount-lamports <int>", "NATIVE SOL: lock amount in lamports (1 SOL = 1_000_000_000). Required when --mint-pubkey is omitted; not allowed with it.").option("--mint-pubkey <base58>", "SPL token mint to lock. Omit for native SOL. Must be a legacy SPL Token mint (Token-2022 is not supported).").option("--amount-base-units <int>", "SPL: lock amount in the mint's base units (e.g. 1000000 = 1 USDC at 6 decimals). Canonical SPL amount input.").option(
2666
+ ).option("--server <url>", "Override server URL for sender-key resolution").option("--from-did <did>", "Sender DID (= payer of the lock). Required when more than one agent on the host.").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").requiredOption("--delegation-id <id>", "Delegation UUID (drives the lock_id derivation)").requiredOption("--recipient-pubkey <base58>", "Payee Solana pubkey (recipient agent's settlement_pubkey)").option("--amount-lamports <int>", "NATIVE SOL: lock amount in lamports (1 SOL = 1_000_000_000). Required when --mint-pubkey is omitted; not allowed with it.").option("--mint-pubkey <base58>", "SPL token mint to lock. Omit for native SOL. Must be a legacy SPL Token mint (Token-2022 is not supported).").option("--amount-base-units <int>", "SPL: lock amount in the mint's base units (e.g. 1000000 = 1 USDC at 6 decimals). Canonical SPL amount input.").option(
2877
2667
  "--amount <decimal>",
2878
2668
  "SPL: lock amount as a human decimal (e.g. 1.5); converted using the mint's on-chain decimals. Convenience alternative to --amount-base-units."
2879
2669
  ).requiredOption("--condition-hash <hex>", "32-byte hex condition_hash from `heyarp escrow derive-condition-hash` (binds the delegation terms)").option(
@@ -3007,7 +2797,7 @@ async function resolveCreateLockAsset(conn, opts, payer, clusterCaip2) {
3007
2797
  if (amount === 0n) {
3008
2798
  throw new Error("wallet create-lock: lock amount must be greater than zero.");
3009
2799
  }
3010
- const [payerAta] = import_web32.PublicKey.findProgramAddressSync([payer.toBuffer(), SPL_TOKEN_PROGRAM_ID2.toBuffer(), mint.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID2);
2800
+ const [payerAta] = import_web3.PublicKey.findProgramAddressSync([payer.toBuffer(), SPL_TOKEN_PROGRAM_ID2.toBuffer(), mint.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID2);
3011
2801
  const ataInfo = await conn.getAccountInfo(payerAta);
3012
2802
  if (!ataInfo) {
3013
2803
  throw new Error(
@@ -3017,8 +2807,8 @@ async function resolveCreateLockAsset(conn, opts, payer, clusterCaip2) {
3017
2807
  if (ataInfo.data.length < 72) {
3018
2808
  throw new Error(`wallet create-lock: payer token account ${payerAta.toBase58()} is malformed (data length ${ataInfo.data.length} < 72).`);
3019
2809
  }
3020
- const ataMint = new import_web32.PublicKey(ataInfo.data.subarray(0, 32));
3021
- const ataOwner = new import_web32.PublicKey(ataInfo.data.subarray(32, 64));
2810
+ const ataMint = new import_web3.PublicKey(ataInfo.data.subarray(0, 32));
2811
+ const ataOwner = new import_web3.PublicKey(ataInfo.data.subarray(32, 64));
3022
2812
  if (!ataMint.equals(mint)) {
3023
2813
  throw new Error(`wallet create-lock: payer token account ${payerAta.toBase58()} is for mint ${ataMint.toBase58()}, not ${mint.toBase58()}.`);
3024
2814
  }
@@ -3039,7 +2829,7 @@ async function resolveCreateLockAsset(conn, opts, payer, clusterCaip2) {
3039
2829
  };
3040
2830
  }
3041
2831
  async function createLockHandler(opts) {
3042
- const agent = resolveSenderAgent("wallet create-lock", opts.server, opts.fromDid);
2832
+ const agent = resolveSenderAgent("wallet create-lock", opts.server, opts.fromDid, opts.from);
3043
2833
  const payerKp = keypairFromAgent(agent);
3044
2834
  const normalisedDelegationId = normaliseDelegationId(opts.delegationId);
3045
2835
  const payee = parsePubkey(opts.recipientPubkey, "--recipient-pubkey");
@@ -3050,18 +2840,18 @@ async function createLockHandler(opts) {
3050
2840
  if (clusterTag !== 0 && clusterTag !== 1) {
3051
2841
  throw new Error(`--cluster-tag must be 0 (devnet) or 1 (mainnet) (got ${clusterTag})`);
3052
2842
  }
3053
- const clusterCaip2 = clusterTag === 1 ? import_sdk9.SOLANA_CLUSTER_IDS["solana-mainnet"] : import_sdk9.SOLANA_CLUSTER_IDS["solana-devnet"];
2843
+ const clusterCaip2 = clusterTag === 1 ? import_sdk11.SOLANA_CLUSTER_IDS["solana-mainnet"] : import_sdk11.SOLANA_CLUSTER_IDS["solana-devnet"];
3054
2844
  const expectedLockAsset = typeof opts.mintPubkey === "string" && opts.mintPubkey !== "" ? { kind: "spl", mint: parsePubkey(opts.mintPubkey, "--mint-pubkey").toBase58(), cluster: clusterCaip2 } : { kind: "native" };
3055
2845
  if (!offlineMode) {
3056
2846
  await preflightLockCurrency(api, agent, normalisedDelegationId, expectedLockAsset);
3057
2847
  }
3058
- const programId = new import_web32.PublicKey(await resolveProgramId(api, opts));
2848
+ const programId = new import_web3.PublicKey(await resolveProgramId(api, opts));
3059
2849
  const rpcUrl = resolveRpcUrl(opts);
3060
- const conn = new import_web32.Connection(rpcUrl, "confirmed");
2850
+ const conn = new import_web3.Connection(rpcUrl, "confirmed");
3061
2851
  const asset = await resolveCreateLockAsset(conn, opts, payerKp.publicKey, clusterCaip2);
3062
2852
  const amount = asset.amount;
3063
- const lockIdBytes = (0, import_sdk9.deriveLockId)(normalisedDelegationId);
3064
- const ix = buildCreateLockIx({
2853
+ const lockIdBytes = (0, import_sdk11.deriveLockId)(normalisedDelegationId);
2854
+ const ix = (0, import_sdk9.buildCreateLockIx)({
3065
2855
  programId,
3066
2856
  lockId: lockIdBytes,
3067
2857
  payer: payerKp.publicKey,
@@ -3070,11 +2860,14 @@ async function createLockHandler(opts) {
3070
2860
  conditionHash,
3071
2861
  mint: asset.kind === "spl" ? asset.mint : null
3072
2862
  });
3073
- const tx = new import_web32.Transaction().add(ix);
2863
+ const tx = new import_web3.Transaction().add(ix);
3074
2864
  tx.feePayer = payerKp.publicKey;
3075
- const { blockhash } = await conn.getLatestBlockhash("confirmed");
2865
+ const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash("confirmed");
3076
2866
  tx.recentBlockhash = blockhash;
3077
2867
  tx.sign(payerKp);
2868
+ process.stderr.write(
2869
+ "\u26A0 create-lock: this signed blob is valid for only ~60-90s \u2014 run `heyarp delegation fund` NOW. If you wait, the create_lock tx is silently dropped on-chain and the delegation fails; re-run create-lock to retry.\n"
2870
+ );
3078
2871
  const blob = tx.serialize({ requireAllSignatures: true, verifySignatures: true });
3079
2872
  return {
3080
2873
  signed_tx_blob: blob.toString("base64"),
@@ -3097,22 +2890,26 @@ async function createLockHandler(opts) {
3097
2890
  // Record the program id the create_lock ix was built against.
3098
2891
  // `delegation offer` cross-checks this pre-flight so a stale
3099
2892
  // ESCRoW... fallback lock doesn't ship silently.
3100
- program_id: programId.toBase58()
2893
+ program_id: programId.toBase58(),
2894
+ // Blockhash + its expiry slot — the ~60-90s submission window for
2895
+ // this blob (see CreateLockOutput docs).
2896
+ blockhash,
2897
+ last_valid_block_height: lastValidBlockHeight
3101
2898
  };
3102
2899
  }
3103
2900
  function keypairFromAgent(agent) {
3104
2901
  const stored = base64ToBytes(agent.settlementSecretKeyB64);
3105
2902
  if (stored.length === 32) {
3106
- return import_web32.Keypair.fromSeed(stored);
2903
+ return import_web3.Keypair.fromSeed(stored);
3107
2904
  }
3108
2905
  if (stored.length === 64) {
3109
- return import_web32.Keypair.fromSecretKey(stored);
2906
+ return import_web3.Keypair.fromSecretKey(stored);
3110
2907
  }
3111
2908
  throw new Error(`agent ${agent.did}: settlementSecretKeyB64 must decode to 32 bytes (Ed25519 seed) or 64 bytes (Solana expanded form); got ${stored.length}`);
3112
2909
  }
3113
2910
  function parsePubkey(value, flag) {
3114
2911
  try {
3115
- return new import_web32.PublicKey(value);
2912
+ return new import_web3.PublicKey(value);
3116
2913
  } catch (err) {
3117
2914
  throw new Error(`${flag}: invalid base58 pubkey '${value}': ${err.message}`);
3118
2915
  }
@@ -3145,7 +2942,7 @@ function registerDelegationCommands(root) {
3145
2942
  registerCancel(cmd);
3146
2943
  }
3147
2944
  function registerOffer(parent) {
3148
- parent.command("offer").description("Open a new delegation addressed to <recipient-did> with the agreed terms INLINE (no escrow lock \u2014 fund AFTER acceptance via `delegation fund`).").argument("<recipient-did>", "Recipient agent DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--delegation-id <uuid>", "Override the auto-generated delegation id (UUID). Reuse the SAME id at `heyarp delegation fund` time. Useful for replay / scripting.").option("--title <s>", "Required: human-readable title for the offer").option("--brief <json>", "Optional structured brief (JSON object)").option("--criterion <s>", "acceptance_criteria \u2014 repeatable; pass --criterion once per bullet", collectRepeated, []).option("--deadline <rfc3339>", 'Optional RFC 3339 deadline (e.g. "2026-12-31T23:59:59Z")').option("--scope <text>", "scope_summary \u2014 short prose describing the agreed work. Required.").option("--amount <s>", 'Optional decimal-as-string amount (e.g. "10.00"). REQUIRES --currency if set.').option("--currency <s>", `Asset identifier: shorthand (${import_sdk10.WELL_KNOWN_ASSET_KEYS.join("|")}) OR raw CAIP-19 string.`).option("--currency-decimals <n>", "Decimal places for base-unit conversion (0-18). Required only when --currency is raw CAIP-19.").option("--currency-symbol <s>", 'Optional UI hint ("USDC", "SOL"). Max 16 chars.').option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk10.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(
2945
+ parent.command("offer").description("Open a new delegation addressed to <recipient-did> with the agreed terms INLINE (no escrow lock \u2014 fund AFTER acceptance via `delegation fund`).").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--delegation-id <uuid>", "Override the auto-generated delegation id (UUID). Reuse the SAME id at `heyarp delegation fund` time. Useful for replay / scripting.").option("--title <s>", "Required: human-readable title for the offer").option("--brief <json>", "Optional structured brief (JSON object)").option("--criterion <s>", "acceptance_criteria \u2014 repeatable; pass --criterion once per bullet", collectRepeated, []).option("--deadline <rfc3339>", 'Optional RFC 3339 deadline (e.g. "2026-12-31T23:59:59Z")').option("--scope <text>", "scope_summary \u2014 short prose describing the agreed work. Required.").option("--amount <s>", 'Optional decimal-as-string amount (e.g. "10.00"). REQUIRES --currency if set.').option("--currency <s>", `Asset identifier: shorthand (${import_sdk12.WELL_KNOWN_ASSET_KEYS.join("|")}) OR raw CAIP-19 string.`).option("--currency-decimals <n>", "Decimal places for base-unit conversion (0-18). Required only when --currency is raw CAIP-19.").option("--currency-symbol <s>", 'Optional UI hint ("USDC", "SOL"). Max 16 chars.').option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk12.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(
3149
2946
  "--json",
3150
2947
  'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"offer", delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude + the "reference this delegation" hints move to stderr; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
3151
2948
  false
@@ -3260,16 +3057,16 @@ async function runOffer(recipientDid, opts) {
3260
3057
  "delegation offer: --verbose and --json are mutually exclusive. --json emits the structured server response; --verbose adds dumps that would break `--json | jq`."
3261
3058
  );
3262
3059
  }
3263
- requireDid("delegation offer", recipientDid, "<recipient-did>");
3060
+ recipientDid = await resolveRecipient(opts.server, "delegation offer", recipientDid, { json: opts.json });
3264
3061
  const ttlSeconds = parseTtl("delegation offer", opts.ttl);
3265
3062
  if (!opts.title || opts.title.length === 0) {
3266
3063
  throw new Error("delegation offer: --title is required (server-side validator rejects empty offers)");
3267
3064
  }
3268
3065
  const terms = parseOfferTerms("delegation offer", opts);
3269
3066
  const offeredAssetId = terms.currency?.asset_id;
3270
- if (offeredAssetId && !(0, import_sdk10.isWhitelistedAssetId)(offeredAssetId)) {
3067
+ if (offeredAssetId && !(0, import_sdk12.isWhitelistedAssetId)(offeredAssetId)) {
3271
3068
  console.error(
3272
- import_chalk8.default.yellow(
3069
+ import_chalk9.default.yellow(
3273
3070
  `warning: currency '${offeredAssetId}' is not in the static payment whitelist \u2014 the server will reject the offer (DELEGATION_ASSET_NOT_ALLOWED) unless its deploy registers this asset. See 'heyarp assets'.`
3274
3071
  )
3275
3072
  );
@@ -3286,45 +3083,45 @@ async function runOffer(recipientDid, opts) {
3286
3083
  );
3287
3084
  }
3288
3085
  const api = new ArpApiClient(opts.server);
3289
- const sender = resolveSenderAgent("delegation offer", opts.server, opts.fromDid);
3086
+ const sender = resolveSenderAgent("delegation offer", opts.server, opts.fromDid, opts.from);
3290
3087
  const content = {
3291
- action: import_sdk10.DelegationActions.OFFER,
3088
+ action: import_sdk12.DelegationActions.OFFER,
3292
3089
  delegation_id: delegationId,
3293
3090
  title: opts.title,
3294
3091
  ...terms
3295
3092
  };
3296
3093
  const body = { type: "delegation", content };
3297
- progress(opts.json, import_chalk8.default.dim(`Server: ${api.serverUrl}`));
3298
- progress(opts.json, import_chalk8.default.dim(`Sender: ${sender.did}`));
3299
- progress(opts.json, import_chalk8.default.dim(`Recipient: ${recipientDid}`));
3300
- progress(opts.json, import_chalk8.default.dim(`Delegation: ${delegationId}`));
3094
+ progress(opts.json, import_chalk9.default.dim(`Server: ${api.serverUrl}`));
3095
+ progress(opts.json, import_chalk9.default.dim(`Sender: ${sender.did}`));
3096
+ progress(opts.json, import_chalk9.default.dim(`Recipient: ${recipientDid}`));
3097
+ progress(opts.json, import_chalk9.default.dim(`Delegation: ${delegationId}`));
3301
3098
  let result;
3302
3099
  try {
3303
3100
  result = await sendDelegationEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
3304
3101
  } catch (err) {
3305
- if (err instanceof ApiError && err.payload.code === import_sdk10.DelegationOfferRejectionCodes.ASSET_NOT_ALLOWED) {
3102
+ if (err instanceof ApiError && err.payload.code === import_sdk12.DelegationOfferRejectionCodes.ASSET_NOT_ALLOWED) {
3306
3103
  const d = err.payload.details;
3307
- console.error(import_chalk8.default.yellow(`
3104
+ console.error(import_chalk9.default.yellow(`
3308
3105
  The server's payment-asset whitelist rejected this currency.`));
3309
3106
  if (d !== void 0) {
3310
- console.error(import_chalk8.default.dim(` offered: ${JSON.stringify(d.offered)}`));
3311
- console.error(import_chalk8.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
3107
+ console.error(import_chalk9.default.dim(` offered: ${JSON.stringify(d.offered)}`));
3108
+ console.error(import_chalk9.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
3312
3109
  }
3313
- console.error(import_chalk8.default.dim(`
3110
+ console.error(import_chalk9.default.dim(`
3314
3111
  See the whitelist (shorthand keys + canonical decimals):
3315
3112
  heyarp assets
3316
3113
  then re-offer with a whitelisted --currency.`));
3317
3114
  }
3318
- if (err instanceof ApiError && err.payload.code === import_sdk10.DelegationOfferRejectionCodes.PRICING_MISMATCH) {
3115
+ if (err instanceof ApiError && err.payload.code === import_sdk12.DelegationOfferRejectionCodes.PRICING_MISMATCH) {
3319
3116
  const d = err.payload.details;
3320
- console.error(import_chalk8.default.yellow(`
3117
+ console.error(import_chalk9.default.yellow(`
3321
3118
  The recipient's published accept-prefs rejected this offer${d?.reason ? ` (mismatch: ${d.reason})` : ""}.`));
3322
3119
  if (d !== void 0) {
3323
- console.error(import_chalk8.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
3324
- console.error(import_chalk8.default.dim(` offered: ${JSON.stringify(d.offered)}`));
3120
+ console.error(import_chalk9.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
3121
+ console.error(import_chalk9.default.dim(` offered: ${JSON.stringify(d.offered)}`));
3325
3122
  }
3326
3123
  console.error(
3327
- import_chalk8.default.dim(
3124
+ import_chalk9.default.dim(
3328
3125
  `
3329
3126
  Check what the recipient accepts BEFORE offering:
3330
3127
  heyarp agents accept-prefs show ${recipientDid}
@@ -3332,12 +3129,12 @@ then re-run with matching --currency / --amount.`
3332
3129
  )
3333
3130
  );
3334
3131
  }
3335
- if (err instanceof ApiError && err.payload.code === import_sdk10.DelegationOfferRejectionCodes.CAPACITY_EXCEEDED) {
3132
+ if (err instanceof ApiError && err.payload.code === import_sdk12.DelegationOfferRejectionCodes.CAPACITY_EXCEEDED) {
3336
3133
  const d = err.payload.details;
3337
3134
  const cap = d?.maxActive === 0 ? "closed for new offers (busy)" : `at capacity (${d?.currentActive}/${d?.maxActive} active delegations)`;
3338
- console.error(import_chalk8.default.yellow(`
3135
+ console.error(import_chalk9.default.yellow(`
3339
3136
  The recipient is ${cap}.`));
3340
- console.error(import_chalk8.default.dim("\nThis is TRANSIENT \u2014 your terms are fine. Retry the same offer later, or pick another worker (`heyarp agents --tag \u2026`)."));
3137
+ console.error(import_chalk9.default.dim("\nThis is TRANSIENT \u2014 your terms are fine. Retry the same offer later, or pick another worker (`heyarp agents --tag \u2026`)."));
3341
3138
  }
3342
3139
  throw err;
3343
3140
  }
@@ -3355,15 +3152,15 @@ The recipient is ${cap}.`));
3355
3152
  });
3356
3153
  } else {
3357
3154
  printIngestResult(result);
3358
- console.log(import_chalk8.default.dim(`
3155
+ console.log(import_chalk9.default.dim(`
3359
3156
  Reference this delegation on subsequent calls with:`));
3360
- console.log(import_chalk8.default.dim(` heyarp delegation accept ${result.relationshipId} ${delegationId}`));
3361
- console.log(import_chalk8.default.dim(` heyarp delegation decline ${result.relationshipId} ${delegationId}`));
3362
- console.log(import_chalk8.default.dim(` heyarp delegation cancel ${result.relationshipId} ${delegationId}`));
3363
- console.log(import_chalk8.default.dim(`
3157
+ console.log(import_chalk9.default.dim(` heyarp delegation accept ${result.relationshipId} ${delegationId}`));
3158
+ console.log(import_chalk9.default.dim(` heyarp delegation decline ${result.relationshipId} ${delegationId}`));
3159
+ console.log(import_chalk9.default.dim(` heyarp delegation cancel ${result.relationshipId} ${delegationId}`));
3160
+ console.log(import_chalk9.default.dim(`
3364
3161
  After the worker accepts, fund the escrow lock:`));
3365
- console.log(import_chalk8.default.dim(` heyarp wallet create-lock --delegation-id ${delegationId} --condition-hash <hex> ... > lock.json`));
3366
- console.log(import_chalk8.default.dim(` heyarp delegation fund ${delegationId} --escrow-lock-from-file lock.json`));
3162
+ console.log(import_chalk9.default.dim(` heyarp wallet create-lock --delegation-id ${delegationId} --condition-hash <hex> ... > lock.json`));
3163
+ console.log(import_chalk9.default.dim(` heyarp delegation fund ${delegationId} --escrow-lock-from-file lock.json`));
3367
3164
  }
3368
3165
  if (opts.waitUntil && !opts.json) {
3369
3166
  const untilPhase = parseUntilPhase(opts.waitUntil);
@@ -3385,7 +3182,7 @@ After the worker accepts, fund the escrow lock:`));
3385
3182
  }
3386
3183
  }
3387
3184
  function registerFund(parent) {
3388
- parent.command("fund").description("Fund an ACCEPTED delegation with the escrow lock (buyer-only). Run AFTER the worker accepts the offer.").argument("<delegation-id>", "Delegation UUID (the one you offered + the worker accepted)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk10.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(
3185
+ parent.command("fund").description("Fund an ACCEPTED delegation with the escrow lock (buyer-only). Run AFTER the worker accepts the offer.").argument("<delegation-id>", "Delegation UUID (the one you offered + the worker accepted)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk12.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(
3389
3186
  "--json",
3390
3187
  'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"fund", delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude moves off stdout; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
3391
3188
  false
@@ -3426,7 +3223,7 @@ async function runFund(delegationId, opts) {
3426
3223
  );
3427
3224
  }
3428
3225
  const api = new ArpApiClient(opts.server);
3429
- const sender = resolveSenderAgent("delegation fund", opts.server, opts.fromDid);
3226
+ const sender = resolveSenderAgent("delegation fund", opts.server, opts.fromDid, opts.from);
3430
3227
  const signer = makeSigner(sender);
3431
3228
  const resolved = await resolveFundRefs("delegation fund", api, signer, { delegationId, selfDid: sender.did });
3432
3229
  if (escrowResult.lockProgramId !== void 0) {
@@ -3443,23 +3240,23 @@ async function runFund(delegationId, opts) {
3443
3240
  }
3444
3241
  if (result2.kind === "skipped_no_expected_program_id") {
3445
3242
  console.error(
3446
- import_chalk8.default.yellow(
3243
+ import_chalk9.default.yellow(
3447
3244
  "\u26A0 delegation fund: no authoritative expected program-id available (--program-id missing, ARP_ESCROW_PROGRAM_ID env unset, server protocol-fee unreachable). Pre-flight skipped; server-side ESC_LOCK_TX_PROGRAM_ID_MISMATCH check is the only backstop. Set ARP_ESCROW_PROGRAM_ID or pass --program-id to enable pre-flight."
3448
3245
  )
3449
3246
  );
3450
3247
  }
3451
3248
  }
3452
- const content = { action: import_sdk10.DelegationActions.FUND, delegation_id: delegationId };
3249
+ const content = { action: import_sdk12.DelegationActions.FUND, delegation_id: delegationId };
3453
3250
  const body = { type: "delegation", content };
3454
3251
  const attachments = { escrow_lock: escrowResult.attachment };
3455
- progress(opts.json, import_chalk8.default.dim(`Server: ${api.serverUrl}`));
3456
- progress(opts.json, import_chalk8.default.dim(`Sender: ${sender.did}`));
3457
- progress(opts.json, import_chalk8.default.dim(`Recipient: ${resolved.recipientDid}`));
3458
- progress(opts.json, import_chalk8.default.dim(`Relationship: ${resolved.relationshipId}`));
3459
- progress(opts.json, import_chalk8.default.dim(`Delegation: ${delegationId} (action=fund)`));
3252
+ progress(opts.json, import_chalk9.default.dim(`Server: ${api.serverUrl}`));
3253
+ progress(opts.json, import_chalk9.default.dim(`Sender: ${sender.did}`));
3254
+ progress(opts.json, import_chalk9.default.dim(`Recipient: ${resolved.recipientDid}`));
3255
+ progress(opts.json, import_chalk9.default.dim(`Relationship: ${resolved.relationshipId}`));
3256
+ progress(opts.json, import_chalk9.default.dim(`Delegation: ${delegationId} (action=fund)`));
3460
3257
  {
3461
3258
  const a = escrowResult.attachment;
3462
- progress(opts.json, import_chalk8.default.dim(`Escrow lock attached: lock_id=${a.lock_id} amount=${a.amount} asset_id=${a.asset_id}`));
3259
+ progress(opts.json, import_chalk9.default.dim(`Escrow lock attached: lock_id=${a.lock_id} amount=${a.amount} asset_id=${a.asset_id}`));
3463
3260
  }
3464
3261
  const result = await sendDelegationEnvelope({
3465
3262
  api,
@@ -3485,7 +3282,7 @@ async function runFund(delegationId, opts) {
3485
3282
  });
3486
3283
  } else {
3487
3284
  printIngestResult(result);
3488
- console.log(import_chalk8.default.dim("\nThe worker waits for the on-chain lock to confirm (LOCKED), then begins work."));
3285
+ console.log(import_chalk9.default.dim("\nThe worker waits for the on-chain lock to confirm (LOCKED), then begins work."));
3489
3286
  }
3490
3287
  if (opts.waitUntil && !opts.json) {
3491
3288
  const untilPhase = parseUntilPhase(opts.waitUntil);
@@ -3534,7 +3331,7 @@ async function resolveFundRefs(cmdName, api, signer, args) {
3534
3331
  );
3535
3332
  }
3536
3333
  function registerAccept(parent) {
3537
- parent.command("accept").description("Accept a PROPOSED delegation \u2014 promotes to ACCEPTED. Counterparty-only.").argument("<relationship-id>", "Relationship UUID").argument("<delegation-id>", "Delegation UUID").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--ttl <seconds>", "Envelope TTL in seconds", "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
3334
+ parent.command("accept").description("Accept a PROPOSED delegation \u2014 promotes to ACCEPTED. Counterparty-only.").argument("<relationship-id>", "Relationship UUID").argument("<delegation-id>", "Delegation UUID").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--ttl <seconds>", "Envelope TTL in seconds", "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
3538
3335
  "--json",
3539
3336
  'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"accept", delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude + pending-lock poll chatter move off stdout; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
3540
3337
  false
@@ -3546,11 +3343,11 @@ function registerAccept(parent) {
3546
3343
  });
3547
3344
  }
3548
3345
  function registerDecline(parent) {
3549
- parent.command("decline").description("Decline a PROPOSED delegation \u2014 moves to DECLINED. Counterparty-only.").argument("<relationship-id>", "Relationship UUID").argument("<delegation-id>", "Delegation UUID").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--ttl <seconds>", "Envelope TTL in seconds", "3600").requiredOption(
3346
+ parent.command("decline").description("Decline a PROPOSED delegation \u2014 moves to DECLINED. Counterparty-only.").argument("<relationship-id>", "Relationship UUID").argument("<delegation-id>", "Delegation UUID").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--ttl <seconds>", "Envelope TTL in seconds", "3600").requiredOption(
3550
3347
  "--reason <code>",
3551
3348
  // surface the closed enum at help time so operators
3552
3349
  // don't have to read source to find acceptable values.
3553
- `Required: decline reason code (one of: ${import_sdk10.DECLINE_REASONS.join(", ")}). Carried in body.content.reason so the counterparty's reactor can branch on it.`
3350
+ `Required: decline reason code (one of: ${import_sdk12.DECLINE_REASONS.join(", ")}). Carried in body.content.reason so the counterparty's reactor can branch on it.`
3554
3351
  ).option("--reason-detail <s>", 'Optional free-text elaboration alongside --reason (e.g. "rate floor 0.20 USDC"). Max 512 chars.').option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
3555
3352
  "--json",
3556
3353
  'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"decline", delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude + pending-lock poll chatter move off stdout; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
@@ -3563,7 +3360,7 @@ function registerDecline(parent) {
3563
3360
  });
3564
3361
  }
3565
3362
  function registerCancel(parent) {
3566
- parent.command("cancel").description("Cancel an OFFERED delegation \u2014 moves to CANCELED. Offerer-only (the OTHER side uses decline).").argument("<relationship-id>", "Relationship UUID").argument("<delegation-id>", "Delegation UUID").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--ttl <seconds>", "Envelope TTL in seconds", "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
3363
+ parent.command("cancel").description("Cancel an OFFERED delegation \u2014 moves to CANCELED. Offerer-only (the OTHER side uses decline).").argument("<relationship-id>", "Relationship UUID").argument("<delegation-id>", "Delegation UUID").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--ttl <seconds>", "Envelope TTL in seconds", "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
3567
3364
  "--json",
3568
3365
  'Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, action:"cancel", delegationId, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash}). Prelude + pending-lock poll chatter move off stdout; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.',
3569
3366
  false
@@ -3587,16 +3384,16 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
3587
3384
  const lockWaitTimeoutSec = parseLockWaitTimeout(cmdName, opts.lockWaitTimeout);
3588
3385
  const lockWaitIntervalSec = parseLockWaitInterval(cmdName, opts.lockWaitInterval);
3589
3386
  let declinePayload = null;
3590
- if (action === import_sdk10.DelegationActions.DECLINE) {
3387
+ if (action === import_sdk12.DelegationActions.DECLINE) {
3591
3388
  const reason = parseDeclineReason(cmdName, opts.reason);
3592
3389
  const validatedDetail = parseReasonDetail(cmdName, opts.reasonDetail);
3593
3390
  declinePayload = validatedDetail ? { reason, reasonDetail: validatedDetail } : { reason };
3594
3391
  }
3595
3392
  const api = new ArpApiClient(opts.server);
3596
- const sender = resolveSenderAgent(cmdName, opts.server, opts.fromDid);
3393
+ const sender = resolveSenderAgent(cmdName, opts.server, opts.fromDid, opts.from);
3597
3394
  const signer = makeSigner(sender);
3598
3395
  const resolved = await resolveDelegationRefs(cmdName, api, signer, { relationshipId, delegationId, action, selfDid: sender.did });
3599
- if (resolved.state === import_sdk10.DelegationStates.PENDING_LOCK_FINALIZATION && opts.waitForLock !== false) {
3396
+ if (resolved.state === import_sdk12.DelegationStates.PENDING_LOCK_FINALIZATION && opts.waitForLock !== false) {
3600
3397
  await awaitDelegationLockFinalized(cmdName, api, signer, {
3601
3398
  relationshipId,
3602
3399
  delegationId,
@@ -3618,10 +3415,10 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
3618
3415
  if (declinePayload.reasonDetail) content.reason_detail = declinePayload.reasonDetail;
3619
3416
  }
3620
3417
  const body = { type: "delegation", content };
3621
- progress(opts.json, import_chalk8.default.dim(`Server: ${api.serverUrl}`));
3622
- progress(opts.json, import_chalk8.default.dim(`Sender: ${sender.did}`));
3623
- progress(opts.json, import_chalk8.default.dim(`Relationship: ${relationshipId}`));
3624
- progress(opts.json, import_chalk8.default.dim(`Delegation: ${delegationId} (action=${action}${action === import_sdk10.DelegationActions.DECLINE ? `, reason=${content.reason}` : ""})`));
3418
+ progress(opts.json, import_chalk9.default.dim(`Server: ${api.serverUrl}`));
3419
+ progress(opts.json, import_chalk9.default.dim(`Sender: ${sender.did}`));
3420
+ progress(opts.json, import_chalk9.default.dim(`Relationship: ${relationshipId}`));
3421
+ progress(opts.json, import_chalk9.default.dim(`Delegation: ${delegationId} (action=${action}${action === import_sdk12.DelegationActions.DECLINE ? `, reason=${content.reason}` : ""})`));
3625
3422
  const result = await sendDelegationEnvelope({
3626
3423
  api,
3627
3424
  sender,
@@ -3650,9 +3447,9 @@ async function runFollowupAction(relationshipId, delegationId, action, opts) {
3650
3447
  async function sendDelegationEnvelope(args) {
3651
3448
  const nextSequence = (args.sender.lastSenderSequence ?? 0) + 1;
3652
3449
  const protectedBlock = {
3653
- protocol_version: import_sdk10.CURRENT_PROTOCOL_VERSION,
3654
- purpose: import_sdk10.Purpose.ENVELOPE,
3655
- message_id: (0, import_sdk10.uuidV4)(),
3450
+ protocol_version: import_sdk12.CURRENT_PROTOCOL_VERSION,
3451
+ purpose: import_sdk12.Purpose.ENVELOPE,
3452
+ message_id: (0, import_sdk12.uuidV4)(),
3656
3453
  sender_did: args.sender.did,
3657
3454
  recipient_did: args.recipientDid,
3658
3455
  // `relationship_id: null` matches the handshake
@@ -3661,20 +3458,20 @@ async function sendDelegationEnvelope(args) {
3661
3458
  // existing relationship row.
3662
3459
  relationship_id: null,
3663
3460
  sender_sequence: nextSequence,
3664
- sender_nonce: (0, import_sdk10.senderNonce)(),
3665
- timestamp: (0, import_sdk10.rfc3339)(),
3666
- expires_at: (0, import_sdk10.expiresAt)(args.ttlSeconds),
3461
+ sender_nonce: (0, import_sdk12.senderNonce)(),
3462
+ timestamp: (0, import_sdk12.rfc3339)(),
3463
+ expires_at: (0, import_sdk12.expiresAt)(args.ttlSeconds),
3667
3464
  delivery_id: null
3668
3465
  };
3669
3466
  const signer = makeSigner(args.sender);
3670
- const envelope = (0, import_sdk10.signEnvelope)({
3467
+ const envelope = (0, import_sdk12.signEnvelope)({
3671
3468
  protected: protectedBlock,
3672
3469
  body: args.body,
3673
3470
  identitySecretKey: signer.identitySecretKey,
3674
3471
  attachments: args.attachments
3675
3472
  });
3676
3473
  if (args.verbose) {
3677
- console.log(import_chalk8.default.bold("\nEnvelope (pre-send):"));
3474
+ console.log(import_chalk9.default.bold("\nEnvelope (pre-send):"));
3678
3475
  console.log(formatJson(envelope));
3679
3476
  }
3680
3477
  try {
@@ -3682,7 +3479,7 @@ async function sendDelegationEnvelope(args) {
3682
3479
  updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
3683
3480
  return result;
3684
3481
  } catch (err) {
3685
- if (err instanceof ApiError && (0, import_sdk10.isPostCommitErrorCode)(err.payload.code)) {
3482
+ if (err instanceof ApiError && (0, import_sdk12.isPostCommitErrorCode)(err.payload.code)) {
3686
3483
  updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
3687
3484
  }
3688
3485
  throw err;
@@ -3704,7 +3501,7 @@ async function resolveDelegationRefs(cmdName, api, signer, args) {
3704
3501
  );
3705
3502
  }
3706
3503
  let recipientDid;
3707
- if (args.action === import_sdk10.DelegationActions.CANCEL) {
3504
+ if (args.action === import_sdk12.DelegationActions.CANCEL) {
3708
3505
  const firstEvents = await api.listEvents(args.relationshipId, signer, { since: 0, limit: 1 });
3709
3506
  const handshake = firstEvents[0];
3710
3507
  if (!handshake) {
@@ -3729,7 +3526,7 @@ async function resolveDelegationRefs(cmdName, api, signer, args) {
3729
3526
  async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
3730
3527
  const log = args.log ?? ((line) => console.log(line));
3731
3528
  log(
3732
- import_chalk8.default.dim(
3529
+ import_chalk9.default.dim(
3733
3530
  `
3734
3531
  [--wait-for-lock] delegation ${args.delegationId} is awaiting on-chain lock confirmation; polling until ready (interval=${args.intervalSec}s timeout=${args.timeoutSec}s)`
3735
3532
  )
@@ -3744,7 +3541,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
3744
3541
  after = page[page.length - 1].id;
3745
3542
  }
3746
3543
  };
3747
- const outcome = await (0, import_sdk10.pollUntil)({
3544
+ const outcome = await (0, import_sdk12.pollUntil)({
3748
3545
  fetch: fetchRow,
3749
3546
  // Match on either "row not found at all" OR "state moved
3750
3547
  // past pending_lock_finalization". The post-poll branch
@@ -3754,7 +3551,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
3754
3551
  // rows return cleanly. Polling on null would loop pointlessly
3755
3552
  // until the deadline fires and surface a misleading "timed
3756
3553
  // out" message for what's actually a wrong-id problem.
3757
- predicate: (row2) => row2 === null || row2.state !== import_sdk10.DelegationStates.PENDING_LOCK_FINALIZATION,
3554
+ predicate: (row2) => row2 === null || row2.state !== import_sdk12.DelegationStates.PENDING_LOCK_FINALIZATION,
3758
3555
  intervalMs: args.intervalSec * 1e3,
3759
3556
  timeoutMs: args.timeoutSec * 1e3,
3760
3557
  // Swallow ONLY transient errors. A 4xx during the poll is a
@@ -3768,7 +3565,7 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
3768
3565
  if (err instanceof ApiError && err.status >= 400 && err.status < 500) {
3769
3566
  throw err;
3770
3567
  }
3771
- log(import_chalk8.default.dim(` poll: transient fetch error (${err instanceof Error ? err.message : String(err)})`));
3568
+ log(import_chalk9.default.dim(` poll: transient fetch error (${err instanceof Error ? err.message : String(err)})`));
3772
3569
  }
3773
3570
  });
3774
3571
  if (outcome.kind === "timeout") {
@@ -3785,12 +3582,12 @@ async function awaitDelegationLockFinalized(cmdName, api, signer, args) {
3785
3582
  `${cmdName}: delegation ${args.delegationId} disappeared from relationship ${args.relationshipId} during --wait-for-lock pre-flight. Re-check the delegation id with \`heyarp delegations ${args.relationshipId}\`.`
3786
3583
  );
3787
3584
  }
3788
- if (row.state !== import_sdk10.DelegationStates.OFFERED) {
3585
+ if (row.state !== import_sdk12.DelegationStates.OFFERED) {
3789
3586
  throw new Error(
3790
3587
  `${cmdName}: delegation ${args.delegationId} transitioned to '${row.state}' while waiting for on-chain lock confirmation; cannot ${args.action}. Re-read the delegation timeline with \`heyarp delegations ${args.relationshipId}\` to see the latest state.`
3791
3588
  );
3792
3589
  }
3793
- log(import_chalk8.default.dim(`[--wait-for-lock] delegation ${args.delegationId} ready (state=${row.state}); proceeding with ${args.action}.`));
3590
+ log(import_chalk9.default.dim(`[--wait-for-lock] delegation ${args.delegationId} ready (state=${row.state}); proceeding with ${args.action}.`));
3794
3591
  return row;
3795
3592
  }
3796
3593
  function parseLockWaitTimeout(cmdName, raw) {
@@ -3816,12 +3613,12 @@ function parseLockWaitInterval(cmdName, raw) {
3816
3613
  return n;
3817
3614
  }
3818
3615
  function printIngestResult(result) {
3819
- console.log(import_chalk8.default.green("\nDelivered."));
3820
- console.log(`${import_chalk8.default.bold("Event id")}: ${import_chalk8.default.cyan(result.eventId)}`);
3821
- console.log(`${import_chalk8.default.bold("Relationship id")}: ${import_chalk8.default.cyan(result.relationshipId)}`);
3822
- console.log(`${import_chalk8.default.bold("Chain index")}: ${import_chalk8.default.cyan(String(result.relationshipEventIndex))}`);
3823
- console.log(`${import_chalk8.default.bold("Server timestamp")}: ${import_chalk8.default.cyan(result.serverTimestamp)}`);
3824
- console.log(`${import_chalk8.default.bold("Server event hash")}: ${import_chalk8.default.cyan(result.serverEventHash)}`);
3616
+ console.log(import_chalk9.default.green("\nDelivered."));
3617
+ console.log(`${import_chalk9.default.bold("Event id")}: ${import_chalk9.default.cyan(result.eventId)}`);
3618
+ console.log(`${import_chalk9.default.bold("Relationship id")}: ${import_chalk9.default.cyan(result.relationshipId)}`);
3619
+ console.log(`${import_chalk9.default.bold("Chain index")}: ${import_chalk9.default.cyan(String(result.relationshipEventIndex))}`);
3620
+ console.log(`${import_chalk9.default.bold("Server timestamp")}: ${import_chalk9.default.cyan(result.serverTimestamp)}`);
3621
+ console.log(`${import_chalk9.default.bold("Server event hash")}: ${import_chalk9.default.cyan(result.serverEventHash)}`);
3825
3622
  }
3826
3623
  function parseOfferTerms(cmdName, opts) {
3827
3624
  const out = {};
@@ -3845,7 +3642,7 @@ function parseOfferTerms(cmdName, opts) {
3845
3642
  if (opts.amount) {
3846
3643
  out.amount = opts.amount;
3847
3644
  if (!opts.currency) {
3848
- throw new Error(`${cmdName}: --amount requires --currency. Shorthand: ${import_sdk10.WELL_KNOWN_ASSET_KEYS.join(", ")}, or raw CAIP-19 + --currency-decimals.`);
3645
+ throw new Error(`${cmdName}: --amount requires --currency. Shorthand: ${import_sdk12.WELL_KNOWN_ASSET_KEYS.join(", ")}, or raw CAIP-19 + --currency-decimals.`);
3849
3646
  }
3850
3647
  out.currency = buildAssetIdentifier(cmdName, DELEGATION_CURRENCY_FLAGS, opts.currency, opts.currencyDecimals, opts.currencySymbol);
3851
3648
  } else if (opts.currency) {
@@ -3868,7 +3665,7 @@ function resolveOfferDelegationId(rawCliId, escrow) {
3868
3665
  cliId = rawCliId.toLowerCase();
3869
3666
  }
3870
3667
  if (escrow === void 0) {
3871
- return cliId ?? (0, import_sdk10.uuidV4)();
3668
+ return cliId ?? (0, import_sdk12.uuidV4)();
3872
3669
  }
3873
3670
  if (escrow.delegationIdFromLock !== void 0) {
3874
3671
  const fileId = escrow.delegationIdFromLock;
@@ -3893,20 +3690,15 @@ function requireUuidNormalised(cmdName, raw, label) {
3893
3690
  requireUuid2(cmdName, raw, label);
3894
3691
  return raw.toLowerCase();
3895
3692
  }
3896
- function requireDid(cmdName, did, label) {
3897
- if (typeof did !== "string" || !did.startsWith("did:arp:") || did.length <= "did:arp:".length) {
3898
- throw new Error(`${cmdName}: ${label} must look like 'did:arp:...' (got '${did}')`);
3899
- }
3900
- }
3901
3693
  function collectRepeated(value, previous) {
3902
3694
  return [...previous, value];
3903
3695
  }
3904
3696
  function parseDeclineReason(cmdName, raw) {
3905
3697
  if (raw === void 0 || raw === "") {
3906
- throw new Error(`${cmdName}: --reason is required when declining (one of: ${import_sdk10.DECLINE_REASONS.join(", ")})`);
3698
+ throw new Error(`${cmdName}: --reason is required when declining (one of: ${import_sdk12.DECLINE_REASONS.join(", ")})`);
3907
3699
  }
3908
- if (!(0, import_sdk10.isDeclineReason)(raw)) {
3909
- throw new Error(`${cmdName}: --reason must be one of ${import_sdk10.DECLINE_REASONS.join(", ")} (got '${raw}')`);
3700
+ if (!(0, import_sdk12.isDeclineReason)(raw)) {
3701
+ throw new Error(`${cmdName}: --reason must be one of ${import_sdk12.DECLINE_REASONS.join(", ")} (got '${raw}')`);
3910
3702
  }
3911
3703
  return raw;
3912
3704
  }
@@ -3921,10 +3713,10 @@ function parseReasonDetail(cmdName, raw) {
3921
3713
  return raw;
3922
3714
  }
3923
3715
  function buildAssetIdentifier(cmdName, labels, rawCurrency, rawDecimals, rawSymbol) {
3924
- const resolved = (0, import_sdk10.resolveAsset)(rawCurrency);
3716
+ const resolved = (0, import_sdk12.resolveAsset)(rawCurrency);
3925
3717
  if (!resolved) {
3926
3718
  throw new Error(
3927
- `${cmdName}: ${labels.currencyFlag} '${rawCurrency}' is not a known shorthand or a valid CAIP-19 string. Shorthand: ${import_sdk10.WELL_KNOWN_ASSET_KEYS.join(", ")}. Or pass a raw CAIP-19 id (e.g. "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/spl:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") with ${labels.decimalsFlag}.`
3719
+ `${cmdName}: ${labels.currencyFlag} '${rawCurrency}' is not a known shorthand or a valid CAIP-19 string. Shorthand: ${import_sdk12.WELL_KNOWN_ASSET_KEYS.join(", ")}. Or pass a raw CAIP-19 id (e.g. "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/spl:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") with ${labels.decimalsFlag}.`
3928
3720
  );
3929
3721
  }
3930
3722
  let decimals = resolved.decimals;
@@ -3933,20 +3725,20 @@ function buildAssetIdentifier(cmdName, labels, rawCurrency, rawDecimals, rawSymb
3933
3725
  throw new Error(`${cmdName}: ${labels.currencyFlag} is a raw CAIP-19 string; ${labels.decimalsFlag} (0-18) is required to convert amounts to base units.`);
3934
3726
  }
3935
3727
  const parsed = Number(rawDecimals);
3936
- if (!Number.isInteger(parsed) || parsed < import_sdk10.ASSET_DECIMALS_MIN || parsed > import_sdk10.ASSET_DECIMALS_MAX) {
3728
+ if (!Number.isInteger(parsed) || parsed < import_sdk12.ASSET_DECIMALS_MIN || parsed > import_sdk12.ASSET_DECIMALS_MAX) {
3937
3729
  throw new Error(`${cmdName}: ${labels.decimalsFlag} must be an integer in [0, 18] (got '${rawDecimals}').`);
3938
3730
  }
3939
3731
  decimals = parsed;
3940
3732
  } else if (rawDecimals !== void 0) {
3941
3733
  const parsed = Number(rawDecimals);
3942
- if (!Number.isInteger(parsed) || parsed < import_sdk10.ASSET_DECIMALS_MIN || parsed > import_sdk10.ASSET_DECIMALS_MAX) {
3734
+ if (!Number.isInteger(parsed) || parsed < import_sdk12.ASSET_DECIMALS_MIN || parsed > import_sdk12.ASSET_DECIMALS_MAX) {
3943
3735
  throw new Error(`${cmdName}: ${labels.decimalsFlag} must be an integer in [0, 18] (got '${rawDecimals}').`);
3944
3736
  }
3945
3737
  decimals = parsed;
3946
3738
  }
3947
3739
  let symbol = resolved.symbol;
3948
3740
  if (rawSymbol !== void 0) {
3949
- if (rawSymbol.length < import_sdk10.ASSET_SYMBOL_MIN_LEN || rawSymbol.length > import_sdk10.ASSET_SYMBOL_MAX_LEN) {
3741
+ if (rawSymbol.length < import_sdk12.ASSET_SYMBOL_MIN_LEN || rawSymbol.length > import_sdk12.ASSET_SYMBOL_MAX_LEN) {
3950
3742
  throw new Error(`${cmdName}: ${labels.symbolFlag} must be 1-16 chars (got length ${rawSymbol.length}).`);
3951
3743
  }
3952
3744
  symbol = rawSymbol;
@@ -3960,12 +3752,12 @@ var DELEGATION_CURRENCY_FLAGS = {
3960
3752
  };
3961
3753
 
3962
3754
  // src/commands/delegations.ts
3963
- var import_sdk11 = require("@heyanon-arp/sdk");
3964
- var import_chalk9 = __toESM(require("chalk"));
3755
+ var import_sdk13 = require("@heyanon-arp/sdk");
3756
+ var import_chalk10 = __toESM(require("chalk"));
3965
3757
  init_api();
3966
- var ALLOWED_STATES = /* @__PURE__ */ new Set([import_sdk11.DelegationStates.OFFERED, import_sdk11.DelegationStates.ACCEPTED, import_sdk11.DelegationStates.DECLINED, import_sdk11.DelegationStates.CANCELED]);
3758
+ var ALLOWED_STATES = /* @__PURE__ */ new Set([import_sdk13.DelegationStates.OFFERED, import_sdk13.DelegationStates.ACCEPTED, import_sdk13.DelegationStates.DECLINED, import_sdk13.DelegationStates.CANCELED]);
3967
3759
  function registerDelegationsCommand(root) {
3968
- root.command("delegations").description("List delegations for a relationship (one row per delegationId, oldest-first)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--state <s>", "Filter by exact state (offered|accepted|declined|canceled)").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(
3760
+ root.command("delegations").description("List delegations for a relationship (one row per delegationId, oldest-first)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--state <s>", "Filter by exact state (offered|accepted|declined|canceled)").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(
3969
3761
  "--verbose",
3970
3762
  'After the one-line summaries, print a framed "Full delegation payloads (N rows)" block \u2014 each row labelled with full delegationId (`delegation accept` / `delegation decline` / `work request` need it) and dumped as JSON. Mutually exclusive with --json.',
3971
3763
  false
@@ -3982,10 +3774,10 @@ async function runDelegations(relationshipId, opts) {
3982
3774
  const limit = parseLimit2(opts.limit);
3983
3775
  const state = parseState(opts.state);
3984
3776
  const api = new ArpApiClient(opts.server);
3985
- const sender = resolveSenderAgent("delegations", opts.server, opts.fromDid);
3986
- progress(opts.json, import_chalk9.default.dim(`Server: ${api.serverUrl}`));
3987
- progress(opts.json, import_chalk9.default.dim(`Signer: ${sender.did}`));
3988
- progress(opts.json, import_chalk9.default.dim(`Relationship: ${relationshipId}`));
3777
+ const sender = resolveSenderAgent("delegations", opts.server, opts.fromDid, opts.from);
3778
+ progress(opts.json, import_chalk10.default.dim(`Server: ${api.serverUrl}`));
3779
+ progress(opts.json, import_chalk10.default.dim(`Signer: ${sender.did}`));
3780
+ progress(opts.json, import_chalk10.default.dim(`Relationship: ${relationshipId}`));
3989
3781
  const query = { limit };
3990
3782
  if (state) query.state = state;
3991
3783
  if (opts.after) query.after = opts.after;
@@ -3996,7 +3788,7 @@ async function runDelegations(relationshipId, opts) {
3996
3788
  return;
3997
3789
  }
3998
3790
  if (rows.length === 0) {
3999
- console.log(import_chalk9.default.dim("\n(no delegations for this relationship)"));
3791
+ console.log(import_chalk10.default.dim("\n(no delegations for this relationship)"));
4000
3792
  return;
4001
3793
  }
4002
3794
  console.log("");
@@ -4012,19 +3804,19 @@ async function runDelegations(relationshipId, opts) {
4012
3804
  }));
4013
3805
  }
4014
3806
  const lastId = rows[rows.length - 1].id;
4015
- console.log(import_chalk9.default.dim(`
3807
+ console.log(import_chalk10.default.dim(`
4016
3808
  ${rows.length} delegation row(s). Paginate with --after ${lastId}.`));
4017
3809
  }
4018
3810
  function formatDelegationLine(d, selfDid, opts = {}) {
4019
- const idHead_ = import_chalk9.default.bold(opts.fullIds ? d.delegationId : idHead(d.delegationId));
3811
+ const idHead_ = import_chalk10.default.bold(opts.fullIds ? d.delegationId : idHead(d.delegationId));
4020
3812
  const state = colorState(d.state).padEnd(stateColumnWidth());
4021
- const offerer = d.offererDid === selfDid ? import_chalk9.default.bold("me") : import_chalk9.default.dim(opts.fullIds ? d.offererDid : didHead(d.offererDid));
3813
+ const offerer = d.offererDid === selfDid ? import_chalk10.default.bold("me") : import_chalk10.default.dim(opts.fullIds ? d.offererDid : didHead(d.offererDid));
4022
3814
  const amount = formatAmount(d);
4023
- const title = d.title ? import_chalk9.default.dim(`"${truncate2(d.title, 40)}"`) : import_chalk9.default.dim("(no title)");
3815
+ const title = d.title ? import_chalk10.default.dim(`"${truncate2(d.title, 40)}"`) : import_chalk10.default.dim("(no title)");
4024
3816
  let declineSuffix = "";
4025
- if (d.state === import_sdk11.DelegationStates.DECLINED && d.declineReason) {
3817
+ if (d.state === import_sdk13.DelegationStates.DECLINED && d.declineReason) {
4026
3818
  const detail = d.declineReasonDetail ? `: ${truncate2(d.declineReasonDetail, 40)}` : "";
4027
- declineSuffix = ` ${import_chalk9.default.dim(`(reason: ${d.declineReason}${detail})`)}`;
3819
+ declineSuffix = ` ${import_chalk10.default.dim(`(reason: ${d.declineReason}${detail})`)}`;
4028
3820
  }
4029
3821
  return `${idHead_} ${state} ${offerer} ${amount} ${title}${declineSuffix}`;
4030
3822
  }
@@ -4037,35 +3829,35 @@ function colorState(s) {
4037
3829
  // returns `undefined` and `formatDelegationLine` crashes with
4038
3830
  // `TypeError: Cannot read properties of undefined (reading
4039
3831
  // 'padEnd')` on any listing containing such a row.
4040
- case import_sdk11.DelegationStates.OFFERED:
4041
- return import_chalk9.default.yellow("offered");
4042
- case import_sdk11.DelegationStates.PENDING_LOCK_FINALIZATION:
4043
- return import_chalk9.default.yellow("pending_lock");
4044
- case import_sdk11.DelegationStates.ACCEPTED:
4045
- return import_chalk9.default.green("accepted");
3832
+ case import_sdk13.DelegationStates.OFFERED:
3833
+ return import_chalk10.default.yellow("offered");
3834
+ case import_sdk13.DelegationStates.PENDING_LOCK_FINALIZATION:
3835
+ return import_chalk10.default.yellow("pending_lock");
3836
+ case import_sdk13.DelegationStates.ACCEPTED:
3837
+ return import_chalk10.default.green("accepted");
4046
3838
  // The on-chain escrow lock is confirmed. Distinct branch so a
4047
3839
  // LOCKED row renders without hitting the defensive fallback
4048
3840
  // (which would otherwise echo the raw state).
4049
- case import_sdk11.DelegationStates.LOCKED:
4050
- return import_chalk9.default.green("locked");
4051
- case import_sdk11.DelegationStates.DECLINED:
4052
- return import_chalk9.default.red("declined");
4053
- case import_sdk11.DelegationStates.CANCELED:
4054
- return import_chalk9.default.dim("canceled");
3841
+ case import_sdk13.DelegationStates.LOCKED:
3842
+ return import_chalk10.default.green("locked");
3843
+ case import_sdk13.DelegationStates.DECLINED:
3844
+ return import_chalk10.default.red("declined");
3845
+ case import_sdk13.DelegationStates.CANCELED:
3846
+ return import_chalk10.default.dim("canceled");
4055
3847
  // Terminal escrow outcomes: completed = payee paid;
4056
3848
  // failed = create_lock never landed; refunded = funds returned
4057
3849
  // to the buyer (work expired / dispute closed);
4058
3850
  // dispute_resolved = operator ruled.
4059
- case import_sdk11.DelegationStates.COMPLETED:
4060
- return import_chalk9.default.green("completed");
4061
- case import_sdk11.DelegationStates.FAILED:
4062
- return import_chalk9.default.red("failed");
4063
- case import_sdk11.DelegationStates.REFUNDED:
4064
- return import_chalk9.default.red("refunded");
4065
- case import_sdk11.DelegationStates.DISPUTING:
4066
- return import_chalk9.default.yellow("disputing");
4067
- case import_sdk11.DelegationStates.DISPUTE_RESOLVED:
4068
- return import_chalk9.default.red("dispute_resolved");
3851
+ case import_sdk13.DelegationStates.COMPLETED:
3852
+ return import_chalk10.default.green("completed");
3853
+ case import_sdk13.DelegationStates.FAILED:
3854
+ return import_chalk10.default.red("failed");
3855
+ case import_sdk13.DelegationStates.REFUNDED:
3856
+ return import_chalk10.default.red("refunded");
3857
+ case import_sdk13.DelegationStates.DISPUTING:
3858
+ return import_chalk10.default.yellow("disputing");
3859
+ case import_sdk13.DelegationStates.DISPUTE_RESOLVED:
3860
+ return import_chalk10.default.red("dispute_resolved");
4069
3861
  default: {
4070
3862
  const _exhaustive = s;
4071
3863
  void _exhaustive;
@@ -4077,9 +3869,9 @@ function stateColumnWidth() {
4077
3869
  return 12;
4078
3870
  }
4079
3871
  function formatAmount(d) {
4080
- if (!d.amount) return import_chalk9.default.dim("(no amount)");
3872
+ if (!d.amount) return import_chalk10.default.dim("(no amount)");
4081
3873
  const currency = d.currency ? d.currency.symbol ?? d.currency.assetId : "?";
4082
- return import_chalk9.default.cyan(`${d.amount} ${currency}`);
3874
+ return import_chalk10.default.cyan(`${d.amount} ${currency}`);
4083
3875
  }
4084
3876
  function idHead(id) {
4085
3877
  if (id.length <= 12) return id;
@@ -4110,7 +3902,7 @@ function parseLimit2(raw) {
4110
3902
  }
4111
3903
 
4112
3904
  // src/commands/did-doc.ts
4113
- var import_sdk12 = require("@heyanon-arp/sdk");
3905
+ var import_sdk14 = require("@heyanon-arp/sdk");
4114
3906
  init_api();
4115
3907
  function registerDidDocCommand(root) {
4116
3908
  root.command("did-doc").description(
@@ -4119,7 +3911,7 @@ function registerDidDocCommand(root) {
4119
3911
  "--field <path>",
4120
3912
  "Extract a single value via a dotted path. Supports object property access (`id`), numeric array indexes (`verificationMethod.0`), and `#fragment` array selectors that match a verification-method or service entry by its `id` suffix (`verificationMethod.#settlement.publicKeyMultibase`). Two well-known shortcuts skip the path entirely AND strip the multibase prefix: `settlementPublicKey` / `identityPublicKey` emit the raw base58 pubkey ready for flags like `--recipient-pubkey`. Scalar values (string / number / boolean) emit raw to stdout for shell composition (`KEY=$(heyarp did-doc ... --field ...)`); objects / arrays emit as pretty-printed JSON. Mutually exclusive with `--json` since `--field` already controls the shape."
4121
3913
  ).action(async (did, opts) => {
4122
- if (!(0, import_sdk12.isValidDid)(did)) {
3914
+ if (!(0, import_sdk14.isValidDid)(did)) {
4123
3915
  throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
4124
3916
  }
4125
3917
  if (opts.json && opts.field !== void 0) {
@@ -4231,8 +4023,8 @@ function describeShape(value) {
4231
4023
  }
4232
4024
 
4233
4025
  // src/commands/doctor.ts
4234
- var import_sdk13 = require("@heyanon-arp/sdk");
4235
- var import_chalk10 = __toESM(require("chalk"));
4026
+ var import_sdk15 = require("@heyanon-arp/sdk");
4027
+ var import_chalk11 = __toESM(require("chalk"));
4236
4028
  init_api();
4237
4029
  function registerDoctorCommand(root) {
4238
4030
  root.command("doctor").description("Liveness probe for a counterparty: resolve DID document + read protocol activity. No auth.").argument("<did>", "did:arp:<base58btc> of the agent to probe").option("--server <url>", "Override ARP server base URL").option("--json", "Machine-readable: single JSON object on stdout. Pipe-safe.", false).action(async (did, opts) => {
@@ -4241,7 +4033,7 @@ function registerDoctorCommand(root) {
4241
4033
  }
4242
4034
  var LISTENING_THRESHOLD_SECONDS = 15 * 60;
4243
4035
  async function runDoctor(did, opts) {
4244
- if (!(0, import_sdk13.isValidDid)(did)) {
4036
+ if (!(0, import_sdk15.isValidDid)(did)) {
4245
4037
  throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
4246
4038
  }
4247
4039
  const api = new ArpApiClient(opts.server);
@@ -4325,52 +4117,52 @@ async function probe(api, did) {
4325
4117
  }
4326
4118
  function formatDoctorReport(r) {
4327
4119
  const lines = [];
4328
- lines.push(`${import_chalk10.default.dim("Server:")} ${r.server}`);
4329
- lines.push(`${import_chalk10.default.dim("Target DID:")} ${r.did}`);
4120
+ lines.push(`${import_chalk11.default.dim("Server:")} ${r.server}`);
4121
+ lines.push(`${import_chalk11.default.dim("Target DID:")} ${r.did}`);
4330
4122
  if (!r.didDocument.found) {
4331
- lines.push(`${import_chalk10.default.dim("DID doc:")} ${import_chalk10.default.red("\u2717")} not found`);
4123
+ lines.push(`${import_chalk11.default.dim("DID doc:")} ${import_chalk11.default.red("\u2717")} not found`);
4332
4124
  } else {
4333
4125
  const registered = r.didDocument.registeredAt ? ` (registered ${r.didDocument.registeredAt})` : "";
4334
- lines.push(`${import_chalk10.default.dim("DID doc:")} ${import_chalk10.default.green("\u2713")} resolved${registered}`);
4126
+ lines.push(`${import_chalk11.default.dim("DID doc:")} ${import_chalk11.default.green("\u2713")} resolved${registered}`);
4335
4127
  }
4336
4128
  if (r.activity) {
4337
4129
  if (r.activity.lastEventAt === null) {
4338
- lines.push(`${import_chalk10.default.dim("Activity:")} ${import_chalk10.default.dim("(no events ever \u2014 fresh agent)")}`);
4130
+ lines.push(`${import_chalk11.default.dim("Activity:")} ${import_chalk11.default.dim("(no events ever \u2014 fresh agent)")}`);
4339
4131
  } else {
4340
4132
  const ageMin = r.activity.ageSeconds !== null ? Math.floor(r.activity.ageSeconds / 60) : null;
4341
4133
  const ageStr = ageMin !== null && ageMin > 0 ? `${ageMin}m ago` : `${r.activity.ageSeconds}s ago`;
4342
- lines.push(`${import_chalk10.default.dim("Activity:")} last event ${ageStr} (${r.activity.lastEventAt})`);
4134
+ lines.push(`${import_chalk11.default.dim("Activity:")} last event ${ageStr} (${r.activity.lastEventAt})`);
4343
4135
  }
4344
4136
  if (r.activity.lastSeenAt !== null && r.activity.lastSeenAt !== void 0) {
4345
4137
  const seenMin = r.activity.seenAgeSeconds !== null && r.activity.seenAgeSeconds !== void 0 ? Math.floor(r.activity.seenAgeSeconds / 60) : null;
4346
4138
  const seenStr = seenMin !== null && seenMin > 0 ? `${seenMin}m ago` : `${r.activity.seenAgeSeconds}s ago`;
4347
- lines.push(`${import_chalk10.default.dim("Last seen:")} signed request ${seenStr} (${r.activity.lastSeenAt})`);
4139
+ lines.push(`${import_chalk11.default.dim("Last seen:")} signed request ${seenStr} (${r.activity.lastSeenAt})`);
4348
4140
  }
4349
4141
  if (r.activity.inboxStreamActive === true) {
4350
- lines.push(`${import_chalk10.default.dim("Inbox SSE:")} ${import_chalk10.default.green("\u2713")} active subscription on the central server`);
4142
+ lines.push(`${import_chalk11.default.dim("Inbox SSE:")} ${import_chalk11.default.green("\u2713")} active subscription on the central server`);
4351
4143
  }
4352
4144
  }
4353
- const verdictColor = r.verdict === "LISTENING" ? import_chalk10.default.green : r.verdict === "DORMANT" ? import_chalk10.default.red : import_chalk10.default.yellow;
4145
+ const verdictColor = r.verdict === "LISTENING" ? import_chalk11.default.green : r.verdict === "DORMANT" ? import_chalk11.default.red : import_chalk11.default.yellow;
4354
4146
  lines.push("");
4355
- lines.push(`${import_chalk10.default.bold("Verdict:")} ${verdictColor(r.verdict)} \u2014 ${r.reason}`);
4147
+ lines.push(`${import_chalk11.default.bold("Verdict:")} ${verdictColor(r.verdict)} \u2014 ${r.reason}`);
4356
4148
  return lines.join("\n");
4357
4149
  }
4358
4150
 
4359
4151
  // src/commands/envelope.ts
4360
- var import_chalk11 = __toESM(require("chalk"));
4152
+ var import_chalk12 = __toESM(require("chalk"));
4361
4153
  init_api();
4362
4154
  function registerEnvelopeCommand(root) {
4363
- root.command("envelope").description("Fetch one canonical envelope by eventId \u2014 full body for inspection (signed read)").argument("<event-id>", "Event UUID \u2014 copy from `heyarp inbox`, `heyarp events`, or a counterparty citation").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("--json", "Machine-readable: emit only the envelope JSON object on stdout (no prelude, no chalk). Pipe-safe.", false).action(async (eventId, opts) => {
4155
+ root.command("envelope").description("Fetch one canonical envelope by eventId \u2014 full body for inspection (signed read)").argument("<event-id>", "Event UUID \u2014 copy from `heyarp inbox`, `heyarp events`, or a counterparty citation").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("--json", "Machine-readable: emit only the envelope JSON object on stdout (no prelude, no chalk). Pipe-safe.", false).action(async (eventId, opts) => {
4364
4156
  await runEnvelope(eventId, opts);
4365
4157
  });
4366
4158
  }
4367
4159
  async function runEnvelope(eventId, opts) {
4368
4160
  const api = new ArpApiClient(opts.server);
4369
- const sender = resolveSenderAgent("envelope", opts.server, opts.fromDid);
4161
+ const sender = resolveSenderAgent("envelope", opts.server, opts.fromDid, opts.from);
4370
4162
  if (!opts.json) {
4371
- console.log(import_chalk11.default.dim(`Server: ${api.serverUrl}`));
4372
- console.log(import_chalk11.default.dim(`Signer: ${sender.did}`));
4373
- console.log(import_chalk11.default.dim(`Event: ${eventId}`));
4163
+ console.log(import_chalk12.default.dim(`Server: ${api.serverUrl}`));
4164
+ console.log(import_chalk12.default.dim(`Signer: ${sender.did}`));
4165
+ console.log(import_chalk12.default.dim(`Event: ${eventId}`));
4374
4166
  }
4375
4167
  const signer = makeSigner(sender);
4376
4168
  const event = await api.getEvent(sender.did, eventId, signer);
@@ -4379,43 +4171,43 @@ async function runEnvelope(eventId, opts) {
4379
4171
  return;
4380
4172
  }
4381
4173
  console.log("");
4382
- console.log(import_chalk11.default.bold("Envelope:"));
4174
+ console.log(import_chalk12.default.bold("Envelope:"));
4383
4175
  console.log(formatJson(event));
4384
4176
  console.log("");
4385
4177
  console.log(formatHints(event));
4386
4178
  }
4387
4179
  function formatHints(event) {
4388
4180
  const lines = [];
4389
- lines.push(`${import_chalk11.default.dim("relationshipId:")} ${import_chalk11.default.cyan(event.relationshipId)}`);
4390
- lines.push(`${import_chalk11.default.dim("serverEventHash:")} ${import_chalk11.default.cyan(event.serverEventHash)}`);
4391
- lines.push(`${import_chalk11.default.dim("eventId:")} ${import_chalk11.default.cyan(event.eventId)}`);
4392
- lines.push(`${import_chalk11.default.dim("relationshipEventIndex:")} ${import_chalk11.default.cyan(String(event.relationshipEventIndex))}`);
4181
+ lines.push(`${import_chalk12.default.dim("relationshipId:")} ${import_chalk12.default.cyan(event.relationshipId)}`);
4182
+ lines.push(`${import_chalk12.default.dim("serverEventHash:")} ${import_chalk12.default.cyan(event.serverEventHash)}`);
4183
+ lines.push(`${import_chalk12.default.dim("eventId:")} ${import_chalk12.default.cyan(event.eventId)}`);
4184
+ lines.push(`${import_chalk12.default.dim("relationshipEventIndex:")} ${import_chalk12.default.cyan(String(event.relationshipEventIndex))}`);
4393
4185
  return lines.join("\n");
4394
4186
  }
4395
4187
 
4396
4188
  // src/commands/escrow.ts
4397
- var import_sdk15 = require("@heyanon-arp/sdk");
4189
+ var import_sdk17 = require("@heyanon-arp/sdk");
4398
4190
  var import_utils2 = require("@noble/hashes/utils");
4399
- var import_chalk12 = __toESM(require("chalk"));
4191
+ var import_chalk13 = __toESM(require("chalk"));
4400
4192
  init_api();
4401
4193
 
4402
4194
  // src/commands/escrow-actions.ts
4403
4195
  var import_node_crypto = require("crypto");
4404
- var import_sdk14 = require("@heyanon-arp/sdk");
4405
- var import_web33 = require("@solana/web3.js");
4196
+ var import_sdk16 = require("@heyanon-arp/sdk");
4197
+ var import_web32 = require("@solana/web3.js");
4406
4198
  init_api();
4407
4199
  var FEE_BUFFER_LAMPORTS = 10000000n;
4408
4200
  async function setup(cmd, delegationIdArg, opts) {
4409
- const agent = resolveSenderAgent(cmd, opts.server, opts.fromDid);
4201
+ const agent = resolveSenderAgent(cmd, opts.server, opts.fromDid, opts.from);
4410
4202
  const keypair = keypairFromAgent(agent);
4411
4203
  const api = new ArpApiClient(opts.server);
4412
- const programId = new import_web33.PublicKey(await resolveProgramIdStrict(api, opts, cmd));
4204
+ const programId = new import_web32.PublicKey(await resolveProgramIdStrict(api, opts, cmd));
4413
4205
  const rpcUrl = resolveRpcUrlStrict(opts, cmd);
4414
- const conn = new import_web33.Connection(rpcUrl, "confirmed");
4206
+ const conn = new import_web32.Connection(rpcUrl, "confirmed");
4415
4207
  const delegationId = normaliseDelegationId(delegationIdArg);
4416
- const fetched = await fetchLockAccount(conn, programId, delegationId);
4208
+ const fetched = await (0, import_sdk9.fetchLockAccount)(conn, programId, delegationId);
4417
4209
  if (!fetched) {
4418
- const lockPda = deriveLockPda(programId, (0, import_sdk14.deriveLockId)(delegationId)).toBase58();
4210
+ const lockPda = (0, import_sdk9.deriveLockPda)(programId, (0, import_sdk16.deriveLockId)(delegationId)).toBase58();
4419
4211
  throw new Error(
4420
4212
  `${cmd}: no on-chain Lock for delegation ${delegationId} (PDA ${lockPda} not found on ${rpcUrl}). Either the buyer hasn't funded yet (delegation fund \u2192 server relays create_lock), or you're pointing at the wrong cluster/program.`
4421
4213
  );
@@ -4440,10 +4232,10 @@ function nowSecs() {
4440
4232
  function deadlinePassed(ctx) {
4441
4233
  return ctx.lock.expiry > 0n && nowSecs() >= ctx.lock.expiry;
4442
4234
  }
4443
- var SYSTEM_PROGRAM_B58 = import_sdk14.SYSTEM_PROGRAM_ID_BASE58;
4235
+ var SYSTEM_PROGRAM_B58 = import_sdk16.SYSTEM_PROGRAM_ID_BASE58;
4444
4236
  function effectiveFeeRecipient(lock) {
4445
- if (lock.feeRecipientAtLock !== SYSTEM_PROGRAM_B58) return new import_web33.PublicKey(lock.feeRecipientAtLock);
4446
- if (lock.treasuryAtLock && lock.treasuryAtLock !== SYSTEM_PROGRAM_B58) return new import_web33.PublicKey(lock.treasuryAtLock);
4237
+ if (lock.feeRecipientAtLock !== SYSTEM_PROGRAM_B58) return new import_web32.PublicKey(lock.feeRecipientAtLock);
4238
+ if (lock.treasuryAtLock && lock.treasuryAtLock !== SYSTEM_PROGRAM_B58) return new import_web32.PublicKey(lock.treasuryAtLock);
4447
4239
  throw new Error(
4448
4240
  "escrow: this lock snapshots the system program as BOTH fee_recipient and treasury \u2014 no writable fee account exists; the on-chain Config was initialized inconsistently."
4449
4241
  );
@@ -4461,7 +4253,7 @@ async function preflightLamports(ctx, stake, what) {
4461
4253
  }
4462
4254
  }
4463
4255
  async function sendIx(ctx, ix) {
4464
- const tx = new import_web33.Transaction().add(ix);
4256
+ const tx = new import_web32.Transaction().add(ix);
4465
4257
  tx.feePayer = ctx.keypair.publicKey;
4466
4258
  const { blockhash, lastValidBlockHeight } = await ctx.conn.getLatestBlockhash("confirmed");
4467
4259
  tx.recentBlockhash = blockhash;
@@ -4502,28 +4294,28 @@ function emit(ctx, action, signature, extra = {}) {
4502
4294
  }
4503
4295
  async function acceptHandler(delegationId, opts) {
4504
4296
  const ctx = await setup("escrow accept", delegationId, opts);
4505
- requireState(ctx, [import_sdk14.LockStates.CREATED], "Accept is only possible before any other transition; if it shows in_progress you already accepted.");
4297
+ requireState(ctx, [import_sdk16.LockStates.CREATED], "Accept is only possible before any other transition; if it shows in_progress you already accepted.");
4506
4298
  requireSigner(ctx, "payee", ctx.lock.payee);
4507
4299
  const stake = ctx.lock.workerStakeAtLock;
4508
4300
  await preflightLamports(ctx, stake, `the worker stake (${stake} lamports, returned when the lock settles in your favour)`);
4509
4301
  progress(ctx.opts.json, `accepting lock ${ctx.lock.lockId.slice(0, 16)}\u2026 \u2014 staking ${stake} lamports from ${ctx.keypair.publicKey.toBase58()}`);
4510
- const sig = await sendIx(ctx, buildAcceptLockIx({ programId: ctx.programId, lockId: ctx.lockId, payee: ctx.keypair.publicKey }));
4302
+ const sig = await sendIx(ctx, (0, import_sdk9.buildAcceptLockIx)({ programId: ctx.programId, lockId: ctx.lockId, payee: ctx.keypair.publicKey }));
4511
4303
  emit(ctx, "accept", sig, { worker_stake: stake.toString() });
4512
4304
  }
4513
4305
  async function submitWorkHandler(delegationId, opts) {
4514
4306
  const ctx = await setup("escrow submit-work", delegationId, opts);
4515
- requireState(ctx, [import_sdk14.LockStates.IN_PROGRESS], "Submit needs an accepted lock ('created' \u2192 run `heyarp escrow accept` first; terminal \u2192 the cycle already ended).");
4307
+ requireState(ctx, [import_sdk16.LockStates.IN_PROGRESS], "Submit needs an accepted lock ('created' \u2192 run `heyarp escrow accept` first; terminal \u2192 the cycle already ended).");
4516
4308
  requireSigner(ctx, "payee", ctx.lock.payee);
4517
4309
  if (deadlinePassed(ctx)) {
4518
4310
  throw new Error(
4519
4311
  `escrow submit-work: the work window expired at ${expiryIso(ctx)} \u2014 the chain will reject submit_work and the buyer can claim the escrow back (claim_expired_work). Nothing to salvage on-chain.`
4520
4312
  );
4521
4313
  }
4522
- const sig = await sendIx(ctx, buildSubmitWorkIx({ programId: ctx.programId, lockId: ctx.lockId, payee: ctx.keypair.publicKey }));
4314
+ const sig = await sendIx(ctx, (0, import_sdk9.buildSubmitWorkIx)({ programId: ctx.programId, lockId: ctx.lockId, payee: ctx.keypair.publicKey }));
4523
4315
  let reviewDeadline = null;
4524
4316
  try {
4525
- const fresh = await fetchLockAccount(ctx.conn, ctx.programId, ctx.delegationId);
4526
- if (fresh && fresh.lock.state === import_sdk14.LockStates.SUBMITTED && fresh.lock.expiry > 0n) {
4317
+ const fresh = await (0, import_sdk9.fetchLockAccount)(ctx.conn, ctx.programId, ctx.delegationId);
4318
+ if (fresh && fresh.lock.state === import_sdk16.LockStates.SUBMITTED && fresh.lock.expiry > 0n) {
4527
4319
  reviewDeadline = new Date(Number(fresh.lock.expiry) * 1e3).toISOString();
4528
4320
  }
4529
4321
  } catch {
@@ -4536,34 +4328,34 @@ async function submitWorkHandler(delegationId, opts) {
4536
4328
  }
4537
4329
  async function claimHandler(delegationId, opts) {
4538
4330
  const ctx = await setup("escrow claim", delegationId, opts);
4539
- requireState(ctx, [import_sdk14.LockStates.SUBMITTED], "Claim needs submitted work ('in_progress' \u2192 the worker must `escrow submit-work` first; 'paid' \u2192 already claimed).");
4331
+ requireState(ctx, [import_sdk16.LockStates.SUBMITTED], "Claim needs submitted work ('in_progress' \u2192 the worker must `escrow submit-work` first; 'paid' \u2192 already claimed).");
4540
4332
  const me = ctx.keypair.publicKey.toBase58();
4541
4333
  let role;
4542
4334
  if (me === ctx.lock.payer) {
4543
- role = import_sdk14.EscrowReleaseMethods.BUYER_APPROVED;
4335
+ role = import_sdk16.EscrowReleaseMethods.BUYER_APPROVED;
4544
4336
  } else if (me === ctx.lock.payee) {
4545
4337
  if (!deadlinePassed(ctx)) {
4546
4338
  throw new Error(
4547
4339
  `escrow claim: the review window is still open (until ${expiryIso(ctx)}). As the worker you can self-claim only AFTER it lapses; before that the buyer must approve (or dispute).`
4548
4340
  );
4549
4341
  }
4550
- role = import_sdk14.EscrowReleaseMethods.REVIEW_TIMEOUT;
4342
+ role = import_sdk16.EscrowReleaseMethods.REVIEW_TIMEOUT;
4551
4343
  } else {
4552
4344
  throw new Error(`escrow claim: your settlement key ${me} is neither the payer (${ctx.lock.payer}) nor the payee (${ctx.lock.payee}) of this lock.`);
4553
4345
  }
4554
4346
  progress(
4555
4347
  ctx.opts.json,
4556
- role === import_sdk14.EscrowReleaseMethods.BUYER_APPROVED ? "approving payment as the buyer \u2014 this RELEASES the escrow and is irreversible" : "self-claiming after review timeout"
4348
+ role === import_sdk16.EscrowReleaseMethods.BUYER_APPROVED ? "approving payment as the buyer \u2014 this RELEASES the escrow and is irreversible" : "self-claiming after review timeout"
4557
4349
  );
4558
4350
  const sig = await sendIx(
4559
4351
  ctx,
4560
- buildClaimWorkPaymentIx({
4352
+ (0, import_sdk9.buildClaimWorkPaymentIx)({
4561
4353
  programId: ctx.programId,
4562
4354
  lockId: ctx.lockId,
4563
4355
  authority: ctx.keypair.publicKey,
4564
- payer: new import_web33.PublicKey(ctx.lock.payer),
4565
- payee: new import_web33.PublicKey(ctx.lock.payee),
4566
- mint: ctx.lock.isNative ? null : new import_web33.PublicKey(ctx.lock.mint),
4356
+ payer: new import_web32.PublicKey(ctx.lock.payer),
4357
+ payee: new import_web32.PublicKey(ctx.lock.payee),
4358
+ mint: ctx.lock.isNative ? null : new import_web32.PublicKey(ctx.lock.mint),
4567
4359
  feeRecipient: effectiveFeeRecipient(ctx.lock)
4568
4360
  })
4569
4361
  );
@@ -4571,40 +4363,40 @@ async function claimHandler(delegationId, opts) {
4571
4363
  }
4572
4364
  async function cancelHandler(delegationId, opts) {
4573
4365
  const ctx = await setup("escrow cancel", delegationId, opts);
4574
- requireState(ctx, [import_sdk14.LockStates.CREATED], "Cancel is the pre-accept exit only \u2014 once the worker accepted ('in_progress') the windows model governs.");
4366
+ requireState(ctx, [import_sdk16.LockStates.CREATED], "Cancel is the pre-accept exit only \u2014 once the worker accepted ('in_progress') the windows model governs.");
4575
4367
  requireSigner(ctx, "payer", ctx.lock.payer);
4576
4368
  const sig = await sendIx(
4577
4369
  ctx,
4578
- buildCancelLockIx({
4370
+ (0, import_sdk9.buildCancelLockIx)({
4579
4371
  programId: ctx.programId,
4580
4372
  lockId: ctx.lockId,
4581
4373
  payer: ctx.keypair.publicKey,
4582
- mint: ctx.lock.isNative ? null : new import_web33.PublicKey(ctx.lock.mint)
4374
+ mint: ctx.lock.isNative ? null : new import_web32.PublicKey(ctx.lock.mint)
4583
4375
  })
4584
4376
  );
4585
4377
  emit(ctx, "cancel", sig, { refunded_amount: ctx.lock.amount.toString() });
4586
4378
  }
4587
4379
  async function claimExpiredHandler(delegationId, opts) {
4588
4380
  const ctx = await setup("escrow claim-expired", delegationId, opts);
4589
- requireState(ctx, [import_sdk14.LockStates.IN_PROGRESS], "Claim-expired recovers an accepted-but-never-submitted lock; 'submitted' work goes through claim/dispute instead.");
4381
+ requireState(ctx, [import_sdk16.LockStates.IN_PROGRESS], "Claim-expired recovers an accepted-but-never-submitted lock; 'submitted' work goes through claim/dispute instead.");
4590
4382
  requireSigner(ctx, "payer", ctx.lock.payer);
4591
4383
  if (!deadlinePassed(ctx)) {
4592
4384
  throw new Error(`escrow claim-expired: the work window is still open (until ${expiryIso(ctx)}). The worker can still submit; the chain will reject this claim until then.`);
4593
4385
  }
4594
4386
  const sig = await sendIx(
4595
4387
  ctx,
4596
- buildClaimExpiredWorkIx({
4388
+ (0, import_sdk9.buildClaimExpiredWorkIx)({
4597
4389
  programId: ctx.programId,
4598
4390
  lockId: ctx.lockId,
4599
4391
  payer: ctx.keypair.publicKey,
4600
- mint: ctx.lock.isNative ? null : new import_web33.PublicKey(ctx.lock.mint)
4392
+ mint: ctx.lock.isNative ? null : new import_web32.PublicKey(ctx.lock.mint)
4601
4393
  })
4602
4394
  );
4603
4395
  emit(ctx, "claim-expired", sig, { refunded_amount: ctx.lock.amount.toString(), worker_stake_forfeited: ctx.lock.workerStakeAtLock.toString() });
4604
4396
  }
4605
4397
  async function disputeOpenHandler(delegationId, opts) {
4606
4398
  const ctx = await setup("escrow dispute open", delegationId, opts);
4607
- requireState(ctx, [import_sdk14.LockStates.SUBMITTED], "Disputes open against SUBMITTED work, inside the review window.");
4399
+ requireState(ctx, [import_sdk16.LockStates.SUBMITTED], "Disputes open against SUBMITTED work, inside the review window.");
4608
4400
  requireSigner(ctx, "payer", ctx.lock.payer);
4609
4401
  if (deadlinePassed(ctx)) {
4610
4402
  throw new Error(
@@ -4614,12 +4406,12 @@ async function disputeOpenHandler(delegationId, opts) {
4614
4406
  const stake = ctx.lock.workerStakeAtLock;
4615
4407
  await preflightLamports(ctx, stake, `the dispute stake (${stake} lamports \u2014 returned if the operator rules for you or the dispute times out)`);
4616
4408
  progress(ctx.opts.json, `opening dispute \u2014 staking ${stake} lamports; the operator has the dispute window to rule, after that either party can close`);
4617
- const sig = await sendIx(ctx, buildOpenDisputeIx({ programId: ctx.programId, lockId: ctx.lockId, payer: ctx.keypair.publicKey }));
4409
+ const sig = await sendIx(ctx, (0, import_sdk9.buildOpenDisputeIx)({ programId: ctx.programId, lockId: ctx.lockId, payer: ctx.keypair.publicKey }));
4618
4410
  emit(ctx, "dispute-open", sig, { buyer_stake: stake.toString() });
4619
4411
  }
4620
4412
  async function disputeCloseHandler(delegationId, opts) {
4621
4413
  const ctx = await setup("escrow dispute close", delegationId, opts);
4622
- requireState(ctx, [import_sdk14.LockStates.DISPUTING], "Close only applies to an OPEN dispute that the operator never resolved.");
4414
+ requireState(ctx, [import_sdk16.LockStates.DISPUTING], "Close only applies to an OPEN dispute that the operator never resolved.");
4623
4415
  const me = ctx.keypair.publicKey.toBase58();
4624
4416
  if (me !== ctx.lock.payer && me !== ctx.lock.payee) {
4625
4417
  throw new Error(`escrow dispute close: your settlement key ${me} is neither party of this lock.`);
@@ -4631,20 +4423,20 @@ async function disputeCloseHandler(delegationId, opts) {
4631
4423
  }
4632
4424
  const sig = await sendIx(
4633
4425
  ctx,
4634
- buildCloseDisputeIx({
4426
+ (0, import_sdk9.buildCloseDisputeIx)({
4635
4427
  programId: ctx.programId,
4636
4428
  lockId: ctx.lockId,
4637
4429
  authority: ctx.keypair.publicKey,
4638
- payer: new import_web33.PublicKey(ctx.lock.payer),
4639
- payee: new import_web33.PublicKey(ctx.lock.payee),
4640
- mint: ctx.lock.isNative ? null : new import_web33.PublicKey(ctx.lock.mint)
4430
+ payer: new import_web32.PublicKey(ctx.lock.payer),
4431
+ payee: new import_web32.PublicKey(ctx.lock.payee),
4432
+ mint: ctx.lock.isNative ? null : new import_web32.PublicKey(ctx.lock.mint)
4641
4433
  })
4642
4434
  );
4643
4435
  emit(ctx, "dispute-close", sig, {});
4644
4436
  }
4645
4437
  async function disputeResolveHandler(delegationId, opts) {
4646
4438
  const ctx = await setup("escrow dispute resolve", delegationId, opts);
4647
- requireState(ctx, [import_sdk14.LockStates.DISPUTING], "Resolve only applies to an OPEN dispute, inside the dispute window.");
4439
+ requireState(ctx, [import_sdk16.LockStates.DISPUTING], "Resolve only applies to an OPEN dispute, inside the dispute window.");
4648
4440
  if (deadlinePassed(ctx)) {
4649
4441
  throw new Error(
4650
4442
  `escrow dispute resolve: the dispute window lapsed at ${expiryIso(ctx)} \u2014 the chain rejects late rulings (LockExpired); either party can now \`escrow dispute close\` instead.`
@@ -4663,15 +4455,15 @@ async function disputeResolveHandler(delegationId, opts) {
4663
4455
  const disputeId = Uint8Array.from(Buffer.from(disputeUuid.replace(/-/g, ""), "hex"));
4664
4456
  const sig = await sendIx(
4665
4457
  ctx,
4666
- buildResolveDisputeIx({
4458
+ (0, import_sdk9.buildResolveDisputeIx)({
4667
4459
  programId: ctx.programId,
4668
4460
  lockId: ctx.lockId,
4669
4461
  operator: ctx.keypair.publicKey,
4670
- payer: new import_web33.PublicKey(ctx.lock.payer),
4671
- winner: new import_web33.PublicKey(winner),
4462
+ payer: new import_web32.PublicKey(ctx.lock.payer),
4463
+ winner: new import_web32.PublicKey(winner),
4672
4464
  feeRecipient: effectiveFeeRecipient(ctx.lock),
4673
- treasury: new import_web33.PublicKey(ctx.lock.treasuryAtLock),
4674
- mint: ctx.lock.isNative ? null : new import_web33.PublicKey(ctx.lock.mint),
4465
+ treasury: new import_web32.PublicKey(ctx.lock.treasuryAtLock),
4466
+ mint: ctx.lock.isNative ? null : new import_web32.PublicKey(ctx.lock.mint),
4675
4467
  args: { isPayerWinner, reasonHash, disputeId }
4676
4468
  })
4677
4469
  );
@@ -4679,16 +4471,16 @@ async function disputeResolveHandler(delegationId, opts) {
4679
4471
  }
4680
4472
  async function showHandler(delegationId, opts) {
4681
4473
  const api = new ArpApiClient(opts.server);
4682
- const programId = new import_web33.PublicKey(await resolveProgramIdStrict(api, opts, "escrow show"));
4474
+ const programId = new import_web32.PublicKey(await resolveProgramIdStrict(api, opts, "escrow show"));
4683
4475
  const rpcUrl = resolveRpcUrlStrict(opts, "escrow show");
4684
- const conn = new import_web33.Connection(rpcUrl, "confirmed");
4476
+ const conn = new import_web32.Connection(rpcUrl, "confirmed");
4685
4477
  const normalised = normaliseDelegationId(delegationId);
4686
- const fetched = await fetchLockAccount(conn, programId, normalised);
4478
+ const fetched = await (0, import_sdk9.fetchLockAccount)(conn, programId, normalised);
4687
4479
  if (!fetched) {
4688
4480
  jsonOut({
4689
4481
  delegation_id: normalised.slice("del_".length),
4690
4482
  lock_exists: false,
4691
- lock_pda: deriveLockPda(programId, (0, import_sdk14.deriveLockId)(normalised)).toBase58(),
4483
+ lock_pda: (0, import_sdk9.deriveLockPda)(programId, (0, import_sdk16.deriveLockId)(normalised)).toBase58(),
4692
4484
  rpc_url: redactRpcUrl(rpcUrl)
4693
4485
  });
4694
4486
  return;
@@ -4713,7 +4505,34 @@ async function showHandler(delegationId, opts) {
4713
4505
  });
4714
4506
  }
4715
4507
  function sharedFlags(cmd) {
4716
- return cmd.option("--server <url>", "Override ARP server base URL (program-id discovery)").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--rpc-url <url>", "Solana RPC URL (STRICT: flag > ARP_ESCROW_RPC_URL env > `heyarp config rpcUrl`; no public fallback for state-changing txs)").option("--program-id <pubkey>", "Escrow program id (STRICT: flag > env > server discovery; no hardcoded fallback)").option("--json", "Machine-readable JSON output", false);
4508
+ return cmd.option("--server <url>", "Override ARP server base URL (program-id discovery)").option("--from-did <did>", "Sender 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("--rpc-url <url>", "Solana RPC URL (STRICT: flag > ARP_ESCROW_RPC_URL env > `heyarp config rpcUrl`; no public fallback for state-changing txs)").option("--program-id <pubkey>", "Escrow program id (STRICT: flag > env > server discovery; no hardcoded fallback)").option("--json", "Machine-readable JSON output", false);
4509
+ }
4510
+ async function disputeShowHandler(delegationId, opts) {
4511
+ const delId = delegationId.replace(/^del_/, "");
4512
+ const api = new ArpApiClient(opts.server);
4513
+ const sender = resolveSenderAgent("escrow dispute show", opts.server, opts.fromDid, opts.from);
4514
+ const row = await api.getDisputeResolution(delId, makeSigner(sender));
4515
+ progress(opts.json, `Server: ${api.serverUrl}`);
4516
+ progress(opts.json, `Signer: ${sender.did}`);
4517
+ if (opts.json) {
4518
+ jsonOut(row);
4519
+ return;
4520
+ }
4521
+ const winner = row.winnerRole === "payer" ? "BUYER (payer)" : row.winnerRole === "payee" ? "WORKER (payee)" : "(undecided)";
4522
+ console.log("");
4523
+ console.log(`Dispute resolution \u2014 delegation ${row.delegationId}`);
4524
+ console.log(` status: ${row.status}`);
4525
+ console.log(` winner: ${winner}${row.winnerDid ? ` ${row.winnerDid}` : ""}`);
4526
+ console.log(` is_payer_winner: ${row.isPayerWinner}`);
4527
+ console.log(` source: ${row.verdictSource ?? "(none)"} policy: ${row.policyId ?? "(none)"}`);
4528
+ console.log(` snapshot_hash: ${row.snapshotHash ?? "(none)"}`);
4529
+ console.log(` reason_hash: ${row.reasonHashHex ?? "(none)"}`);
4530
+ console.log(` resolve tx: ${row.solanaSignature ?? "(none)"}`);
4531
+ console.log(` attempts: ${row.attempts}${row.lastError ? ` last_error: ${row.lastError}` : ""}`);
4532
+ console.log("\n reasoning:");
4533
+ console.log(
4534
+ (row.reasoning ?? "(none)").split("\n").map((l) => ` ${l}`).join("\n")
4535
+ );
4717
4536
  }
4718
4537
  function registerEscrowActionCommands(escrow) {
4719
4538
  sharedFlags(
@@ -4749,6 +4568,9 @@ function registerEscrowActionCommands(escrow) {
4749
4568
  "OPERATOR: rule the dispute (winner takes the escrow; stakes split per config). Requires the on-chain-registered operator key. Disputing \u2192 DisputeResolved."
4750
4569
  ).option("--payer-wins", "Rule for the buyer").option("--payee-wins", "Rule for the worker").option("--reason <text>", "Resolution reasoning \u2014 sha256 recorded on-chain as reason_hash")
4751
4570
  ).action(disputeResolveHandler);
4571
+ dispute.command("show <delegation-id>").description(
4572
+ "Read the arbiter's verdict for a disputed delegation \u2014 winner + DID, source (llm | objective_fallback), reasoning, status, resolve tx. Signed server read; parties only."
4573
+ ).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("--json", "Machine-readable JSON output", false).action(disputeShowHandler);
4752
4574
  sharedFlags(escrow.command("show <delegation-id>").description("Decode + print the on-chain Lock account (state, parties, amounts, rolling deadline). Read-only.")).action(
4753
4575
  showHandler
4754
4576
  );
@@ -4765,13 +4587,13 @@ function registerEscrowCommands(root) {
4765
4587
  "Compute canonical condition_hash (32-byte hex) for `heyarp wallet create-lock --condition-hash <hex>` from the DELEGATION terms. Projects the flags to the canonical subset and hashes via SDK deriveDelegationConditionHash \u2014 no server fetch. The SAME terms MUST go into `delegation offer` or the server rejects the lock (ESC_LOCK_CONDITION_HASH_MISMATCH)."
4766
4588
  ).requiredOption("--delegation-id <id>", "Delegation UUID this lock binds (drives the on-chain lock_id + the condition_hash identity binding)").requiredOption("--scope <text>", "scope_summary \u2014 short prose describing the agreed work").option(
4767
4589
  "--currency <s>",
4768
- `Asset identifier bound into the hash: shorthand (${import_sdk15.WELL_KNOWN_ASSET_KEYS.join("|")}) OR raw CAIP-19 string. Optional but must match the offer's --currency.`
4769
- ).option("--currency-decimals <n>", "Decimal places (0-18). Required only when --currency is raw CAIP-19.").option("--currency-symbol <s>", 'Optional UI hint ("USDC", "SOL"). Max 16 chars.').option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--json", "Machine-readable JSON: {delegation_id, condition_hash_hex, projected_subset}", false).action(async (opts) => {
4590
+ `Asset identifier bound into the hash: shorthand (${import_sdk17.WELL_KNOWN_ASSET_KEYS.join("|")}) OR raw CAIP-19 string. Optional but must match the offer's --currency.`
4591
+ ).option("--currency-decimals <n>", "Decimal places (0-18). Required only when --currency is raw CAIP-19.").option("--currency-symbol <s>", 'Optional UI hint ("USDC", "SOL"). Max 16 chars.').option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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 JSON: {delegation_id, condition_hash_hex, projected_subset}", false).action(async (opts) => {
4770
4592
  await runDeriveConditionHash(opts);
4771
4593
  });
4772
4594
  cmd.command("recover-sequence").description(
4773
4595
  "Repair a desynced local `lastSenderSequence` after a post-commit failure the CLI couldn't auto-classify (e.g. `INTERNAL_SERVER_ERROR` from the global Internal filter \u2014 pre-/post-commit origin is ambiguous, so auto-advance is unsafe). Queries the server's owner-only `/sender-sequence` endpoint and compares; with --apply, updates local agent state to match. Default is dry-run \u2014 prints the diff and exits 0 if in-sync, 1 if drift detected."
4774
- ).option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--apply", "Apply the fix (write the server-known value to local state). Default: dry-run.", false).option("--json", "Machine-readable JSON: {local, server, drift, applied}", false).action(async (opts) => {
4596
+ ).option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--apply", "Apply the fix (write the server-known value to local state). Default: dry-run.", false).option("--json", "Machine-readable JSON: {local, server, drift, applied}", false).action(async (opts) => {
4775
4597
  await runRecoverSequence(opts);
4776
4598
  });
4777
4599
  }
@@ -4779,7 +4601,7 @@ async function runEscrowInfo(opts) {
4779
4601
  const api = new ArpApiClient(opts.server);
4780
4602
  const status = await api.getEscrowConfig();
4781
4603
  if (opts.json) {
4782
- progress(true, import_chalk12.default.dim(`Server: ${api.serverUrl}`));
4604
+ progress(true, import_chalk13.default.dim(`Server: ${api.serverUrl}`));
4783
4605
  jsonOut(status);
4784
4606
  } else {
4785
4607
  console.log(formatEscrowConfigStatus(api.serverUrl, status));
@@ -4788,35 +4610,35 @@ async function runEscrowInfo(opts) {
4788
4610
  function formatEscrowConfigStatus(serverUrl, s) {
4789
4611
  const lines = [];
4790
4612
  const win = (secs) => secs % 3600 === 0 ? `${secs / 3600}h` : secs % 60 === 0 ? `${secs / 60}m` : `${secs}s`;
4791
- lines.push(`${import_chalk12.default.dim("Server:")} ${serverUrl}`);
4792
- lines.push(`${import_chalk12.default.dim("Program ID:")} ${s.programId}`);
4793
- lines.push(`${import_chalk12.default.dim("Admin:")} ${s.admin}`);
4794
- lines.push(`${import_chalk12.default.dim("Treasury:")} ${s.treasury}`);
4795
- lines.push(`${import_chalk12.default.dim("Paused:")} ${s.paused ? import_chalk12.default.yellow("YES (new locks rejected)") : import_chalk12.default.green("no")}`);
4613
+ lines.push(`${import_chalk13.default.dim("Server:")} ${serverUrl}`);
4614
+ lines.push(`${import_chalk13.default.dim("Program ID:")} ${s.programId}`);
4615
+ lines.push(`${import_chalk13.default.dim("Admin:")} ${s.admin}`);
4616
+ lines.push(`${import_chalk13.default.dim("Treasury:")} ${s.treasury}`);
4617
+ lines.push(`${import_chalk13.default.dim("Paused:")} ${s.paused ? import_chalk13.default.yellow("YES (new locks rejected)") : import_chalk13.default.green("no")}`);
4796
4618
  lines.push("");
4797
- lines.push(import_chalk12.default.bold("Windows (rolling deadlines):"));
4798
- lines.push(` ${import_chalk12.default.dim("work:")} ${win(s.workWindowSecs)} ${import_chalk12.default.dim("(accept \u2192 submit_work)")}`);
4799
- lines.push(` ${import_chalk12.default.dim("review:")} ${win(s.reviewWindowSecs)} ${import_chalk12.default.dim("(submit_work \u2192 buyer approve / worker self-claim)")}`);
4800
- lines.push(` ${import_chalk12.default.dim("dispute:")} ${win(s.disputeWindowSecs)} ${import_chalk12.default.dim("(open_dispute \u2192 operator resolve / timeout close)")}`);
4619
+ lines.push(import_chalk13.default.bold("Windows (rolling deadlines):"));
4620
+ lines.push(` ${import_chalk13.default.dim("work:")} ${win(s.workWindowSecs)} ${import_chalk13.default.dim("(accept \u2192 submit_work)")}`);
4621
+ lines.push(` ${import_chalk13.default.dim("review:")} ${win(s.reviewWindowSecs)} ${import_chalk13.default.dim("(submit_work \u2192 buyer approve / worker self-claim)")}`);
4622
+ lines.push(` ${import_chalk13.default.dim("dispute:")} ${win(s.disputeWindowSecs)} ${import_chalk13.default.dim("(open_dispute \u2192 operator resolve / timeout close)")}`);
4801
4623
  lines.push("");
4802
- lines.push(import_chalk12.default.bold("Stakes:"));
4803
- lines.push(` ${import_chalk12.default.dim("worker stake:")} ${s.workerStakeLamports} lamports ${import_chalk12.default.dim("(escrowed at accept_lock, returned on completion)")}`);
4804
- lines.push(` ${import_chalk12.default.dim("operator dispute fee:")} ${s.operatorDisputeFeeLamports} lamports`);
4624
+ lines.push(import_chalk13.default.bold("Stakes:"));
4625
+ lines.push(` ${import_chalk13.default.dim("worker stake:")} ${s.workerStakeLamports} lamports ${import_chalk13.default.dim("(escrowed at accept_lock, returned on completion)")}`);
4626
+ lines.push(` ${import_chalk13.default.dim("operator dispute fee:")} ${s.operatorDisputeFeeLamports} lamports`);
4805
4627
  lines.push("");
4806
- lines.push(import_chalk12.default.bold("Protocol fee:"));
4628
+ lines.push(import_chalk13.default.bold("Protocol fee:"));
4807
4629
  if (!s.feeEnabled || s.feeBps === 0) {
4808
- lines.push(` ${import_chalk12.default.green("DISABLED")}`);
4809
- lines.push(` ${import_chalk12.default.dim("fee_bps:")} ${s.feeBps}`);
4810
- lines.push(` ${import_chalk12.default.dim("fee_recipient:")} ${s.feeRecipient}`);
4630
+ lines.push(` ${import_chalk13.default.green("DISABLED")}`);
4631
+ lines.push(` ${import_chalk13.default.dim("fee_bps:")} ${s.feeBps}`);
4632
+ lines.push(` ${import_chalk13.default.dim("fee_recipient:")} ${s.feeRecipient}`);
4811
4633
  lines.push("");
4812
- lines.push(import_chalk12.default.dim(` New locks will snapshot fee_bps=0 \u2014 payee receives 100% on claim.`));
4634
+ lines.push(import_chalk13.default.dim(` New locks will snapshot fee_bps=0 \u2014 payee receives 100% on claim.`));
4813
4635
  } else {
4814
4636
  const pct = (s.feeBps / 100).toFixed(2);
4815
- lines.push(` ${import_chalk12.default.yellow("ENABLED")} \u2014 ${pct}% of payee slice (${s.feeBps} bps)`);
4816
- lines.push(` ${import_chalk12.default.dim("fee_recipient:")} ${s.feeRecipient}`);
4637
+ lines.push(` ${import_chalk13.default.yellow("ENABLED")} \u2014 ${pct}% of payee slice (${s.feeBps} bps)`);
4638
+ lines.push(` ${import_chalk13.default.dim("fee_recipient:")} ${s.feeRecipient}`);
4817
4639
  lines.push("");
4818
- lines.push(import_chalk12.default.dim(` New locks will snapshot fee_bps=${s.feeBps} onto themselves.`));
4819
- lines.push(import_chalk12.default.dim(` Existing locks keep their lock-time snapshot \u2014 no retroactive change.`));
4640
+ lines.push(import_chalk13.default.dim(` New locks will snapshot fee_bps=${s.feeBps} onto themselves.`));
4641
+ lines.push(import_chalk13.default.dim(` Existing locks keep their lock-time snapshot \u2014 no retroactive change.`));
4820
4642
  }
4821
4643
  return lines.join("\n");
4822
4644
  }
@@ -4840,11 +4662,11 @@ async function runDeriveConditionHash(opts) {
4840
4662
  throw new Error(`${cmdName}: --scope is required (binds scope_summary into the condition_hash)`);
4841
4663
  }
4842
4664
  const api = new ArpApiClient(opts.server);
4843
- const sender = resolveSenderAgent(cmdName, opts.server, opts.fromDid);
4844
- progress(opts.json, import_chalk12.default.dim(`Server: ${api.serverUrl}`));
4845
- progress(opts.json, import_chalk12.default.dim(`Signer: ${sender.did}`));
4665
+ const sender = resolveSenderAgent(cmdName, opts.server, opts.fromDid, opts.from);
4666
+ progress(opts.json, import_chalk13.default.dim(`Server: ${api.serverUrl}`));
4667
+ progress(opts.json, import_chalk13.default.dim(`Signer: ${sender.did}`));
4846
4668
  const subset = projectDelegationForHash(cmdName, opts, delegationId);
4847
- const hashBytes = (0, import_sdk15.deriveDelegationConditionHash)(subset);
4669
+ const hashBytes = (0, import_sdk17.deriveDelegationConditionHash)(subset);
4848
4670
  const hex = (0, import_utils2.bytesToHex)(hashBytes);
4849
4671
  if (opts.json) {
4850
4672
  jsonOut({
@@ -4854,14 +4676,14 @@ async function runDeriveConditionHash(opts) {
4854
4676
  });
4855
4677
  return;
4856
4678
  }
4857
- console.log(import_chalk12.default.dim(`Delegation: ${delegationId}`));
4858
- console.log(import_chalk12.default.dim("Subset hashed:"));
4859
- console.log(import_chalk12.default.dim(` scopeSummary: ${subset.scopeSummary ?? "(unset)"}`));
4860
- if (subset.currency !== void 0) console.log(import_chalk12.default.dim(` currency.asset_id: ${subset.currency.asset_id}`));
4679
+ console.log(import_chalk13.default.dim(`Delegation: ${delegationId}`));
4680
+ console.log(import_chalk13.default.dim("Subset hashed:"));
4681
+ console.log(import_chalk13.default.dim(` scopeSummary: ${subset.scopeSummary ?? "(unset)"}`));
4682
+ if (subset.currency !== void 0) console.log(import_chalk13.default.dim(` currency.asset_id: ${subset.currency.asset_id}`));
4861
4683
  console.log("");
4862
- console.log(`${import_chalk12.default.bold("condition_hash:")} ${hex}`);
4684
+ console.log(`${import_chalk13.default.bold("condition_hash:")} ${hex}`);
4863
4685
  console.log("");
4864
- console.log(import_chalk12.default.dim(`Pass to: heyarp wallet create-lock --delegation-id ${delegationId} --condition-hash ${hex} ...`));
4686
+ console.log(import_chalk13.default.dim(`Pass to: heyarp wallet create-lock --delegation-id ${delegationId} --condition-hash ${hex} ...`));
4865
4687
  }
4866
4688
  function classifyRecoverOutcome(local, server) {
4867
4689
  if (local === server) return { kind: "in-sync", value: local };
@@ -4869,7 +4691,7 @@ function classifyRecoverOutcome(local, server) {
4869
4691
  return { kind: "ahead", local, server, drift: local - server };
4870
4692
  }
4871
4693
  async function runRecoverSequence(opts) {
4872
- const sender = resolveSenderAgent("escrow recover-sequence", opts.server, opts.fromDid);
4694
+ const sender = resolveSenderAgent("escrow recover-sequence", opts.server, opts.fromDid, opts.from);
4873
4695
  const signer = makeSigner(sender);
4874
4696
  const api = new ArpApiClient(opts.server);
4875
4697
  const local = sender.lastSenderSequence ?? 0;
@@ -4894,43 +4716,43 @@ async function runRecoverSequence(opts) {
4894
4716
  applied: opts.apply === true && outcome.kind === "behind"
4895
4717
  });
4896
4718
  } else {
4897
- console.log(import_chalk12.default.dim(`DID: ${sender.did}`));
4898
- console.log(import_chalk12.default.dim(`Server: ${api.serverUrl}`));
4719
+ console.log(import_chalk13.default.dim(`DID: ${sender.did}`));
4720
+ console.log(import_chalk13.default.dim(`Server: ${api.serverUrl}`));
4899
4721
  console.log("");
4900
- console.log(`${import_chalk12.default.bold("Local lastSenderSequence:")} ${local}`);
4901
- console.log(`${import_chalk12.default.bold("Server lastSenderSequence:")} ${server}`);
4722
+ console.log(`${import_chalk13.default.bold("Local lastSenderSequence:")} ${local}`);
4723
+ console.log(`${import_chalk13.default.bold("Server lastSenderSequence:")} ${server}`);
4902
4724
  console.log("");
4903
4725
  if (outcome.kind === "in-sync") {
4904
- console.log(import_chalk12.default.green("\u2713 In sync \u2014 no recovery needed."));
4726
+ console.log(import_chalk13.default.green("\u2713 In sync \u2014 no recovery needed."));
4905
4727
  } else if (outcome.kind === "behind") {
4906
- console.log(import_chalk12.default.yellow(`\u26A0 Local is BEHIND by ${outcome.drift}. Server has accepted envelopes the CLI didn't classify as post-commit.`));
4728
+ console.log(import_chalk13.default.yellow(`\u26A0 Local is BEHIND by ${outcome.drift}. Server has accepted envelopes the CLI didn't classify as post-commit.`));
4907
4729
  if (opts.apply) {
4908
- console.log(import_chalk12.default.dim("Writing server value to local state..."));
4730
+ console.log(import_chalk13.default.dim("Writing server value to local state..."));
4909
4731
  } else {
4910
- console.log(import_chalk12.default.dim("Dry-run. Pass --apply to update local state to match server."));
4732
+ console.log(import_chalk13.default.dim("Dry-run. Pass --apply to update local state to match server."));
4911
4733
  }
4912
4734
  } else {
4913
- console.log(import_chalk12.default.red(`\u2717 Local is AHEAD of server by ${outcome.drift}. This should not happen under normal protocol flow.`));
4914
- console.log(import_chalk12.default.dim("NOT applying \u2014 manual investigation needed. Possible causes:"));
4915
- console.log(import_chalk12.default.dim(" - Local agents.json edited by hand to a wrong value"));
4916
- console.log(import_chalk12.default.dim(" - Server data lost / rolled back"));
4917
- console.log(import_chalk12.default.dim(" - HEYARP_HOME pointed at a wrong account"));
4735
+ console.log(import_chalk13.default.red(`\u2717 Local is AHEAD of server by ${outcome.drift}. This should not happen under normal protocol flow.`));
4736
+ console.log(import_chalk13.default.dim("NOT applying \u2014 manual investigation needed. Possible causes:"));
4737
+ console.log(import_chalk13.default.dim(" - Local agents.json edited by hand to a wrong value"));
4738
+ console.log(import_chalk13.default.dim(" - Server data lost / rolled back"));
4739
+ console.log(import_chalk13.default.dim(" - HEYARP_HOME pointed at a wrong account"));
4918
4740
  }
4919
4741
  }
4920
4742
  if (outcome.kind === "behind" && opts.apply) {
4921
4743
  updateAgentLocal(opts.server, sender.did, { lastSenderSequence: outcome.server });
4922
- if (!opts.json) console.log(import_chalk12.default.green(`\u2713 Local lastSenderSequence updated: ${local} \u2192 ${outcome.server}`));
4744
+ if (!opts.json) console.log(import_chalk13.default.green(`\u2713 Local lastSenderSequence updated: ${local} \u2192 ${outcome.server}`));
4923
4745
  }
4924
4746
  if (outcome.kind === "behind" && !opts.apply) process.exitCode = 1;
4925
4747
  if (outcome.kind === "ahead") process.exitCode = 2;
4926
4748
  }
4927
4749
 
4928
4750
  // src/commands/events.ts
4929
- var import_sdk16 = require("@heyanon-arp/sdk");
4930
- var import_chalk13 = __toESM(require("chalk"));
4751
+ var import_sdk18 = require("@heyanon-arp/sdk");
4752
+ var import_chalk14 = __toESM(require("chalk"));
4931
4753
  init_api();
4932
4754
  function registerEventsCommand(root) {
4933
- root.command("events").description("List events for a relationship (chain order, ascending index)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--since <n>", "Cursor: only events with relationshipEventIndex >= since").option("--limit <n>", "Max events to return (1..100)", "20").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option(
4755
+ root.command("events").description("List events for a relationship (chain order, ascending index)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--since <n>", "Cursor: only events with relationshipEventIndex >= since").option("--limit <n>", "Max events 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(
4934
4756
  "--verbose",
4935
4757
  'After the summary table, print a framed "Full event payloads (N rows)" block \u2014 each event labelled with full eventId + serverEventHash and dumped as JSON. Mutually exclusive with --json.',
4936
4758
  false
@@ -4969,16 +4791,16 @@ async function runEvents(relationshipId, opts) {
4969
4791
  const limit = parseLimit3(opts.limit);
4970
4792
  const since = parseSince(opts.since);
4971
4793
  const api = new ArpApiClient(opts.server);
4972
- const sender = resolveSenderAgent("events", opts.server, opts.fromDid);
4794
+ const sender = resolveSenderAgent("events", opts.server, opts.fromDid, opts.from);
4973
4795
  if (!opts.json) {
4974
- console.log(import_chalk13.default.dim(`Server: ${api.serverUrl}`));
4975
- console.log(import_chalk13.default.dim(`Signer: ${sender.did}`));
4976
- console.log(import_chalk13.default.dim(`Relationship: ${relationshipId}`));
4796
+ console.log(import_chalk14.default.dim(`Server: ${api.serverUrl}`));
4797
+ console.log(import_chalk14.default.dim(`Signer: ${sender.did}`));
4798
+ console.log(import_chalk14.default.dim(`Relationship: ${relationshipId}`));
4977
4799
  }
4978
4800
  const query = { limit };
4979
4801
  if (since !== void 0) query.since = since;
4980
- if (opts.successOnly) query.readModelStatus = import_sdk16.ReadModelStatuses.MATERIALIZED;
4981
- else if (opts.rejectedOnly) query.readModelStatus = import_sdk16.ReadModelStatuses.REJECTED;
4802
+ if (opts.successOnly) query.readModelStatus = import_sdk18.ReadModelStatuses.MATERIALIZED;
4803
+ else if (opts.rejectedOnly) query.readModelStatus = import_sdk18.ReadModelStatuses.REJECTED;
4982
4804
  const signer = makeSigner(sender);
4983
4805
  const events = await api.listEvents(relationshipId, signer, query);
4984
4806
  if (opts.json) {
@@ -4986,7 +4808,7 @@ async function runEvents(relationshipId, opts) {
4986
4808
  return;
4987
4809
  }
4988
4810
  if (events.length === 0) {
4989
- console.log(import_chalk13.default.dim("\n(no events for this relationship)"));
4811
+ console.log(import_chalk14.default.dim("\n(no events for this relationship)"));
4990
4812
  return;
4991
4813
  }
4992
4814
  console.log("");
@@ -5002,20 +4824,20 @@ async function runEvents(relationshipId, opts) {
5002
4824
  }));
5003
4825
  }
5004
4826
  const lastIndex = events[events.length - 1].relationshipEventIndex;
5005
- console.log(import_chalk13.default.dim(`
4827
+ console.log(import_chalk14.default.dim(`
5006
4828
  ${events.length} event(s). Paginate with --since ${lastIndex + 1}.`));
5007
4829
  }
5008
4830
  function formatEventLine(ev, selfDid, opts = {}) {
5009
- const idx = import_chalk13.default.bold(`#${ev.relationshipEventIndex}`);
4831
+ const idx = import_chalk14.default.bold(`#${ev.relationshipEventIndex}`);
5010
4832
  const eventId = opts.fullIds ? ev.eventId : eventIdHead(ev.eventId);
5011
4833
  const type = ev.type.padEnd(20);
5012
4834
  const direction = directionLabel(ev, selfDid, opts);
5013
4835
  const hash = opts.fullIds ? ev.serverEventHash : hashHead(ev.serverEventHash);
5014
4836
  const extra = extraDetail(ev);
5015
- const tail = extra ? ` ${import_chalk13.default.dim(`(${extra})`)}` : "";
5016
- const status = ev.readModelStatus ?? import_sdk16.ReadModelStatuses.MATERIALIZED;
5017
- const statusGlyph = status === import_sdk16.ReadModelStatuses.REJECTED ? `${import_chalk13.default.red("\u2717")} ` : " ";
5018
- return `${statusGlyph}${idx} ${import_chalk13.default.cyan(eventId)} ${type} ${direction} ${import_chalk13.default.cyan(hash)}${tail}`;
4837
+ const tail = extra ? ` ${import_chalk14.default.dim(`(${extra})`)}` : "";
4838
+ const status = ev.readModelStatus ?? import_sdk18.ReadModelStatuses.MATERIALIZED;
4839
+ const statusGlyph = status === import_sdk18.ReadModelStatuses.REJECTED ? `${import_chalk14.default.red("\u2717")} ` : " ";
4840
+ return `${statusGlyph}${idx} ${import_chalk14.default.cyan(eventId)} ${type} ${direction} ${import_chalk14.default.cyan(hash)}${tail}`;
5019
4841
  }
5020
4842
  function eventIdHead(eventId) {
5021
4843
  if (eventId.length <= 20) return eventId;
@@ -5024,9 +4846,9 @@ function eventIdHead(eventId) {
5024
4846
  function directionLabel(ev, selfDid, opts = {}) {
5025
4847
  const senderHead = opts.fullIds ? ev.senderDid : didHead2(ev.senderDid);
5026
4848
  const recipientHead = opts.fullIds ? ev.recipientDid : didHead2(ev.recipientDid);
5027
- if (ev.senderDid === selfDid) return `${import_chalk13.default.bold("me")} \u2192 ${import_chalk13.default.dim(recipientHead)}`;
5028
- if (ev.recipientDid === selfDid) return `${import_chalk13.default.dim(senderHead)} \u2192 ${import_chalk13.default.bold("me")}`;
5029
- return `${import_chalk13.default.dim(senderHead)} \u2192 ${import_chalk13.default.dim(recipientHead)}`;
4849
+ if (ev.senderDid === selfDid) return `${import_chalk14.default.bold("me")} \u2192 ${import_chalk14.default.dim(recipientHead)}`;
4850
+ if (ev.recipientDid === selfDid) return `${import_chalk14.default.dim(senderHead)} \u2192 ${import_chalk14.default.bold("me")}`;
4851
+ return `${import_chalk14.default.dim(senderHead)} \u2192 ${import_chalk14.default.dim(recipientHead)}`;
5030
4852
  }
5031
4853
  function extraDetail(ev) {
5032
4854
  if (ev.type === "handshake_response") {
@@ -5063,7 +4885,7 @@ function parseSince(raw) {
5063
4885
  }
5064
4886
 
5065
4887
  // src/commands/guide.ts
5066
- var import_chalk14 = __toESM(require("chalk"));
4888
+ var import_chalk15 = __toESM(require("chalk"));
5067
4889
 
5068
4890
  // src/guide/source.ts
5069
4891
  var GUIDE_TITLE = "HeyARP CLI \u2014 agent guide";
@@ -5597,7 +5419,7 @@ var GUIDE_SECTIONS = [
5597
5419
  " 1. heyarp login link this CLI to your Solana wallet \u2014 hand the",
5598
5420
  " printed URL to your HUMAN operator (browser",
5599
5421
  " approval; registration REQUIRES it)",
5600
- " 2. heyarp register create your DID + Ed25519 keys",
5422
+ " 2. heyarp register --name <handle> create your DID + Ed25519 keys (handle: unique, lowercase a-z0-9_ 3-32, immutable \u2014 others can address you by it instead of your DID, e.g. `send-handshake <handle>`; `heyarp whois <handle>` resolves it)",
5601
5423
  " 3. heyarp whoami confirm your DID + login account are set",
5602
5424
  " 4. role for THIS deal: you SEND the offer \u2192 buyer; an offer ARRIVES \u2192 worker",
5603
5425
  " 5. BUYER only \u2014 fund your settlement wallet: `whoami --local` \u2192",
@@ -5704,7 +5526,7 @@ function renderCommand(c) {
5704
5526
  ${c.description}`;
5705
5527
  }
5706
5528
  function renderSection(s) {
5707
- const lines = [import_chalk14.default.bold(s.title)];
5529
+ const lines = [import_chalk15.default.bold(s.title)];
5708
5530
  if (s.body && s.body.length > 0) lines.push(...s.body);
5709
5531
  if (s.nextActions && s.nextActions.length > 0) {
5710
5532
  lines.push(" Commands:");
@@ -5731,21 +5553,21 @@ function modeHeader(mode) {
5731
5553
  ""
5732
5554
  ];
5733
5555
  case "role":
5734
- return [import_chalk14.default.dim(`(${mode.role} guide \u2014 your slice only; run \`heyarp guide\` for the overview)`), ""];
5556
+ return [import_chalk15.default.dim(`(${mode.role} guide \u2014 your slice only; run \`heyarp guide\` for the overview)`), ""];
5735
5557
  case "setup":
5736
- return [import_chalk14.default.dim("(setup \u2014 role-agnostic; run `heyarp guide` for the overview)"), ""];
5558
+ return [import_chalk15.default.dim("(setup \u2014 role-agnostic; run `heyarp guide` for the overview)"), ""];
5737
5559
  case "troubleshoot":
5738
- return [import_chalk14.default.dim("(troubleshooting \u2014 role-agnostic)"), ""];
5560
+ return [import_chalk15.default.dim("(troubleshooting \u2014 role-agnostic)"), ""];
5739
5561
  }
5740
5562
  }
5741
5563
  function modeFooter(mode) {
5742
5564
  if (mode.kind === "overview") {
5743
- return ["", import_chalk14.default.dim("Full reference per role: `heyarp guide --role worker|buyer`. Docs: https://www.npmjs.com/package/@heyanon-arp/cli")];
5565
+ return ["", import_chalk15.default.dim("Full reference per role: `heyarp guide --role worker|buyer`. Docs: https://www.npmjs.com/package/@heyanon-arp/cli")];
5744
5566
  }
5745
5567
  return [];
5746
5568
  }
5747
5569
  function renderGuide(mode = { kind: "overview" }) {
5748
- const blocks = [import_chalk14.default.bold(GUIDE_TITLE), "", ...modeHeader(mode)];
5570
+ const blocks = [import_chalk15.default.bold(GUIDE_TITLE), "", ...modeHeader(mode)];
5749
5571
  for (const s of selectSections(mode)) {
5750
5572
  blocks.push(renderSection(s), "");
5751
5573
  }
@@ -5795,7 +5617,7 @@ function renderPrompt(mode, opts = { concise: false }) {
5795
5617
  // src/commands/homes.ts
5796
5618
  var import_node_fs6 = require("fs");
5797
5619
  var import_node_path6 = require("path");
5798
- var import_chalk15 = __toESM(require("chalk"));
5620
+ var import_chalk16 = __toESM(require("chalk"));
5799
5621
  var import_prompts = __toESM(require("prompts"));
5800
5622
 
5801
5623
  // src/homes.ts
@@ -5889,27 +5711,27 @@ function runHomes(opts) {
5889
5711
  return;
5890
5712
  }
5891
5713
  if (rows.length === 0) {
5892
- console.log(import_chalk15.default.dim("(no HEYARP_HOME directories registered yet \u2014 run `heyarp register` once and the registry populates itself)"));
5893
- console.log(import_chalk15.default.dim(` registry path: ${homesRegistryPath()}`));
5714
+ console.log(import_chalk16.default.dim("(no HEYARP_HOME directories registered yet \u2014 run `heyarp register` once and the registry populates itself)"));
5715
+ console.log(import_chalk16.default.dim(` registry path: ${homesRegistryPath()}`));
5894
5716
  return;
5895
5717
  }
5896
5718
  const header = ["Path", "Agents", "Last seen", "Status"];
5897
5719
  const data = rows.map((r) => [
5898
- r.path + (r.isCurrent ? import_chalk15.default.green(" (current)") : ""),
5720
+ r.path + (r.isCurrent ? import_chalk16.default.green(" (current)") : ""),
5899
5721
  String(r.agentCount),
5900
5722
  formatRelativeTime(r.lastSeenAt),
5901
- r.exists ? import_chalk15.default.green("ok") : import_chalk15.default.red("missing")
5723
+ r.exists ? import_chalk16.default.green("ok") : import_chalk16.default.red("missing")
5902
5724
  ]);
5903
5725
  console.log("");
5904
5726
  console.log(formatTable(header, data));
5905
- console.log(import_chalk15.default.dim(`
5727
+ console.log(import_chalk16.default.dim(`
5906
5728
  Registry path: ${homesRegistryPath()}`));
5907
- console.log(import_chalk15.default.dim(`Set HEYARP_HOME=<path> in a shell to switch between homes; run \`heyarp homes forget <path>\` to drop a stale entry.`));
5729
+ console.log(import_chalk16.default.dim(`Set HEYARP_HOME=<path> in a shell to switch between homes; run \`heyarp homes forget <path>\` to drop a stale entry.`));
5908
5730
  }
5909
5731
  async function runForget(path, opts) {
5910
5732
  if (!opts.yes) {
5911
- console.log(import_chalk15.default.yellow(`About to remove '${path}' from the homes registry.`));
5912
- console.log(import_chalk15.default.dim(" Note: this only forgets the registry entry; the directory + its agents.json are NOT touched."));
5733
+ console.log(import_chalk16.default.yellow(`About to remove '${path}' from the homes registry.`));
5734
+ console.log(import_chalk16.default.dim(" Note: this only forgets the registry entry; the directory + its agents.json are NOT touched."));
5913
5735
  const answer = await (0, import_prompts.default)(
5914
5736
  {
5915
5737
  type: "confirm",
@@ -5919,21 +5741,21 @@ async function runForget(path, opts) {
5919
5741
  },
5920
5742
  {
5921
5743
  onCancel: () => {
5922
- console.log(import_chalk15.default.yellow("Aborted."));
5744
+ console.log(import_chalk16.default.yellow("Aborted."));
5923
5745
  process.exit(130);
5924
5746
  }
5925
5747
  }
5926
5748
  );
5927
5749
  if (!answer.confirm) {
5928
- console.log(import_chalk15.default.dim("Aborted (no changes)."));
5750
+ console.log(import_chalk16.default.dim("Aborted (no changes)."));
5929
5751
  return;
5930
5752
  }
5931
5753
  }
5932
5754
  const removed = forgetHome(path);
5933
5755
  if (removed) {
5934
- console.log(import_chalk15.default.green(`\u2713 forgot ${path}`));
5756
+ console.log(import_chalk16.default.green(`\u2713 forgot ${path}`));
5935
5757
  } else {
5936
- console.log(import_chalk15.default.dim(`(no entry for ${path} in the registry \u2014 already absent)`));
5758
+ console.log(import_chalk16.default.dim(`(no entry for ${path} in the registry \u2014 already absent)`));
5937
5759
  }
5938
5760
  }
5939
5761
  function countAgents(homePath) {
@@ -5958,13 +5780,13 @@ function formatTable(header, data) {
5958
5780
  const padding = " ".repeat(Math.max(0, widths[i] - lengths[i]));
5959
5781
  return cell + padding;
5960
5782
  }).join(" ");
5961
- const headerLine = import_chalk15.default.bold(
5783
+ const headerLine = import_chalk16.default.bold(
5962
5784
  pad(
5963
5785
  header,
5964
5786
  header.map((s) => s.length)
5965
5787
  )
5966
5788
  );
5967
- const sepLine = import_chalk15.default.dim(
5789
+ const sepLine = import_chalk16.default.dim(
5968
5790
  pad(
5969
5791
  widths.map((w) => "-".repeat(w)),
5970
5792
  widths
@@ -5991,7 +5813,7 @@ function formatRelativeTime(iso) {
5991
5813
  }
5992
5814
 
5993
5815
  // src/commands/inbox.ts
5994
- var import_chalk16 = __toESM(require("chalk"));
5816
+ var import_chalk17 = __toESM(require("chalk"));
5995
5817
  init_api();
5996
5818
  function formatTailStartedPing(input) {
5997
5819
  const ping = {
@@ -6009,7 +5831,7 @@ function registerInboxCommand(root) {
6009
5831
  ).argument("[did]", "Recipient DID (did:arp:...) \u2014 must have local state. Optional when --from-did is given OR exactly one agent is registered for the resolved server.").option("--server <url>", "Override ARP server base URL").option("--limit <n>", "Max events to return (1..100)", "20").option("--before <iso>", "Cursor: only events strictly OLDER than this RFC 3339 timestamp").option("--before-event-id <id>", "Tiebreaker for --before \u2014 pass the previous page's last eventId").option(
6010
5832
  "--since <iso>",
6011
5833
  "Forward cursor: only events strictly NEWER than this RFC 3339 timestamp. Polling workers persist this between iterations to skip already-handled envelopes (fixes the double-fire pattern of re-reading from the same head). Pages are returned OLDEST-FIRST when --since is used alone (so a poller can advance its watermark to the page tail without losing backlogged events); combine with --before for a newest-first range query."
6012
- ).option("--since-event-id <id>", "Tiebreaker for --since \u2014 pass the previous tick's last handled eventId. Combine with --since for same-millisecond stability.").option("--verbose", "After the table, print the full JSON envelope for each event with a per-row label that includes the full serverEventHash + eventId", false).option("--json", "Machine-readable mode \u2014 emit a single JSON array of events, no human-format summary, no chalk colors. Pipe-safe.", false).option("--full-ids", "Print sender DID and full serverEventHash in the table (no truncation). Use when you need to copy-paste either value into another command.", false).option("--from-did <did>", "Alias for the positional <did> argument \u2014 accepted for consistency with other signed commands. Must match the positional if both are given.").option(
5834
+ ).option("--since-event-id <id>", "Tiebreaker for --since \u2014 pass the previous tick's last handled eventId. Combine with --since for same-millisecond stability.").option("--verbose", "After the table, print the full JSON envelope for each event with a per-row label that includes the full serverEventHash + eventId", false).option("--json", "Machine-readable mode \u2014 emit a single JSON array of events, no human-format summary, no chalk colors. Pipe-safe.", false).option("--full-ids", "Print sender DID and full serverEventHash in the table (no truncation). Use when you need to copy-paste either value into another command.", false).option("--from-did <did>", "Alias for the positional <did> argument \u2014 accepted for consistency with other signed commands. Must match the positional if both are given.").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option(
6013
5835
  "--tail",
6014
5836
  // The polling output (`heyarp inbox --json`) emits raw
6015
5837
  // `EventPublic[]` rows with `.body` at the top level, but
@@ -6030,7 +5852,7 @@ async function runInbox(positionalDid, opts) {
6030
5852
  throw new Error(`inbox: positional <did> (${positionalDid}) and --from-did (${opts.fromDid}) disagree \u2014 pass only one`);
6031
5853
  }
6032
5854
  const explicitDid = positionalDid ?? opts.fromDid;
6033
- const local = explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("inbox", opts.server, void 0);
5855
+ const local = explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("inbox", opts.server, void 0, opts.from);
6034
5856
  const did = local.did;
6035
5857
  if (opts.tail) {
6036
5858
  await runInboxTail(did, local, opts);
@@ -6038,8 +5860,8 @@ async function runInbox(positionalDid, opts) {
6038
5860
  }
6039
5861
  const api = new ArpApiClient(opts.server);
6040
5862
  if (!opts.json) {
6041
- console.log(import_chalk16.default.dim(`Server: ${api.serverUrl}`));
6042
- console.log(import_chalk16.default.dim(`Signer: ${local.did}`));
5863
+ console.log(import_chalk17.default.dim(`Server: ${api.serverUrl}`));
5864
+ console.log(import_chalk17.default.dim(`Signer: ${local.did}`));
6043
5865
  }
6044
5866
  const query = { limit };
6045
5867
  if (opts.before) query.before = opts.before;
@@ -6053,7 +5875,7 @@ async function runInbox(positionalDid, opts) {
6053
5875
  return;
6054
5876
  }
6055
5877
  if (events.length === 0) {
6056
- console.log(import_chalk16.default.dim("\n(no events addressed to me \u2014 `heyarp events <relationship-id>` shows the chain-wide listing)"));
5878
+ console.log(import_chalk17.default.dim("\n(no events addressed to me \u2014 `heyarp events <relationship-id>` shows the chain-wide listing)"));
6057
5879
  return;
6058
5880
  }
6059
5881
  console.log("");
@@ -6068,16 +5890,16 @@ async function runInbox(positionalDid, opts) {
6068
5890
  secondary: `eventId=${ev.eventId} serverEventHash=${ev.serverEventHash}`
6069
5891
  }));
6070
5892
  }
6071
- const addressedToMeHint = import_chalk16.default.dim(" (envelopes addressed to me \u2014 for the full chain see `heyarp events <relationship-id>`)");
5893
+ const addressedToMeHint = import_chalk17.default.dim(" (envelopes addressed to me \u2014 for the full chain see `heyarp events <relationship-id>`)");
6072
5894
  if (opts.since && !opts.before) {
6073
5895
  console.log(
6074
- import_chalk16.default.dim(
5896
+ import_chalk17.default.dim(
6075
5897
  `
6076
5898
  ${events.length} event(s) (oldest-first).${addressedToMeHint} Advance the forward cursor with --since <serverTimestamp> --since-event-id <eventId> using the LAST row above.`
6077
5899
  )
6078
5900
  );
6079
5901
  } else {
6080
- console.log(import_chalk16.default.dim(`
5902
+ console.log(import_chalk17.default.dim(`
6081
5903
  ${events.length} event(s).${addressedToMeHint} Paginate with --before <serverTimestamp> --before-event-id <eventId> using the LAST row above.`));
6082
5904
  }
6083
5905
  }
@@ -6092,7 +5914,7 @@ async function runInboxTail(did, local, opts) {
6092
5914
  } else {
6093
5915
  warn(
6094
5916
  opts.json,
6095
- import_chalk16.default.yellow(
5917
+ import_chalk17.default.yellow(
6096
5918
  "\u26A0 inbox --tail: stdout is piped but `process.stdout._handle.setBlocking` is unavailable in this Node runtime. Buffered writes may delay event delivery. Fall back to polling (`heyarp inbox --json`) if events stop arriving."
6097
5919
  )
6098
5920
  );
@@ -6102,9 +5924,9 @@ async function runInboxTail(did, local, opts) {
6102
5924
  if (opts.json) {
6103
5925
  console.log(formatTailStartedPing({ server: api.serverUrl, signer: local.did, stdoutBlockingApplied }));
6104
5926
  } else {
6105
- console.log(import_chalk16.default.dim(`Server: ${api.serverUrl}`));
6106
- console.log(import_chalk16.default.dim(`Signer: ${local.did}`));
6107
- console.log(import_chalk16.default.dim("Mode: --tail (live SSE, Ctrl-C to stop)"));
5927
+ console.log(import_chalk17.default.dim(`Server: ${api.serverUrl}`));
5928
+ console.log(import_chalk17.default.dim(`Signer: ${local.did}`));
5929
+ console.log(import_chalk17.default.dim("Mode: --tail (live SSE, Ctrl-C to stop)"));
6108
5930
  }
6109
5931
  const controller = new AbortController();
6110
5932
  let userAborted = false;
@@ -6123,7 +5945,7 @@ async function runInboxTail(did, local, opts) {
6123
5945
  }
6124
5946
  if (event.type === "heartbeat") continue;
6125
5947
  if (event.type === "connected") {
6126
- console.log(import_chalk16.default.green("\u25CF stream open \u2014 listening for envelopes..."));
5948
+ console.log(import_chalk17.default.green("\u25CF stream open \u2014 listening for envelopes..."));
6127
5949
  continue;
6128
5950
  }
6129
5951
  if (event.type === "envelope") {
@@ -6137,7 +5959,7 @@ async function runInboxTail(did, local, opts) {
6137
5959
  }
6138
5960
  continue;
6139
5961
  }
6140
- console.log(import_chalk16.default.dim(`(unknown event: ${event.type})`));
5962
+ console.log(import_chalk17.default.dim(`(unknown event: ${event.type})`));
6141
5963
  }
6142
5964
  if (!userAborted) {
6143
5965
  throw new Error("inbox --tail: stream ended unexpectedly (server may have restarted, or change stream errored). Re-run to reconnect.");
@@ -6145,7 +5967,7 @@ async function runInboxTail(did, local, opts) {
6145
5967
  } catch (err) {
6146
5968
  const name = err.name;
6147
5969
  if (name === "AbortError" || userAborted) {
6148
- if (!opts.json) console.log(import_chalk16.default.dim("\nstream closed."));
5970
+ if (!opts.json) console.log(import_chalk17.default.dim("\nstream closed."));
6149
5971
  return;
6150
5972
  }
6151
5973
  throw err;
@@ -6165,15 +5987,15 @@ function formatInboxTable(events, opts = {}) {
6165
5987
  ]);
6166
5988
  const widths = header.map((h, i) => Math.max(h.length, ...data.map((row) => row[i].length)));
6167
5989
  const pad = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(" ");
6168
- const lines = [import_chalk16.default.bold(pad(header)), import_chalk16.default.dim(pad(widths.map((w) => "-".repeat(w)))), ...data.map((row) => pad(row))];
6169
- const detail = events.map((ev) => ` ${import_chalk16.default.dim("eventId:")} ${import_chalk16.default.cyan(ev.eventId)} ${import_chalk16.default.dim("serverTimestamp:")} ${import_chalk16.default.cyan(ev.serverTimestamp)}`).join("\n");
5990
+ const lines = [import_chalk17.default.bold(pad(header)), import_chalk17.default.dim(pad(widths.map((w) => "-".repeat(w)))), ...data.map((row) => pad(row))];
5991
+ const detail = events.map((ev) => ` ${import_chalk17.default.dim("eventId:")} ${import_chalk17.default.cyan(ev.eventId)} ${import_chalk17.default.dim("serverTimestamp:")} ${import_chalk17.default.cyan(ev.serverTimestamp)}`).join("\n");
6170
5992
  return `${lines.join("\n")}
6171
5993
 
6172
- ${import_chalk16.default.bold("Pagination cursors")} (last \u2192 first):
5994
+ ${import_chalk17.default.bold("Pagination cursors")} (last \u2192 first):
6173
5995
  ${detail}`;
6174
5996
  }
6175
5997
  function hashHead2(hash) {
6176
- if (!hash) return import_chalk16.default.dim("(none)");
5998
+ if (!hash) return import_chalk17.default.dim("(none)");
6177
5999
  if (hash.length <= 14) return hash;
6178
6000
  return `${hash.slice(0, 14)}...`;
6179
6001
  }
@@ -6189,8 +6011,8 @@ function parseLimit4(raw) {
6189
6011
  // src/commands/keys.ts
6190
6012
  var import_node_crypto2 = require("crypto");
6191
6013
  var import_node_fs7 = require("fs");
6192
- var import_sdk17 = require("@heyanon-arp/sdk");
6193
- var import_chalk17 = __toESM(require("chalk"));
6014
+ var import_sdk19 = require("@heyanon-arp/sdk");
6015
+ var import_chalk18 = __toESM(require("chalk"));
6194
6016
  function writeSecretFile(path, body) {
6195
6017
  const tmp = `${path}.tmp.${(0, import_node_crypto2.randomBytes)(8).toString("hex")}`;
6196
6018
  const fd = (0, import_node_fs7.openSync)(tmp, "wx", 384);
@@ -6217,19 +6039,19 @@ function writeSecretFile(path, body) {
6217
6039
  function registerKeysCommand(root) {
6218
6040
  const keys = root.command("keys").description("Local key utilities");
6219
6041
  keys.command("gen").description("Generate a fresh identity + settlement keypair (no save by default)").action(() => {
6220
- const identity = (0, import_sdk17.generateKeyPair)();
6221
- const settlement = (0, import_sdk17.generateKeyPair)();
6042
+ const identity = (0, import_sdk19.generateKeyPair)();
6043
+ const settlement = (0, import_sdk19.generateKeyPair)();
6222
6044
  const out = [
6223
- import_chalk17.default.bold("Identity key (Ed25519)"),
6224
- ` public (base58btc): ${import_chalk17.default.cyan((0, import_sdk17.base58btcEncode)(identity.publicKey))}`,
6225
- ` secret (base64) : ${import_chalk17.default.yellow(Buffer.from(identity.secretKey).toString("base64"))}`,
6045
+ import_chalk18.default.bold("Identity key (Ed25519)"),
6046
+ ` public (base58btc): ${import_chalk18.default.cyan((0, import_sdk19.base58btcEncode)(identity.publicKey))}`,
6047
+ ` secret (base64) : ${import_chalk18.default.yellow(Buffer.from(identity.secretKey).toString("base64"))}`,
6226
6048
  "",
6227
- import_chalk17.default.bold("Settlement key (Ed25519)"),
6228
- ` public (base58btc): ${import_chalk17.default.cyan((0, import_sdk17.base58btcEncode)(settlement.publicKey))}`,
6229
- ` secret (base64) : ${import_chalk17.default.yellow(Buffer.from(settlement.secretKey).toString("base64"))}`,
6049
+ import_chalk18.default.bold("Settlement key (Ed25519)"),
6050
+ ` public (base58btc): ${import_chalk18.default.cyan((0, import_sdk19.base58btcEncode)(settlement.publicKey))}`,
6051
+ ` secret (base64) : ${import_chalk18.default.yellow(Buffer.from(settlement.secretKey).toString("base64"))}`,
6230
6052
  "",
6231
- import_chalk17.default.bold("Resulting DID"),
6232
- ` ${import_chalk17.default.cyan((0, import_sdk17.formatDid)(identity.publicKey))}`
6053
+ import_chalk18.default.bold("Resulting DID"),
6054
+ ` ${import_chalk18.default.cyan((0, import_sdk19.formatDid)(identity.publicKey))}`
6233
6055
  ];
6234
6056
  console.log(out.join("\n"));
6235
6057
  });
@@ -6238,20 +6060,20 @@ function registerKeysCommand(root) {
6238
6060
  const json = JSON.stringify(toKeyBundle(agent, (/* @__PURE__ */ new Date()).toISOString()), null, 2);
6239
6061
  if (opts.out) {
6240
6062
  writeSecretFile(opts.out, json);
6241
- process.stderr.write(import_chalk17.default.yellow(`\u26A0 wrote SECRET key bundle to ${opts.out} (mode 0600) \u2014 keep it offline; anyone with this file can operate ${did}.
6063
+ process.stderr.write(import_chalk18.default.yellow(`\u26A0 wrote SECRET key bundle to ${opts.out} (mode 0600) \u2014 keep it offline; anyone with this file can operate ${did}.
6242
6064
  `));
6243
6065
  console.log(opts.out);
6244
6066
  } else {
6245
- process.stderr.write(import_chalk17.default.yellow("\u26A0 this is a SECRET key bundle \u2014 redirect to a file and keep it offline.\n"));
6067
+ process.stderr.write(import_chalk18.default.yellow("\u26A0 this is a SECRET key bundle \u2014 redirect to a file and keep it offline.\n"));
6246
6068
  console.log(json);
6247
6069
  }
6248
6070
  });
6249
6071
  keys.command("whoami").description("Print the DID derived from a base64-encoded identity secret key").argument("<secret-key-b64>", "32-byte Ed25519 seed, base64").action((secretKeyB64) => {
6250
6072
  const seed = decodeSeed(secretKeyB64);
6251
- const pub = (0, import_sdk17.getPublicKey)(seed);
6252
- const did = (0, import_sdk17.formatDid)(pub);
6253
- console.log(`${import_chalk17.default.bold("DID")}: ${import_chalk17.default.cyan(did)}`);
6254
- console.log(`${import_chalk17.default.bold("Identity public key (base58btc)")}: ${import_chalk17.default.cyan((0, import_sdk17.base58btcEncode)(pub))}`);
6073
+ const pub = (0, import_sdk19.getPublicKey)(seed);
6074
+ const did = (0, import_sdk19.formatDid)(pub);
6075
+ console.log(`${import_chalk18.default.bold("DID")}: ${import_chalk18.default.cyan(did)}`);
6076
+ console.log(`${import_chalk18.default.bold("Identity public key (base58btc)")}: ${import_chalk18.default.cyan((0, import_sdk19.base58btcEncode)(pub))}`);
6255
6077
  });
6256
6078
  }
6257
6079
  function decodeSeed(b64) {
@@ -6268,7 +6090,7 @@ function decodeSeed(b64) {
6268
6090
  }
6269
6091
 
6270
6092
  // src/commands/list.ts
6271
- var import_chalk18 = __toESM(require("chalk"));
6093
+ var import_chalk19 = __toESM(require("chalk"));
6272
6094
  function registerListCommand(root) {
6273
6095
  root.command("list").description("List agents registered locally (~/.heyarp/agents.json)").option("--json", "Machine-readable mode \u2014 emit the local agents as a single JSON array on stdout ({serverUrl, did, name, tags, registeredAt}[]).", false).action((opts) => {
6274
6096
  const rows = listAgents();
@@ -6277,7 +6099,7 @@ function registerListCommand(root) {
6277
6099
  return;
6278
6100
  }
6279
6101
  if (rows.length === 0) {
6280
- console.log(import_chalk18.default.dim(`No local agents. State file: ${stateFilePath()}`));
6102
+ console.log(import_chalk19.default.dim(`No local agents. State file: ${stateFilePath()}`));
6281
6103
  return;
6282
6104
  }
6283
6105
  const grouped = /* @__PURE__ */ new Map();
@@ -6289,7 +6111,7 @@ function registerListCommand(root) {
6289
6111
  for (const [serverUrl, group] of grouped) {
6290
6112
  if (!first) console.log("");
6291
6113
  first = false;
6292
- console.log(import_chalk18.default.bold(`Server: ${serverUrl}`));
6114
+ console.log(import_chalk19.default.bold(`Server: ${serverUrl}`));
6293
6115
  console.log(formatAgentsTable(group.map(({ agent }) => ({ did: agent.did, name: agent.name, tags: agent.tags, registeredAt: agent.registeredAt }))));
6294
6116
  }
6295
6117
  });
@@ -6297,7 +6119,7 @@ function registerListCommand(root) {
6297
6119
 
6298
6120
  // src/commands/login.ts
6299
6121
  var import_node_crypto3 = require("crypto");
6300
- var import_chalk19 = __toESM(require("chalk"));
6122
+ var import_chalk20 = __toESM(require("chalk"));
6301
6123
  init_api();
6302
6124
  var POLL_INTERVAL_MS = 2e3;
6303
6125
  var POLL_TIMEOUT_MS = 11 * 6e4;
@@ -6367,9 +6189,9 @@ function registerLoginCommand(root) {
6367
6189
  jsonOut({ serverUrl: result.serverUrl, wallet: result.wallet, credentialsPath: credentialsFilePath() });
6368
6190
  } else {
6369
6191
  console.log("");
6370
- console.log(`${import_chalk19.default.green("Logged in as")} ${import_chalk19.default.cyan(result.wallet)}`);
6371
- console.log(import_chalk19.default.dim(`If that is not the wallet you approved with, run heyarp logout immediately.`));
6372
- console.log(import_chalk19.default.dim(`Credential saved to ${credentialsFilePath()} (mode 0600).`));
6192
+ console.log(`${import_chalk20.default.green("Logged in as")} ${import_chalk20.default.cyan(result.wallet)}`);
6193
+ console.log(import_chalk20.default.dim(`If that is not the wallet you approved with, run heyarp logout immediately.`));
6194
+ console.log(import_chalk20.default.dim(`Credential saved to ${credentialsFilePath()} (mode 0600).`));
6373
6195
  }
6374
6196
  } catch (err) {
6375
6197
  emitActionError(err, cmd);
@@ -6379,7 +6201,7 @@ function registerLoginCommand(root) {
6379
6201
  }
6380
6202
 
6381
6203
  // src/commands/logout.ts
6382
- var import_chalk20 = __toESM(require("chalk"));
6204
+ var import_chalk21 = __toESM(require("chalk"));
6383
6205
  init_api();
6384
6206
  function registerLogoutCommand(root) {
6385
6207
  root.command("logout").description("Log out of the ARP server: revoke the stored CLI auth token (best-effort) and delete the local credential for this server.").option("--server <url>", "Override ARP server base URL").option("--json", "machine-readable output ({ serverUrl, loggedOut, wallet? })", false).action(async (opts, cmd) => {
@@ -6404,7 +6226,7 @@ function registerLogoutCommand(root) {
6404
6226
  if (opts.json) {
6405
6227
  jsonOut({ serverUrl: api.serverUrl, loggedOut: true, wallet: credential.wallet });
6406
6228
  } else {
6407
- console.log(`${import_chalk20.default.green("Logged out of")} ${api.serverUrl} ${import_chalk20.default.dim(`(was ${credential.wallet})`)}`);
6229
+ console.log(`${import_chalk21.default.green("Logged out of")} ${api.serverUrl} ${import_chalk21.default.dim(`(was ${credential.wallet})`)}`);
6408
6230
  }
6409
6231
  } catch (err) {
6410
6232
  emitActionError(err, cmd);
@@ -6413,13 +6235,65 @@ function registerLogoutCommand(root) {
6413
6235
  });
6414
6236
  }
6415
6237
 
6238
+ // src/commands/name.ts
6239
+ var import_sdk20 = require("@heyanon-arp/sdk");
6240
+ var import_chalk22 = __toESM(require("chalk"));
6241
+ init_api();
6242
+ function registerNameCommand(root) {
6243
+ const name = root.command("name").description("Agent name (handle) utilities.");
6244
+ name.command("check").description("Check whether an agent name (handle) can be registered \u2014 reports invalid / reserved / taken / available without registering.").argument("<name>", "Candidate handle (lowercase a-z0-9_, 3-32 chars)").option("--server <url>", "Override ARP server base URL").option("--json", "Emit {name, available, reason, did?} as a single JSON object on stdout.", false).action(async (input, opts) => {
6245
+ const result = await runNameCheck(input, opts);
6246
+ if (opts.json) {
6247
+ jsonOut(result);
6248
+ } else {
6249
+ printNameCheck(input, result);
6250
+ }
6251
+ if (!result.available) process.exitCode = 1;
6252
+ });
6253
+ }
6254
+ async function runNameCheck(input, opts) {
6255
+ const name = (0, import_sdk20.normalizeName)(input);
6256
+ if (!(0, import_sdk20.isValidAgentName)(name)) {
6257
+ return { name, available: false, reason: "invalid" };
6258
+ }
6259
+ if ((0, import_sdk20.isReservedName)(name)) {
6260
+ return { name, available: false, reason: "reserved" };
6261
+ }
6262
+ const api = new ArpApiClient(opts.server);
6263
+ progress(opts.json, import_chalk22.default.dim(`Server: ${api.serverUrl}`));
6264
+ try {
6265
+ const profile = await api.discoverByName(name);
6266
+ return { name, available: false, reason: "taken", did: profile.did };
6267
+ } catch (err) {
6268
+ if (err instanceof ApiError && err.payload.code === "AGENT_NOT_FOUND") {
6269
+ return { name, available: true, reason: null };
6270
+ }
6271
+ throw err;
6272
+ }
6273
+ }
6274
+ function printNameCheck(input, r) {
6275
+ switch (r.reason) {
6276
+ case "invalid":
6277
+ console.log(`${import_chalk22.default.red("\u2717")} '${input}' is not a valid handle \u2014 must be lowercase a-z0-9_, 3-32 chars.`);
6278
+ break;
6279
+ case "reserved":
6280
+ console.log(`${import_chalk22.default.red("\u2717")} '${r.name}' is reserved and cannot be registered.`);
6281
+ break;
6282
+ case "taken":
6283
+ console.log(`${import_chalk22.default.yellow("\u2717")} '${r.name}' is taken \u2192 ${import_chalk22.default.cyan(r.did ?? "(unknown DID)")}`);
6284
+ break;
6285
+ default:
6286
+ console.log(`${import_chalk22.default.green("\u2713")} '${r.name}' is available.`);
6287
+ }
6288
+ }
6289
+
6416
6290
  // src/commands/profile.ts
6417
- var import_sdk18 = require("@heyanon-arp/sdk");
6418
- var import_chalk21 = __toESM(require("chalk"));
6291
+ var import_sdk21 = require("@heyanon-arp/sdk");
6292
+ var import_chalk23 = __toESM(require("chalk"));
6419
6293
  init_api();
6420
6294
  function registerProfileCommand(root) {
6421
6295
  root.command("profile").description("Composed agent profile: public fields + reputation + liveness, in one read.").argument("<did>", "did:arp:<base58btc> identifier").option("--server <url>", "Override ARP server base URL").option("--json", "Emit the profile as JSON on stdout.", false).action(async (did, opts) => {
6422
- if (!(0, import_sdk18.isValidDid)(did)) {
6296
+ if (!(0, import_sdk21.isValidDid)(did)) {
6423
6297
  throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
6424
6298
  }
6425
6299
  const api = new ArpApiClient(opts.server);
@@ -6430,33 +6304,33 @@ function registerProfileCommand(root) {
6430
6304
  }
6431
6305
  const j = false;
6432
6306
  const s = p.reputation.scores;
6433
- const live = p.liveness.online ? import_chalk21.default.green("\u25CF online") : import_chalk21.default.dim("\u25CB offline");
6307
+ const live = p.liveness.online ? import_chalk23.default.green("\u25CF online") : import_chalk23.default.dim("\u25CB offline");
6434
6308
  const tags = p.tags.map(sanitizeForTerminal).filter((t) => t.length > 0);
6435
- progress(j, import_chalk21.default.bold(`${p.name ? sanitizeForTerminal(p.name) : "(unnamed)"} ${import_chalk21.default.dim(p.did)}`));
6436
- if (p.description) progress(j, import_chalk21.default.dim(` ${sanitizeForTerminal(p.description)}`));
6437
- progress(j, ` ${live}${p.liveness.inboxStreamActive ? import_chalk21.default.green(" \xB7 stream attached") : ""} \xB7 last seen ${p.liveness.lastSeenAt ?? "\u2014"}`);
6438
- progress(j, ` tags: ${tags.length ? tags.join(", ") : import_chalk21.default.dim("none")}`);
6309
+ progress(j, import_chalk23.default.bold(`${p.name ? sanitizeForTerminal(p.name) : "(unnamed)"} ${import_chalk23.default.dim(p.did)}`));
6310
+ if (p.description) progress(j, import_chalk23.default.dim(` ${sanitizeForTerminal(p.description)}`));
6311
+ progress(j, ` ${live}${p.liveness.inboxStreamActive ? import_chalk23.default.green(" \xB7 stream attached") : ""} \xB7 last seen ${p.liveness.lastSeenAt ?? "\u2014"}`);
6312
+ progress(j, ` tags: ${tags.length ? tags.join(", ") : import_chalk23.default.dim("none")}`);
6439
6313
  progress(j, "");
6440
- progress(j, import_chalk21.default.bold(" Reputation") + import_chalk21.default.dim(" (informational)"));
6314
+ progress(j, import_chalk23.default.bold(" Reputation") + import_chalk23.default.dim(" (informational)"));
6441
6315
  progress(
6442
6316
  j,
6443
6317
  ` composite ${s.composite.toFixed(2)} \xB7 reliability ${s.reliability.toFixed(2)} \xB7 settlement ${s.settlement.toFixed(2)} \xB7 dispute-health ${s.disputeHealth.toFixed(2)}`
6444
6318
  );
6445
- progress(j, import_chalk21.default.dim(` ${p.reputation.computed ? `computed ${p.reputation.lastComputedAt}` : "never computed (neutral cold-start)"}`));
6319
+ progress(j, import_chalk23.default.dim(` ${p.reputation.computed ? `computed ${p.reputation.lastComputedAt}` : "never computed (neutral cold-start)"}`));
6446
6320
  });
6447
6321
  }
6448
6322
 
6449
6323
  // src/commands/receipt.ts
6450
- var import_sdk19 = require("@heyanon-arp/sdk");
6324
+ var import_sdk22 = require("@heyanon-arp/sdk");
6451
6325
  var import_shield2 = require("@heyanon-arp/shield");
6452
- var import_chalk22 = __toESM(require("chalk"));
6326
+ var import_chalk24 = __toESM(require("chalk"));
6453
6327
  init_api();
6454
6328
  function registerReceiptCommands(root) {
6455
6329
  const cmd = root.command("receipt").description("Receipt envelopes \u2014 the payee proposes a delivery record (payment consent is on-chain via claim_work_payment)");
6456
6330
  registerPropose(cmd);
6457
6331
  }
6458
6332
  function registerPropose(parent) {
6459
- parent.command("propose").description("Send a receipt envelope as the PAYEE. Row lands PROPOSED; the buyer approves payment on-chain via claim_work_payment.").argument("<recipient-did>", "Recipient agent DID (= caller / offerer of the parent delegation)").argument("<delegation-id>", "Parent delegation id (UUID, must be ACCEPTED)").argument("[request-hash]", "sha256:<64 hex> \u2014 SHA-256 of the work_request payload being settled. Omit when --auto-hashes is set.").argument("[response-hash]", "sha256:<64 hex> \u2014 SHA-256 of the work_response payload being settled. Omit when --auto-hashes is set.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--verdict <s>", "verdict_proposed (accepted | accepted_with_notes | rejected)", "accepted").option("--notes-hash <sha256>", "Optional sha256:<64 hex> notes hash").option("--deliverable-hash <sha256>", "Optional sha256:<64 hex> deliverable hash").option("--input-tokens <n>", "Optional usage.input_tokens").option("--output-tokens <n>", "Optional usage.output_tokens").option("--latency-ms <n>", "Optional usage.latency_ms").option("--model <name>", "Optional usage.model").option("--computed-amount <s>", "Optional usage.computed_amount").option("--ttl <seconds>", "Envelope TTL in seconds", "3600").option(
6333
+ parent.command("propose").description("Send a receipt envelope as the PAYEE. Row lands PROPOSED; the buyer approves payment on-chain via claim_work_payment.").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (= caller / offerer of the parent delegation)").argument("<delegation-id>", "Parent delegation id (UUID, must be ACCEPTED)").argument("[request-hash]", "sha256:<64 hex> \u2014 SHA-256 of the work_request payload being settled. Omit when --auto-hashes is set.").argument("[response-hash]", "sha256:<64 hex> \u2014 SHA-256 of the work_response payload being settled. Omit when --auto-hashes is set.").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--verdict <s>", "verdict_proposed (accepted | accepted_with_notes | rejected)", "accepted").option("--notes-hash <sha256>", "Optional sha256:<64 hex> notes hash").option("--deliverable-hash <sha256>", "Optional sha256:<64 hex> deliverable hash").option("--input-tokens <n>", "Optional usage.input_tokens").option("--output-tokens <n>", "Optional usage.output_tokens").option("--latency-ms <n>", "Optional usage.latency_ms").option("--model <name>", "Optional usage.model").option("--computed-amount <s>", "Optional usage.computed_amount").option("--ttl <seconds>", "Envelope TTL in seconds", "3600").option(
6460
6334
  "--auto-hashes",
6461
6335
  "Compute request_hash + response_hash automatically from the work-log row at (--rel-id, <delegation-id>, --request-id). Positional <request-hash>/<response-hash> become optional; if supplied they must match the computed values (consistency check). --rel-id and --request-id auto-resolve from local state when unambiguous \u2014 pass them explicitly only if the lookup finds multiple candidates.",
6462
6336
  false
@@ -6476,7 +6350,7 @@ function registerPropose(parent) {
6476
6350
  } catch (err) {
6477
6351
  emitActionError(err, cmd);
6478
6352
  if (!opts.json && err instanceof ApiError && err.payload.code === "RECEIPT_ALREADY_EXISTS") {
6479
- console.error(import_chalk22.default.dim(" This receipt already exists (a prior propose committed it). Do NOT re-propose \u2014 payment consent is on-chain (claim_work_payment)."));
6353
+ console.error(import_chalk24.default.dim(" This receipt already exists (a prior propose committed it). Do NOT re-propose \u2014 payment consent is on-chain (claim_work_payment)."));
6480
6354
  }
6481
6355
  process.exitCode = 1;
6482
6356
  }
@@ -6488,7 +6362,7 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
6488
6362
  "receipt propose: --verbose and --json are mutually exclusive. --json already emits the full server response as a structured payload; --verbose adds an envelope + response dump on top that would break `--json | jq`."
6489
6363
  );
6490
6364
  }
6491
- requireDid2("receipt propose", recipientDid, "<recipient-did>");
6365
+ recipientDid = await resolveRecipient(opts.server, "receipt propose", recipientDid, { json: opts.json });
6492
6366
  delegationId = requireUuidNormalised2("receipt propose", delegationId, "<delegation-id>");
6493
6367
  if (opts.relId) opts.relId = requireUuidNormalised2("receipt propose", opts.relId, "--rel-id");
6494
6368
  const verdict = parseVerdict("receipt propose", opts.verdict);
@@ -6497,12 +6371,12 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
6497
6371
  if (opts.deliverableHash) requireSha256("receipt propose", opts.deliverableHash, "--deliverable-hash");
6498
6372
  const usage = parseUsage("receipt propose", opts);
6499
6373
  const api = new ArpApiClient(opts.server);
6500
- const sender = resolveSenderAgent("receipt propose", opts.server, opts.fromDid);
6374
+ const sender = resolveSenderAgent("receipt propose", opts.server, opts.fromDid, opts.from);
6501
6375
  if (!opts.relId && opts.autoHashes) {
6502
6376
  opts.relId = await resolveAutoRelId(api, sender, delegationId);
6503
6377
  progress(
6504
6378
  opts.json,
6505
- import_chalk22.default.dim(`[auto-rel-id] resolved --rel-id=${opts.relId} (delegation found in exactly one of your relationships; pass --rel-id explicitly to override)`)
6379
+ import_chalk24.default.dim(`[auto-rel-id] resolved --rel-id=${opts.relId} (delegation found in exactly one of your relationships; pass --rel-id explicitly to override)`)
6506
6380
  );
6507
6381
  }
6508
6382
  if (opts.relId) {
@@ -6518,7 +6392,7 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
6518
6392
  opts.requestId = await resolveAutoRequestId(api, sender, opts.relId, delegationId);
6519
6393
  progress(
6520
6394
  opts.json,
6521
- import_chalk22.default.dim(
6395
+ import_chalk24.default.dim(
6522
6396
  `[auto-request-id] resolved --request-id=${opts.requestId} (unique 'responded' work_log under this delegation; pass --request-id explicitly to override)`
6523
6397
  )
6524
6398
  );
@@ -6537,8 +6411,8 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
6537
6411
  }
6538
6412
  requestHash = computed.requestHash;
6539
6413
  responseHash = computed.responseHash;
6540
- progress(opts.json, import_chalk22.default.dim(`[auto-hashes] request_hash: ${requestHash} (from work-log ${opts.relId}/${delegationId}/${opts.requestId})`));
6541
- progress(opts.json, import_chalk22.default.dim(`[auto-hashes] response_hash: ${responseHash}`));
6414
+ progress(opts.json, import_chalk24.default.dim(`[auto-hashes] request_hash: ${requestHash} (from work-log ${opts.relId}/${delegationId}/${opts.requestId})`));
6415
+ progress(opts.json, import_chalk24.default.dim(`[auto-hashes] response_hash: ${responseHash}`));
6542
6416
  } else {
6543
6417
  if (requestHashArg === void 0 || responseHashArg === void 0) {
6544
6418
  throw new Error("receipt propose: <request-hash> and <response-hash> are required (or pass --auto-hashes + --rel-id + --request-id to derive them from the work-log)");
@@ -6558,11 +6432,11 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
6558
6432
  if (opts.deliverableHash) content.deliverable_hash = opts.deliverableHash;
6559
6433
  if (usage) content.usage = usage;
6560
6434
  const body = { type: "receipt", content };
6561
- progress(opts.json, import_chalk22.default.dim(`Server: ${api.serverUrl}`));
6562
- progress(opts.json, import_chalk22.default.dim(`Sender (payee): ${sender.did}`));
6563
- progress(opts.json, import_chalk22.default.dim(`Recipient (caller): ${recipientDid}`));
6564
- progress(opts.json, import_chalk22.default.dim(`Delegation: ${delegationId}`));
6565
- progress(opts.json, import_chalk22.default.dim(`Verdict (proposed): ${verdict}`));
6435
+ progress(opts.json, import_chalk24.default.dim(`Server: ${api.serverUrl}`));
6436
+ progress(opts.json, import_chalk24.default.dim(`Sender (payee): ${sender.did}`));
6437
+ progress(opts.json, import_chalk24.default.dim(`Recipient (caller): ${recipientDid}`));
6438
+ progress(opts.json, import_chalk24.default.dim(`Delegation: ${delegationId}`));
6439
+ progress(opts.json, import_chalk24.default.dim(`Verdict (proposed): ${verdict}`));
6566
6440
  const result = await sendReceiptEnvelope({ api, sender, recipientDid, body, attachments: void 0, ttlSeconds, verbose: opts.verbose, server: opts.server });
6567
6441
  if (opts.json) {
6568
6442
  const json = {
@@ -6583,10 +6457,10 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
6583
6457
  return;
6584
6458
  }
6585
6459
  printIngestResult2(result);
6586
- console.log(import_chalk22.default.dim(`
6587
- Receipt event hash: ${import_chalk22.default.cyan(result.serverEventHash)}`));
6588
- console.log(import_chalk22.default.dim("Receipt recorded. Payment consent is ON-CHAIN now: the buyer approves by"));
6589
- console.log(import_chalk22.default.dim("sending claim_work_payment (or you self-claim after the review window)."));
6460
+ console.log(import_chalk24.default.dim(`
6461
+ Receipt event hash: ${import_chalk24.default.cyan(result.serverEventHash)}`));
6462
+ console.log(import_chalk24.default.dim("Receipt recorded. Payment consent is ON-CHAIN now: the buyer approves by"));
6463
+ console.log(import_chalk24.default.dim("sending claim_work_payment (or you self-claim after the review window)."));
6590
6464
  }
6591
6465
  async function assertSenderIsReceiptPayee(api, sender, relationshipId, delegationId) {
6592
6466
  const signer = makeSigner(sender);
@@ -6654,7 +6528,7 @@ async function computeWorkLogHashes(api, sender, relationshipId, delegationId, r
6654
6528
  `receipt propose --auto-hashes: no work-log row found for (relationshipId=${relationshipId}, delegationId=${delegationId}, requestId=${requestId}). Did the work_request envelope land yet?`
6655
6529
  );
6656
6530
  }
6657
- if (workLog.state !== import_sdk19.WorkLogStates.RESPONDED) {
6531
+ if (workLog.state !== import_sdk22.WorkLogStates.RESPONDED) {
6658
6532
  throw new Error(
6659
6533
  `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.`
6660
6534
  );
@@ -6670,34 +6544,34 @@ async function computeWorkLogHashes(api, sender, relationshipId, delegationId, r
6670
6544
  };
6671
6545
  const responseBody = workLog.responseOutput !== void 0 ? { type: "work_response", content: { delegation_id: workLog.delegationId, request_id: workLog.requestId, output: workLog.responseOutput } } : { type: "work_response", content: { delegation_id: workLog.delegationId, request_id: workLog.requestId, error: workLog.responseError } };
6672
6546
  return {
6673
- requestHash: (0, import_sdk19.canonicalSha256Hex)(requestBody),
6674
- responseHash: (0, import_sdk19.canonicalSha256Hex)(responseBody)
6547
+ requestHash: (0, import_sdk22.canonicalSha256Hex)(requestBody),
6548
+ responseHash: (0, import_sdk22.canonicalSha256Hex)(responseBody)
6675
6549
  };
6676
6550
  }
6677
6551
  async function sendReceiptEnvelope(args) {
6678
6552
  const nextSequence = (args.sender.lastSenderSequence ?? 0) + 1;
6679
6553
  const protectedBlock = {
6680
- protocol_version: import_sdk19.CURRENT_PROTOCOL_VERSION,
6681
- purpose: import_sdk19.Purpose.ENVELOPE,
6682
- message_id: (0, import_sdk19.uuidV4)(),
6554
+ protocol_version: import_sdk22.CURRENT_PROTOCOL_VERSION,
6555
+ purpose: import_sdk22.Purpose.ENVELOPE,
6556
+ message_id: (0, import_sdk22.uuidV4)(),
6683
6557
  sender_did: args.sender.did,
6684
6558
  recipient_did: args.recipientDid,
6685
6559
  relationship_id: null,
6686
6560
  sender_sequence: nextSequence,
6687
- sender_nonce: (0, import_sdk19.senderNonce)(),
6688
- timestamp: (0, import_sdk19.rfc3339)(),
6689
- expires_at: (0, import_sdk19.expiresAt)(args.ttlSeconds),
6561
+ sender_nonce: (0, import_sdk22.senderNonce)(),
6562
+ timestamp: (0, import_sdk22.rfc3339)(),
6563
+ expires_at: (0, import_sdk22.expiresAt)(args.ttlSeconds),
6690
6564
  delivery_id: null
6691
6565
  };
6692
6566
  const signer = makeSigner(args.sender);
6693
- const envelope = (0, import_sdk19.signEnvelope)({
6567
+ const envelope = (0, import_sdk22.signEnvelope)({
6694
6568
  protected: protectedBlock,
6695
6569
  body: args.body,
6696
6570
  identitySecretKey: signer.identitySecretKey,
6697
6571
  attachments: args.attachments
6698
6572
  });
6699
6573
  if (args.verbose) {
6700
- console.log(import_chalk22.default.bold("\nEnvelope (pre-send):"));
6574
+ console.log(import_chalk24.default.bold("\nEnvelope (pre-send):"));
6701
6575
  console.log(formatJson(envelope));
6702
6576
  }
6703
6577
  try {
@@ -6705,24 +6579,24 @@ async function sendReceiptEnvelope(args) {
6705
6579
  updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
6706
6580
  return result;
6707
6581
  } catch (err) {
6708
- if (err instanceof ApiError && (0, import_sdk19.isPostCommitErrorCode)(err.payload.code)) {
6582
+ if (err instanceof ApiError && (0, import_sdk22.isPostCommitErrorCode)(err.payload.code)) {
6709
6583
  updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
6710
6584
  }
6711
6585
  throw err;
6712
6586
  }
6713
6587
  }
6714
6588
  function printIngestResult2(result) {
6715
- console.log(import_chalk22.default.green("\nDelivered."));
6716
- console.log(`${import_chalk22.default.bold("Event id")}: ${import_chalk22.default.cyan(result.eventId)}`);
6717
- console.log(`${import_chalk22.default.bold("Relationship id")}: ${import_chalk22.default.cyan(result.relationshipId)}`);
6718
- console.log(`${import_chalk22.default.bold("Chain index")}: ${import_chalk22.default.cyan(String(result.relationshipEventIndex))}`);
6719
- console.log(`${import_chalk22.default.bold("Server timestamp")}: ${import_chalk22.default.cyan(result.serverTimestamp)}`);
6720
- console.log(`${import_chalk22.default.bold("Server event hash")}: ${import_chalk22.default.cyan(result.serverEventHash)}`);
6589
+ console.log(import_chalk24.default.green("\nDelivered."));
6590
+ console.log(`${import_chalk24.default.bold("Event id")}: ${import_chalk24.default.cyan(result.eventId)}`);
6591
+ console.log(`${import_chalk24.default.bold("Relationship id")}: ${import_chalk24.default.cyan(result.relationshipId)}`);
6592
+ console.log(`${import_chalk24.default.bold("Chain index")}: ${import_chalk24.default.cyan(String(result.relationshipEventIndex))}`);
6593
+ console.log(`${import_chalk24.default.bold("Server timestamp")}: ${import_chalk24.default.cyan(result.serverTimestamp)}`);
6594
+ console.log(`${import_chalk24.default.bold("Server event hash")}: ${import_chalk24.default.cyan(result.serverEventHash)}`);
6721
6595
  }
6722
6596
  function parseVerdict(cmdName, raw) {
6723
- if (raw === void 0 || raw === "") return import_sdk19.ReceiptVerdicts.ACCEPTED;
6724
- if (!import_sdk19.RECEIPT_VERDICTS.includes(raw)) {
6725
- throw new Error(`${cmdName}: --verdict must be one of ${import_sdk19.RECEIPT_VERDICTS.join(" | ")} (got '${raw}')`);
6597
+ if (raw === void 0 || raw === "") return import_sdk22.ReceiptVerdicts.ACCEPTED;
6598
+ if (!import_sdk22.RECEIPT_VERDICTS.includes(raw)) {
6599
+ throw new Error(`${cmdName}: --verdict must be one of ${import_sdk22.RECEIPT_VERDICTS.join(" | ")} (got '${raw}')`);
6726
6600
  }
6727
6601
  return raw;
6728
6602
  }
@@ -6759,24 +6633,19 @@ function requireUuid3(cmdName, raw, label) {
6759
6633
  requireUuid(cmdName, raw, label);
6760
6634
  }
6761
6635
  function requireSha256(cmdName, raw, label) {
6762
- if (!(0, import_sdk19.isSha256Hex)(raw)) {
6636
+ if (!(0, import_sdk22.isSha256Hex)(raw)) {
6763
6637
  throw new Error(`${cmdName}: ${label} must match 'sha256:<64 lowercase hex>' (got '${raw}')`);
6764
6638
  }
6765
6639
  }
6766
- function requireDid2(cmdName, did, label) {
6767
- if (typeof did !== "string" || !did.startsWith("did:arp:") || did.length <= "did:arp:".length) {
6768
- throw new Error(`${cmdName}: ${label} must look like 'did:arp:...' (got '${did}')`);
6769
- }
6770
- }
6771
6640
 
6772
6641
  // src/commands/receipts.ts
6773
- var import_sdk20 = require("@heyanon-arp/sdk");
6774
- var import_chalk23 = __toESM(require("chalk"));
6642
+ var import_sdk23 = require("@heyanon-arp/sdk");
6643
+ var import_chalk25 = __toESM(require("chalk"));
6775
6644
  init_api();
6776
6645
  function registerReceiptsCommand(root) {
6777
6646
  root.command("receipts").description(
6778
6647
  "List receipts for a relationship (one row per (delegationId, requestHash, responseHash), oldest-first). Receipt rows expose the chain hash as `receiptEventHash` (NOT `serverEventHash` \u2014 that field is the wider envelope identifier on `heyarp events` rows). Scripts using `--json | jq .receiptEventHash` get the value; `jq .serverEventHash` silently returns null because the row doesn't carry that key."
6779
- ).argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--delegation-id <uuid>", "Narrow to receipts 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(
6648
+ ).argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--delegation-id <uuid>", "Narrow to receipts 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(
6780
6649
  "--verbose",
6781
6650
  'After the one-line summaries, print a framed "Full receipt payloads (N rows)" block \u2014 each row labelled with full delegationId + requestHash + responseHash and dumped as JSON. Mutually exclusive with --json.',
6782
6651
  false
@@ -6792,11 +6661,11 @@ async function runReceipts(relationshipId, opts) {
6792
6661
  }
6793
6662
  const limit = parseLimit5(opts.limit);
6794
6663
  const api = new ArpApiClient(opts.server);
6795
- const sender = resolveSenderAgent("receipts", opts.server, opts.fromDid);
6664
+ const sender = resolveSenderAgent("receipts", opts.server, opts.fromDid, opts.from);
6796
6665
  if (!opts.json) {
6797
- console.log(import_chalk23.default.dim(`Server: ${api.serverUrl}`));
6798
- console.log(import_chalk23.default.dim(`Signer: ${sender.did}`));
6799
- console.log(import_chalk23.default.dim(`Relationship: ${relationshipId}`));
6666
+ console.log(import_chalk25.default.dim(`Server: ${api.serverUrl}`));
6667
+ console.log(import_chalk25.default.dim(`Signer: ${sender.did}`));
6668
+ console.log(import_chalk25.default.dim(`Relationship: ${relationshipId}`));
6800
6669
  }
6801
6670
  const query = { limit };
6802
6671
  if (opts.delegationId) query.delegationId = opts.delegationId;
@@ -6808,7 +6677,7 @@ async function runReceipts(relationshipId, opts) {
6808
6677
  return;
6809
6678
  }
6810
6679
  if (rows.length === 0) {
6811
- console.log(import_chalk23.default.dim("\n(no receipts for this relationship)"));
6680
+ console.log(import_chalk25.default.dim("\n(no receipts for this relationship)"));
6812
6681
  return;
6813
6682
  }
6814
6683
  console.log("");
@@ -6825,29 +6694,29 @@ async function runReceipts(relationshipId, opts) {
6825
6694
  }));
6826
6695
  }
6827
6696
  const lastId = rows[rows.length - 1].id;
6828
- console.log(import_chalk23.default.dim(`
6697
+ console.log(import_chalk25.default.dim(`
6829
6698
  ${rows.length} receipt row(s). Paginate with --after ${lastId}.`));
6830
6699
  }
6831
6700
  function formatReceiptLine(r, selfDid, opts = {}) {
6832
6701
  const delegationPart = opts.fullIds ? r.delegationId : idHead2(r.delegationId);
6833
6702
  const requestHashPart = opts.fullIds ? r.requestHash : hashHead3(r.requestHash);
6834
- const id = import_chalk23.default.bold(`${delegationPart}/${requestHashPart}`);
6703
+ const id = import_chalk25.default.bold(`${delegationPart}/${requestHashPart}`);
6835
6704
  const callerHead = opts.fullIds ? r.callerDid : didHead3(r.callerDid);
6836
6705
  const payeeHead = opts.fullIds ? r.payeeDid : didHead3(r.payeeDid);
6837
- const direction = r.payeeDid === selfDid ? `${import_chalk23.default.bold("me")}(payee) \u2192 ${import_chalk23.default.dim(callerHead)}` : `${import_chalk23.default.dim(payeeHead)}(payee) \u2192 ${import_chalk23.default.bold("me")}`;
6706
+ const direction = r.payeeDid === selfDid ? `${import_chalk25.default.bold("me")}(payee) \u2192 ${import_chalk25.default.dim(callerHead)}` : `${import_chalk25.default.dim(payeeHead)}(payee) \u2192 ${import_chalk25.default.bold("me")}`;
6838
6707
  const verdict = formatVerdict(r);
6839
6708
  const responseTail = opts.fullIds ? `
6840
- ${import_chalk23.default.dim("responseHash:")} ${import_chalk23.default.cyan(r.responseHash)}` : "";
6709
+ ${import_chalk25.default.dim("responseHash:")} ${import_chalk25.default.cyan(r.responseHash)}` : "";
6841
6710
  return `${id} ${direction} ${verdict}${responseTail}`;
6842
6711
  }
6843
6712
  function formatVerdict(r) {
6844
6713
  switch (r.verdictProposed) {
6845
- case import_sdk20.ReceiptVerdicts.ACCEPTED:
6846
- return import_chalk23.default.green("accepted");
6847
- case import_sdk20.ReceiptVerdicts.ACCEPTED_WITH_NOTES:
6848
- return import_chalk23.default.yellow("accepted_with_notes");
6849
- case import_sdk20.ReceiptVerdicts.REJECTED:
6850
- return import_chalk23.default.red("rejected");
6714
+ case import_sdk23.ReceiptVerdicts.ACCEPTED:
6715
+ return import_chalk25.default.green("accepted");
6716
+ case import_sdk23.ReceiptVerdicts.ACCEPTED_WITH_NOTES:
6717
+ return import_chalk25.default.yellow("accepted_with_notes");
6718
+ case import_sdk23.ReceiptVerdicts.REJECTED:
6719
+ return import_chalk25.default.red("rejected");
6851
6720
  }
6852
6721
  }
6853
6722
  function idHead2(id) {
@@ -6873,8 +6742,8 @@ function parseLimit5(raw) {
6873
6742
 
6874
6743
  // src/commands/recover.ts
6875
6744
  var import_node_fs8 = require("fs");
6876
- var import_sdk21 = require("@heyanon-arp/sdk");
6877
- var import_chalk24 = __toESM(require("chalk"));
6745
+ var import_sdk24 = require("@heyanon-arp/sdk");
6746
+ var import_chalk26 = __toESM(require("chalk"));
6878
6747
  init_api();
6879
6748
  function registerRecoverCommand(root) {
6880
6749
  root.command("recover").description(
@@ -6894,23 +6763,23 @@ async function runRecover(opts) {
6894
6763
  }
6895
6764
  const bundle = validateKeyBundle(raw);
6896
6765
  const identitySecret = new Uint8Array(Buffer.from(bundle.identitySecretKeyB64, "base64"));
6897
- const identityPub = (0, import_sdk21.base58btcDecode)(bundle.identityPublicKeyB58);
6898
- const derivedDid = (0, import_sdk21.formatDid)(identityPub);
6766
+ const identityPub = (0, import_sdk24.base58btcDecode)(bundle.identityPublicKeyB58);
6767
+ const derivedDid = (0, import_sdk24.formatDid)(identityPub);
6899
6768
  if (derivedDid !== bundle.did) {
6900
6769
  throw new Error(`recover: key file is inconsistent \u2014 its DID (${bundle.did}) does not match its identity public key (${derivedDid})`);
6901
6770
  }
6902
6771
  const probe2 = new TextEncoder().encode("heyarp-recover-keycheck");
6903
- if (!(0, import_sdk21.verify)((0, import_sdk21.sign)(probe2, identitySecret), probe2, identityPub)) {
6772
+ if (!(0, import_sdk24.verify)((0, import_sdk24.sign)(probe2, identitySecret), probe2, identityPub)) {
6904
6773
  throw new Error("recover: the identity secret key does not match the public key in this bundle");
6905
6774
  }
6906
6775
  const settlementSecret = new Uint8Array(Buffer.from(bundle.settlementSecretKeyB64, "base64"));
6907
- const settlementPub = (0, import_sdk21.base58btcDecode)(bundle.settlementPublicKeyB58);
6908
- if (!(0, import_sdk21.verify)((0, import_sdk21.sign)(probe2, settlementSecret), probe2, settlementPub)) {
6776
+ const settlementPub = (0, import_sdk24.base58btcDecode)(bundle.settlementPublicKeyB58);
6777
+ if (!(0, import_sdk24.verify)((0, import_sdk24.sign)(probe2, settlementSecret), probe2, settlementPub)) {
6909
6778
  throw new Error("recover: the settlement secret key does not match the settlement public key in this bundle");
6910
6779
  }
6911
6780
  if (bundle.ownerWallet && bundle.ownerWallet !== credential.wallet) {
6912
6781
  process.stderr.write(
6913
- import_chalk24.default.yellow(
6782
+ import_chalk26.default.yellow(
6914
6783
  `\u26A0 this bundle was exported under wallet ${bundle.ownerWallet}, but you are logged in as ${credential.wallet}. The server will reject the recover unless the agent is yours.
6915
6784
  `
6916
6785
  )
@@ -6927,7 +6796,7 @@ async function runRecover(opts) {
6927
6796
  lastSenderSequence = seq.lastSenderSequence;
6928
6797
  } catch (err) {
6929
6798
  process.stderr.write(
6930
- import_chalk24.default.yellow(
6799
+ import_chalk26.default.yellow(
6931
6800
  `\u26A0 could not read the sender sequence from the server (${err.message}). If sends are rejected as backwards, run \`heyarp escrow recover-sequence --apply\`.
6932
6801
  `
6933
6802
  )
@@ -6955,14 +6824,14 @@ async function runRecover(opts) {
6955
6824
  jsonOut({ recovered: true, did: derivedDid, name: row.name });
6956
6825
  return;
6957
6826
  }
6958
- console.log(import_chalk24.default.green(`\u2713 Recovered ${row.name ? `${row.name} ` : ""}${derivedDid} into local state \u2014 you can operate it now.`));
6827
+ console.log(import_chalk26.default.green(`\u2713 Recovered ${row.name ? `${row.name} ` : ""}${derivedDid} into local state \u2014 you can operate it now.`));
6959
6828
  }
6960
6829
 
6961
6830
  // src/commands/register.ts
6962
6831
  var import_node_crypto4 = require("crypto");
6963
6832
  var import_node_fs9 = require("fs");
6964
- var import_sdk22 = require("@heyanon-arp/sdk");
6965
- var import_chalk25 = __toESM(require("chalk"));
6833
+ var import_sdk25 = require("@heyanon-arp/sdk");
6834
+ var import_chalk27 = __toESM(require("chalk"));
6966
6835
  var import_prompts2 = __toESM(require("prompts"));
6967
6836
  init_api();
6968
6837
  init_paths();
@@ -6974,7 +6843,7 @@ function registerRegisterCommand(root) {
6974
6843
  "`--password` is REQUIRED \u2014 must be at least 8 characters. In interactive mode (--yes omitted) the CLI prompts for it; with --yes it must be passed explicitly.",
6975
6844
  "`--yes` is the non-interactive switch \u2014 every required field must arrive via flags (no prompts). Use this for scripted setups."
6976
6845
  ].join("\n")
6977
- ).option("--server <url>", "Override ARP server base URL").option("--from-keys <file>", "Load identity + settlement keys from a JSON file instead of generating").option("--name <s>", "Display name (skips the name prompt)").option("--description <s>", "Description (skips the description prompt)").option("--tag <s>", "Capability tag \u2014 repeatable, e.g. --tag translation --tag fr", accumulate3, []).option(
6846
+ ).option("--server <url>", "Override ARP server base URL").option("--from-keys <file>", "Load identity + settlement keys from a JSON file instead of generating").option("--name <s>", "Unique handle \u2014 lowercase a-z0-9_, 3-32 chars, immutable (skips the name prompt)").option("--description <s>", "Description (skips the description prompt)").option("--tag <s>", "Capability tag \u2014 repeatable, e.g. --tag translation --tag fr", accumulate3, []).option(
6978
6847
  "--password <s>",
6979
6848
  // `--password` puts the secret in `argv` — visible via
6980
6849
  // `ps aux` / kernel process table on shared hosts,
@@ -7016,44 +6885,44 @@ var defaultRegisterDeps = {
7016
6885
  async function runRegister(opts, deps = defaultRegisterDeps) {
7017
6886
  assertJsonRequiresYes(opts);
7018
6887
  const api = deps.makeApi(opts.server);
7019
- if (!opts.json) console.log(import_chalk25.default.dim(`Server: ${api.serverUrl}`));
6888
+ if (!opts.json) console.log(import_chalk27.default.dim(`Server: ${api.serverUrl}`));
7020
6889
  const credential = requireCredential("register", api.serverUrl);
7021
6890
  if (!opts.json) {
7022
6891
  warnIfAgentsAlreadyRegistered(opts.server);
7023
6892
  warnIfOrphanHomesPresent();
7024
6893
  }
7025
6894
  const keys = opts.fromKeys ? loadKeysFromFile(opts.fromKeys) : freshKeys();
7026
- const did = (0, import_sdk22.formatDid)(keys.identityPublicKey);
7027
- if (!opts.json) console.log(import_chalk25.default.dim(`DID will be: ${did}`));
6895
+ const did = (0, import_sdk25.formatDid)(keys.identityPublicKey);
6896
+ if (!opts.json) console.log(import_chalk27.default.dim(`DID will be: ${did}`));
7028
6897
  const answers = await mergeAnswers(opts);
7029
6898
  const scryptSalt = (0, import_node_crypto4.randomBytes)(16);
7030
- if (!opts.json) console.log(import_chalk25.default.dim("Deriving scrypt key, this may take a moment..."));
7031
- const scryptKey = (0, import_sdk22.deriveScryptKey)(answers.password, new Uint8Array(scryptSalt));
6899
+ if (!opts.json) console.log(import_chalk27.default.dim("Deriving scrypt key, this may take a moment..."));
6900
+ const scryptKey = (0, import_sdk25.deriveScryptKey)(answers.password, new Uint8Array(scryptSalt));
7032
6901
  const challenge = await api.issueChallenge("register");
7033
6902
  const challengeBytes = base64UrlNoPadDecode(challenge.challengeB64);
7034
6903
  if (challengeBytes.length !== 32) {
7035
6904
  throw new Error(`Server returned a ${challengeBytes.length}-byte challenge; expected 32`);
7036
6905
  }
7037
- const challengeSig = (0, import_sdk22.signChallenge)(challengeBytes, keys.identitySecretKey);
7038
- const identityPublicKeyB58 = (0, import_sdk22.base58btcEncode)(keys.identityPublicKey);
6906
+ const challengeSig = (0, import_sdk25.signChallenge)(challengeBytes, keys.identitySecretKey);
6907
+ const identityPublicKeyB58 = (0, import_sdk25.base58btcEncode)(keys.identityPublicKey);
7039
6908
  await api.submitChallengeResponse({
7040
6909
  challengeId: challenge.challengeId,
7041
6910
  identityPublicKey: identityPublicKeyB58,
7042
6911
  signature: Buffer.from(challengeSig).toString("base64")
7043
6912
  });
7044
- const settlementPublicKeyB58 = (0, import_sdk22.base58btcEncode)(keys.settlementPublicKey);
7045
- const scryptSaltId = (0, import_sdk22.uuidV4)();
6913
+ const settlementPublicKeyB58 = (0, import_sdk25.base58btcEncode)(keys.settlementPublicKey);
6914
+ const scryptSaltId = (0, import_sdk25.uuidV4)();
7046
6915
  const payload = {
7047
- purpose: import_sdk22.Purpose.KEY_LINK,
6916
+ purpose: import_sdk25.Purpose.KEY_LINK,
7048
6917
  agent_did: did,
7049
6918
  identity_public_key: identityPublicKeyB58,
7050
6919
  settlement_public_key: settlementPublicKeyB58,
7051
- owner_signing_method: import_sdk22.OWNER_SIGNING_METHODS[0],
6920
+ owner_signing_method: import_sdk25.OWNER_SIGNING_METHODS[0],
7052
6921
  link_method: "manual",
7053
- created_at: (0, import_sdk22.rfc3339)(),
7054
- nonce: (0, import_sdk22.senderNonce)()
6922
+ created_at: (0, import_sdk25.rfc3339)(),
6923
+ nonce: (0, import_sdk25.senderNonce)()
7055
6924
  };
7056
- const attestation = (0, import_sdk22.signKeyLinkAttestation)({ payload, scryptKey, scryptSaltId });
6925
+ const attestation = (0, import_sdk25.signKeyLinkAttestation)({ payload, scryptKey, scryptSaltId });
7057
6926
  const body = {
7058
6927
  challengeId: challenge.challengeId,
7059
6928
  identityPublicKey: identityPublicKeyB58,
@@ -7096,7 +6965,7 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
7096
6965
  try {
7097
6966
  result = await api.register(body, credential.token);
7098
6967
  } catch (err) {
7099
- if (err instanceof ApiError && (err.payload.code === import_sdk22.CliAuthTokenErrorCodes.INVALID || err.payload.code === import_sdk22.CliAuthTokenErrorCodes.REQUIRED)) {
6968
+ if (err instanceof ApiError && (err.payload.code === import_sdk25.CliAuthTokenErrorCodes.INVALID || err.payload.code === import_sdk25.CliAuthTokenErrorCodes.REQUIRED)) {
7100
6969
  throw new Error(
7101
6970
  `register: the stored login token for ${api.serverUrl} was rejected (${err.payload.message}) \u2014 run 'heyarp login' again. Your keys are saved locally; re-running register with --from-keys is safe.`
7102
6971
  );
@@ -7115,19 +6984,19 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
7115
6984
  try {
7116
6985
  recordHome(arpHomeDir());
7117
6986
  } catch (registryErr) {
7118
- if (!opts.json) console.log(import_chalk25.default.dim(`(homes registry write failed: ${registryErr.message})`));
6987
+ if (!opts.json) console.log(import_chalk27.default.dim(`(homes registry write failed: ${registryErr.message})`));
7119
6988
  }
7120
6989
  if (!opts.json) {
7121
- console.log(import_chalk25.default.green("\nRegistered."));
7122
- console.log(`${import_chalk25.default.bold("DID")}: ${import_chalk25.default.cyan(result.did)}`);
7123
- console.log(`${import_chalk25.default.bold("Settlement pubkey")} ${import_chalk25.default.dim("(fund with SOL)")}: ${import_chalk25.default.cyan(settlementPublicKeyB58)}`);
7124
- console.log(`${import_chalk25.default.bold("Owner account")}: ${import_chalk25.default.cyan(credential.wallet)}`);
7125
- console.log(import_chalk25.default.bold("DID document:"));
6990
+ console.log(import_chalk27.default.green("\nRegistered."));
6991
+ console.log(`${import_chalk27.default.bold("DID")}: ${import_chalk27.default.cyan(result.did)}`);
6992
+ console.log(`${import_chalk27.default.bold("Settlement pubkey")} ${import_chalk27.default.dim("(fund with SOL)")}: ${import_chalk27.default.cyan(settlementPublicKeyB58)}`);
6993
+ console.log(`${import_chalk27.default.bold("Owner account")}: ${import_chalk27.default.cyan(credential.wallet)}`);
6994
+ console.log(import_chalk27.default.bold("DID document:"));
7126
6995
  console.log(formatJson(result.didDocument));
7127
6996
  }
7128
- if (!opts.json) console.log(import_chalk25.default.green(`
6997
+ if (!opts.json) console.log(import_chalk27.default.green(`
7129
6998
  \u2713 Discoverable now via \`heyarp agents\`.`));
7130
- if (!opts.json) console.log(import_chalk25.default.dim(`
6999
+ if (!opts.json) console.log(import_chalk27.default.dim(`
7131
7000
  Local state saved to ${arpHomeDir()}/agents.json (mode 0600).`));
7132
7001
  if (opts.json) {
7133
7002
  console.log(
@@ -7178,8 +7047,13 @@ async function mergeAnswers(opts) {
7178
7047
  promptDefs.push({
7179
7048
  type: "text",
7180
7049
  name: "name",
7181
- message: "Agent name (display only)",
7182
- validate: (v) => v.length > 0 ? true : "required"
7050
+ message: "Agent name \u2014 unique handle (lowercase a-z0-9_, 3-32 chars, immutable; addressable instead of the DID)",
7051
+ validate: (v) => {
7052
+ const n = (0, import_sdk25.normalizeName)(v);
7053
+ if (!(0, import_sdk25.isValidAgentName)(n)) return "must be lowercase a-z0-9_, 3-32 chars";
7054
+ if ((0, import_sdk25.isReservedName)(n)) return `'${n}' is reserved`;
7055
+ return true;
7056
+ }
7183
7057
  });
7184
7058
  }
7185
7059
  if (need.description) {
@@ -7195,18 +7069,29 @@ async function mergeAnswers(opts) {
7195
7069
  }
7196
7070
  const prompted = promptDefs.length > 0 ? await (0, import_prompts2.default)(promptDefs, {
7197
7071
  onCancel: () => {
7198
- console.log(import_chalk25.default.yellow("\nAborted."));
7072
+ console.log(import_chalk27.default.yellow("\nAborted."));
7199
7073
  process.exit(130);
7200
7074
  }
7201
7075
  }) : {};
7202
7076
  const tags = (opts.tag && opts.tag.length > 0 ? opts.tag : parseTagsCsv(typeof prompted.tagsCsv === "string" ? prompted.tagsCsv : "")).map((t) => t.trim().toLowerCase()).filter((t) => t.length > 0);
7077
+ const name = normalizeAndValidateName(opts.name ?? prompted.name);
7203
7078
  return {
7204
7079
  password: opts.password ?? prompted.password,
7205
- name: opts.name ?? prompted.name,
7080
+ name,
7206
7081
  description: opts.description ?? prompted.description ?? "",
7207
7082
  tags
7208
7083
  };
7209
7084
  }
7085
+ function normalizeAndValidateName(raw) {
7086
+ const name = (0, import_sdk25.normalizeName)(raw);
7087
+ if (!(0, import_sdk25.isValidAgentName)(name)) {
7088
+ throw new Error(`register: name '${raw}' must be a lowercase handle \u2014 a-z0-9_, 3-32 chars`);
7089
+ }
7090
+ if ((0, import_sdk25.isReservedName)(name)) {
7091
+ throw new Error(`register: name '${name}' is reserved and cannot be registered`);
7092
+ }
7093
+ return name;
7094
+ }
7210
7095
  function warnIfOrphanHomesPresent() {
7211
7096
  if (process.env.HEYARP_HOME && process.env.HEYARP_HOME.length > 0) {
7212
7097
  return;
@@ -7216,16 +7101,16 @@ function warnIfOrphanHomesPresent() {
7216
7101
  try {
7217
7102
  others = listHomes().filter((h) => h.path !== current);
7218
7103
  } catch (registryErr) {
7219
- console.log(import_chalk25.default.dim(`(homes registry unreadable, skipping orphan-home check: ${registryErr.message})`));
7104
+ console.log(import_chalk27.default.dim(`(homes registry unreadable, skipping orphan-home check: ${registryErr.message})`));
7220
7105
  return;
7221
7106
  }
7222
7107
  if (others.length === 0) return;
7223
- const list = others.map((h) => ` \u2022 ${import_chalk25.default.cyan(h.path)} ${import_chalk25.default.dim(`(last seen ${h.lastSeenAt})`)}`).join("\n");
7224
- console.log(import_chalk25.default.yellow(`
7108
+ const list = others.map((h) => ` \u2022 ${import_chalk27.default.cyan(h.path)} ${import_chalk27.default.dim(`(last seen ${h.lastSeenAt})`)}`).join("\n");
7109
+ console.log(import_chalk27.default.yellow(`
7225
7110
  \u26A0 HEYARP_HOME is unset, but other agent homes are registered on this machine:`));
7226
7111
  console.log(list);
7227
7112
  console.log(
7228
- import_chalk25.default.dim(
7113
+ import_chalk27.default.dim(
7229
7114
  ` Registering will create a NEW agent under ${current}.
7230
7115
  If you meant to add to an existing home, abort (Ctrl-C) and re-run with:
7231
7116
  HEYARP_HOME=<path> heyarp register \u2026
@@ -7238,11 +7123,11 @@ function warnIfAgentsAlreadyRegistered(serverOverride) {
7238
7123
  const targetServer = resolveServerUrl(serverOverride);
7239
7124
  const existing = listAgents().filter((row) => row.serverUrl === targetServer);
7240
7125
  if (existing.length === 0) return;
7241
- const list = existing.map((row) => ` \u2022 ${import_chalk25.default.cyan(row.agent.did)}${row.agent.name ? import_chalk25.default.dim(` (${row.agent.name})`) : ""}`).join("\n");
7242
- console.log(import_chalk25.default.yellow("\n\u26A0 ~/.heyarp/agents.json already has agent(s) for this server:"));
7126
+ const list = existing.map((row) => ` \u2022 ${import_chalk27.default.cyan(row.agent.did)}${row.agent.name ? import_chalk27.default.dim(` (${row.agent.name})`) : ""}`).join("\n");
7127
+ console.log(import_chalk27.default.yellow("\n\u26A0 ~/.heyarp/agents.json already has agent(s) for this server:"));
7243
7128
  console.log(list);
7244
7129
  console.log(
7245
- import_chalk25.default.dim(
7130
+ import_chalk27.default.dim(
7246
7131
  " After this register completes, you will have multiple local DIDs sharing one state file.\n To keep their state isolated, run with HEYARP_HOME pointing at a per-agent dir, e.g.\n HEYARP_HOME=/tmp/agent-alice heyarp register \u2026\n Otherwise, pass --from-did <did> explicitly on every signed command.\n"
7247
7132
  )
7248
7133
  );
@@ -7252,8 +7137,8 @@ function parseTagsCsv(raw) {
7252
7137
  return raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
7253
7138
  }
7254
7139
  function freshKeys() {
7255
- const identity = (0, import_sdk22.generateKeyPair)();
7256
- const settlement = (0, import_sdk22.generateKeyPair)();
7140
+ const identity = (0, import_sdk25.generateKeyPair)();
7141
+ const settlement = (0, import_sdk25.generateKeyPair)();
7257
7142
  return {
7258
7143
  identityPublicKey: identity.publicKey,
7259
7144
  identitySecretKey: identity.secretKey,
@@ -7279,9 +7164,9 @@ function loadKeysFromFile(path) {
7279
7164
  if (identitySecret.length !== 32) throw new Error("--from-keys: identitySecretKeyB64 is not a 32-byte Ed25519 seed");
7280
7165
  if (settlementSecret.length !== 32) throw new Error("--from-keys: settlementSecretKeyB64 is not a 32-byte Ed25519 seed");
7281
7166
  return {
7282
- identityPublicKey: (0, import_sdk22.getPublicKey)(identitySecret),
7167
+ identityPublicKey: (0, import_sdk25.getPublicKey)(identitySecret),
7283
7168
  identitySecretKey: identitySecret,
7284
- settlementPublicKey: (0, import_sdk22.getPublicKey)(settlementSecret),
7169
+ settlementPublicKey: (0, import_sdk25.getPublicKey)(settlementSecret),
7285
7170
  settlementSecretKey: settlementSecret
7286
7171
  };
7287
7172
  }
@@ -7297,10 +7182,10 @@ function assertJsonRequiresYes(opts) {
7297
7182
  }
7298
7183
 
7299
7184
  // src/commands/relationships.ts
7300
- var import_sdk23 = require("@heyanon-arp/sdk");
7301
- var import_chalk26 = __toESM(require("chalk"));
7185
+ var import_sdk26 = require("@heyanon-arp/sdk");
7186
+ var import_chalk28 = __toESM(require("chalk"));
7302
7187
  init_api();
7303
- var ALLOWED_STATES2 = new Set(import_sdk23.RELATIONSHIP_STATE_NAMES);
7188
+ var ALLOWED_STATES2 = new Set(import_sdk26.RELATIONSHIP_STATE_NAMES);
7304
7189
  function registerRelationshipsCommand(root) {
7305
7190
  root.command("relationships").description(
7306
7191
  "List relationships <did> belongs to (live + closed pairs, ordered by lastEventAt desc). DID can be passed positionally OR via --from-did; if both are omitted the resolver picks the sole local agent for the server (see `heyarp config set server` + multi-DID disambiguation rules)."
@@ -7308,7 +7193,7 @@ function registerRelationshipsCommand(root) {
7308
7193
  "--json",
7309
7194
  "Machine-readable mode \u2014 emit the relationships as a single JSON array on stdout (RelationshipPublic[]). Prelude + table move to stderr. Mutually exclusive with --verbose.",
7310
7195
  false
7311
- ).option("--from-did <did>", "Alias for the positional <did> argument \u2014 accepted for consistency with other signed commands. Must match the positional if both are given.").action(async (did, opts) => {
7196
+ ).option("--from-did <did>", "Alias for the positional <did> argument \u2014 accepted for consistency with other signed commands. Must match the positional if both are given.").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").action(async (did, opts) => {
7312
7197
  await runRelationships(did, opts);
7313
7198
  });
7314
7199
  }
@@ -7324,11 +7209,11 @@ async function runRelationships(positionalDid, opts) {
7324
7209
  throw new Error(`relationships: positional <did> (${positionalDid}) and --from-did (${opts.fromDid}) disagree \u2014 pass only one`);
7325
7210
  }
7326
7211
  const explicitDid = positionalDid ?? opts.fromDid;
7327
- const local = explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("relationships", opts.server, void 0);
7212
+ const local = explicitDid !== void 0 ? loadAgentOrThrow(opts.server, explicitDid) : resolveSenderAgent("relationships", opts.server, void 0, opts.from);
7328
7213
  const did = local.did;
7329
7214
  const api = new ArpApiClient(opts.server);
7330
- progress(opts.json, import_chalk26.default.dim(`Server: ${api.serverUrl}`));
7331
- progress(opts.json, import_chalk26.default.dim(`Signer: ${local.did}`));
7215
+ progress(opts.json, import_chalk28.default.dim(`Server: ${api.serverUrl}`));
7216
+ progress(opts.json, import_chalk28.default.dim(`Signer: ${local.did}`));
7332
7217
  const query = { limit };
7333
7218
  if (state) query.state = state;
7334
7219
  const signer = makeSigner(local);
@@ -7338,18 +7223,18 @@ async function runRelationships(positionalDid, opts) {
7338
7223
  return;
7339
7224
  }
7340
7225
  if (rows.length === 0) {
7341
- console.log(import_chalk26.default.dim("\n(no relationships)"));
7226
+ console.log(import_chalk28.default.dim("\n(no relationships)"));
7342
7227
  return;
7343
7228
  }
7344
7229
  console.log("");
7345
7230
  console.log(formatRelationshipsTable(rows, did));
7346
7231
  if (opts.verbose) {
7347
- console.log(import_chalk26.default.bold("\nFull relationships:"));
7232
+ console.log(import_chalk28.default.bold("\nFull relationships:"));
7348
7233
  for (const r of rows) {
7349
7234
  console.log(formatJson(r));
7350
7235
  }
7351
7236
  }
7352
- console.log(import_chalk26.default.dim(`
7237
+ console.log(import_chalk28.default.dim(`
7353
7238
  ${rows.length} relationship(s).`));
7354
7239
  }
7355
7240
  function formatRelationshipsTable(rows, selfDid) {
@@ -7357,7 +7242,7 @@ function formatRelationshipsTable(rows, selfDid) {
7357
7242
  const data = rows.map((r) => [r.relationshipId, otherPair(r, selfDid), r.state, r.lastEventAt ?? "(none)", String(r.lastEventIndex)]);
7358
7243
  const widths = header.map((h, i) => Math.max(h.length, ...data.map((row) => row[i].length)));
7359
7244
  const pad = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(" ");
7360
- return [import_chalk26.default.bold(pad(header)), import_chalk26.default.dim(pad(widths.map((w) => "-".repeat(w)))), ...data.map((row) => pad(row))].join("\n");
7245
+ return [import_chalk28.default.bold(pad(header)), import_chalk28.default.dim(pad(widths.map((w) => "-".repeat(w)))), ...data.map((row) => pad(row))].join("\n");
7361
7246
  }
7362
7247
  function otherPair(r, selfDid) {
7363
7248
  if (r.pairDidA === selfDid) return r.pairDidB;
@@ -7381,12 +7266,12 @@ function parseLimit6(raw) {
7381
7266
  }
7382
7267
 
7383
7268
  // src/commands/reputation.ts
7384
- var import_sdk24 = require("@heyanon-arp/sdk");
7385
- var import_chalk27 = __toESM(require("chalk"));
7269
+ var import_sdk27 = require("@heyanon-arp/sdk");
7270
+ var import_chalk29 = __toESM(require("chalk"));
7386
7271
  init_api();
7387
7272
  function registerReputationCommand(root) {
7388
7273
  root.command("reputation").description("Show an agent's informational reputation (composite + component scores + raw counters). Public, no auth. NOT a money/eligibility gate.").argument("<did>", "did:arp:<base58btc> identifier").option("--server <url>", "Override ARP server base URL").option("--json", "Emit the reputation as JSON on stdout.", false).action(async (did, opts) => {
7389
- if (!(0, import_sdk24.isValidDid)(did)) {
7274
+ if (!(0, import_sdk27.isValidDid)(did)) {
7390
7275
  throw new Error(`'${did}' is not a syntactically valid did:arp identifier`);
7391
7276
  }
7392
7277
  const api = new ArpApiClient(opts.server);
@@ -7398,10 +7283,10 @@ function registerReputationCommand(root) {
7398
7283
  const s = rep.scores;
7399
7284
  const c = rep.counters;
7400
7285
  const j = false;
7401
- progress(j, import_chalk27.default.bold(`Reputation \u2014 ${did}`));
7286
+ progress(j, import_chalk29.default.bold(`Reputation \u2014 ${did}`));
7402
7287
  progress(
7403
7288
  j,
7404
- import_chalk27.default.dim(` ${rep.informational ? "INFORMATIONAL" : "GATING"} \xB7 ${rep.computed ? `computed ${rep.lastComputedAt}` : "never computed (neutral cold-start)"}`)
7289
+ import_chalk29.default.dim(` ${rep.informational ? "INFORMATIONAL" : "GATING"} \xB7 ${rep.computed ? `computed ${rep.lastComputedAt}` : "never computed (neutral cold-start)"}`)
7405
7290
  );
7406
7291
  progress(j, "");
7407
7292
  progress(j, ` composite ${bar(s.composite)} ${s.composite.toFixed(2)}`);
@@ -7409,17 +7294,17 @@ function registerReputationCommand(root) {
7409
7294
  progress(j, ` settlement ${bar(s.settlement)} ${s.settlement.toFixed(2)}`);
7410
7295
  progress(j, ` dispute health ${bar(s.disputeHealth)} ${s.disputeHealth.toFixed(2)}`);
7411
7296
  progress(j, "");
7412
- progress(j, import_chalk27.default.dim(" evidence:"));
7297
+ progress(j, import_chalk29.default.dim(" evidence:"));
7413
7298
  progress(
7414
7299
  j,
7415
- import_chalk27.default.dim(
7300
+ import_chalk29.default.dim(
7416
7301
  ` on-chain cycles ${c.onchainCycles} \xB7 completed ${c.completedDelegations} (payer ${c.completedAsPayer} / payee ${c.completedAsPayee}) \xB7 failed ${c.failedDelegations}`
7417
7302
  )
7418
7303
  );
7419
- progress(j, import_chalk27.default.dim(` escrows settled ${c.settledEscrows} / refunded ${c.refundedEscrows} \xB7 disputed ${c.disputedEscrows} (adverse ${c.disputesAdverse})`));
7420
- progress(j, import_chalk27.default.dim(` distinct counterparts ${c.distinctCounterparts} \xB7 active relationships ${c.activeRelationships}`));
7304
+ progress(j, import_chalk29.default.dim(` escrows settled ${c.settledEscrows} / refunded ${c.refundedEscrows} \xB7 disputed ${c.disputedEscrows} (adverse ${c.disputesAdverse})`));
7305
+ progress(j, import_chalk29.default.dim(` distinct counterparts ${c.distinctCounterparts} \xB7 active relationships ${c.activeRelationships}`));
7421
7306
  progress(j, "");
7422
- progress(j, import_chalk27.default.dim(" Informational only \u2014 a discovery-sort signal, not a money or eligibility gate."));
7307
+ progress(j, import_chalk29.default.dim(" Informational only \u2014 a discovery-sort signal, not a money or eligibility gate."));
7423
7308
  });
7424
7309
  }
7425
7310
  function bar(score) {
@@ -7428,11 +7313,11 @@ function bar(score) {
7428
7313
  }
7429
7314
 
7430
7315
  // src/commands/send-handshake.ts
7431
- var import_sdk25 = require("@heyanon-arp/sdk");
7432
- var import_chalk28 = __toESM(require("chalk"));
7316
+ var import_sdk28 = require("@heyanon-arp/sdk");
7317
+ var import_chalk30 = __toESM(require("chalk"));
7433
7318
  init_api();
7434
7319
  function registerSendHandshakeCommand(root) {
7435
- root.command("send-handshake").description("Send a handshake envelope to <recipient-did>. Server creates the relationship row on first contact.").argument("<recipient-did>", "Recipient agent DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--greeting <s>", "Optional greeting text included in body.content").option("--intent <s>", "Optional intent text included in body.content").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk25.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(
7320
+ root.command("send-handshake").description("Send a handshake envelope to a recipient (agent name or DID). Server creates the relationship row on first contact.").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (did:arp:...)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--greeting <s>", "Optional greeting text included in body.content").option("--intent <s>", "Optional intent text included in body.content").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk28.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(
7436
7321
  "--json",
7437
7322
  "Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, eventId, relationshipId, relationshipEventIndex, serverTimestamp, signedMessageHash, serverEventHash, prevServerEventHash, senderSequence}). The Server/Sender/Recipient prelude moves to stderr so `--json | jq` stays byte-pure. Mutually exclusive with --verbose.",
7438
7323
  false
@@ -7441,46 +7326,44 @@ function registerSendHandshakeCommand(root) {
7441
7326
  });
7442
7327
  }
7443
7328
  async function runSendHandshake(recipientDid, opts) {
7444
- if (!(0, import_sdk25.isValidDid)(recipientDid)) {
7445
- throw new Error(`send-handshake: <recipient-did> must be a valid did:arp identifier (base58btc-encoded 32-byte Ed25519 pubkey) (got '${recipientDid}')`);
7446
- }
7447
7329
  if (opts.verbose && opts.json) {
7448
7330
  throw new Error(
7449
7331
  "send-handshake: --verbose and --json are mutually exclusive. --json emits the structured server response; --verbose adds envelope + response dumps that would break `--json | jq`."
7450
7332
  );
7451
7333
  }
7334
+ recipientDid = await resolveRecipient(opts.server, "send-handshake", recipientDid, { json: opts.json });
7452
7335
  const ttlSeconds = parseTtl3(opts.ttl);
7453
7336
  const api = new ArpApiClient(opts.server);
7454
- progress(opts.json, import_chalk28.default.dim(`Server: ${api.serverUrl}`));
7455
- const sender = resolveSenderAgent("send-handshake", opts.server, opts.fromDid);
7456
- progress(opts.json, import_chalk28.default.dim(`Sender: ${sender.did}`));
7457
- progress(opts.json, import_chalk28.default.dim(`Recipient: ${recipientDid}`));
7337
+ progress(opts.json, import_chalk30.default.dim(`Server: ${api.serverUrl}`));
7338
+ const sender = resolveSenderAgent("send-handshake", opts.server, opts.fromDid, opts.from);
7339
+ progress(opts.json, import_chalk30.default.dim(`Sender: ${sender.did}`));
7340
+ progress(opts.json, import_chalk30.default.dim(`Recipient: ${recipientDid}`));
7458
7341
  const content = {};
7459
7342
  if (opts.greeting) content.greeting = opts.greeting;
7460
7343
  if (opts.intent) content.intent = opts.intent;
7461
7344
  const body = { type: "handshake", content };
7462
7345
  const nextSequence = (sender.lastSenderSequence ?? 0) + 1;
7463
7346
  const protectedBlock = {
7464
- protocol_version: import_sdk25.CURRENT_PROTOCOL_VERSION,
7465
- purpose: import_sdk25.Purpose.ENVELOPE,
7466
- message_id: (0, import_sdk25.uuidV4)(),
7347
+ protocol_version: import_sdk28.CURRENT_PROTOCOL_VERSION,
7348
+ purpose: import_sdk28.Purpose.ENVELOPE,
7349
+ message_id: (0, import_sdk28.uuidV4)(),
7467
7350
  sender_did: sender.did,
7468
7351
  recipient_did: recipientDid,
7469
7352
  relationship_id: null,
7470
7353
  sender_sequence: nextSequence,
7471
- sender_nonce: (0, import_sdk25.senderNonce)(),
7472
- timestamp: (0, import_sdk25.rfc3339)(),
7473
- expires_at: (0, import_sdk25.expiresAt)(ttlSeconds),
7354
+ sender_nonce: (0, import_sdk28.senderNonce)(),
7355
+ timestamp: (0, import_sdk28.rfc3339)(),
7356
+ expires_at: (0, import_sdk28.expiresAt)(ttlSeconds),
7474
7357
  delivery_id: null
7475
7358
  };
7476
7359
  const signer = makeSigner(sender);
7477
- const envelope = (0, import_sdk25.signEnvelope)({
7360
+ const envelope = (0, import_sdk28.signEnvelope)({
7478
7361
  protected: protectedBlock,
7479
7362
  body,
7480
7363
  identitySecretKey: signer.identitySecretKey
7481
7364
  });
7482
7365
  if (opts.verbose) {
7483
- console.log(import_chalk28.default.bold("\nEnvelope (pre-send):"));
7366
+ console.log(import_chalk30.default.bold("\nEnvelope (pre-send):"));
7484
7367
  console.log(formatJson(envelope));
7485
7368
  }
7486
7369
  const result = await api.ingest(envelope);
@@ -7500,23 +7383,23 @@ async function runSendHandshake(recipientDid, opts) {
7500
7383
  });
7501
7384
  return;
7502
7385
  }
7503
- console.log(import_chalk28.default.green("\nDelivered."));
7504
- console.log(`${import_chalk28.default.bold("Event id")}: ${import_chalk28.default.cyan(result.eventId)}`);
7505
- console.log(`${import_chalk28.default.bold("Relationship id")}: ${import_chalk28.default.cyan(result.relationshipId)}`);
7506
- console.log(`${import_chalk28.default.bold("Chain index")}: ${import_chalk28.default.cyan(String(result.relationshipEventIndex))}`);
7507
- console.log(`${import_chalk28.default.bold("Server timestamp")}: ${import_chalk28.default.cyan(result.serverTimestamp)}`);
7508
- console.log(`${import_chalk28.default.bold("Signed message hash")}: ${import_chalk28.default.cyan(result.signedMessageHash)}`);
7509
- console.log(`${import_chalk28.default.bold("Server event hash")}: ${import_chalk28.default.cyan(result.serverEventHash)}`);
7386
+ console.log(import_chalk30.default.green("\nDelivered."));
7387
+ console.log(`${import_chalk30.default.bold("Event id")}: ${import_chalk30.default.cyan(result.eventId)}`);
7388
+ console.log(`${import_chalk30.default.bold("Relationship id")}: ${import_chalk30.default.cyan(result.relationshipId)}`);
7389
+ console.log(`${import_chalk30.default.bold("Chain index")}: ${import_chalk30.default.cyan(String(result.relationshipEventIndex))}`);
7390
+ console.log(`${import_chalk30.default.bold("Server timestamp")}: ${import_chalk30.default.cyan(result.serverTimestamp)}`);
7391
+ console.log(`${import_chalk30.default.bold("Signed message hash")}: ${import_chalk30.default.cyan(result.signedMessageHash)}`);
7392
+ console.log(`${import_chalk30.default.bold("Server event hash")}: ${import_chalk30.default.cyan(result.serverEventHash)}`);
7510
7393
  if (result.prevServerEventHash) {
7511
- console.log(`${import_chalk28.default.bold("Prev server event hash")}: ${import_chalk28.default.cyan(result.prevServerEventHash)}`);
7394
+ console.log(`${import_chalk30.default.bold("Prev server event hash")}: ${import_chalk30.default.cyan(result.prevServerEventHash)}`);
7512
7395
  } else {
7513
- console.log(`${import_chalk28.default.bold("Prev server event hash")}: ${import_chalk28.default.dim("(null \u2014 first event of this relationship)")}`);
7396
+ console.log(`${import_chalk30.default.bold("Prev server event hash")}: ${import_chalk30.default.dim("(null \u2014 first event of this relationship)")}`);
7514
7397
  }
7515
7398
  if (opts.verbose) {
7516
- console.log(import_chalk28.default.bold("\nFull server response:"));
7399
+ console.log(import_chalk30.default.bold("\nFull server response:"));
7517
7400
  console.log(formatJson(result));
7518
7401
  }
7519
- console.log(import_chalk28.default.dim(`
7402
+ console.log(import_chalk30.default.dim(`
7520
7403
  Local sender_sequence advanced to ${nextSequence}.`));
7521
7404
  }
7522
7405
  function parseTtl3(raw) {
@@ -7529,19 +7412,19 @@ function parseTtl3(raw) {
7529
7412
  }
7530
7413
 
7531
7414
  // src/commands/send-handshake-response.ts
7532
- var import_sdk26 = require("@heyanon-arp/sdk");
7533
- var import_chalk29 = __toESM(require("chalk"));
7415
+ var import_sdk29 = require("@heyanon-arp/sdk");
7416
+ var import_chalk31 = __toESM(require("chalk"));
7534
7417
  init_api();
7535
- var ALLOWED_DECISIONS = new Set(import_sdk26.HANDSHAKE_DECISIONS);
7418
+ var ALLOWED_DECISIONS = new Set(import_sdk29.HANDSHAKE_DECISIONS);
7536
7419
  function registerSendHandshakeResponseCommand(root) {
7537
- root.command("send-handshake-response").description("Accept or decline an inbound handshake from <recipient-did>. Server reuses the existing relationship row.").argument("<recipient-did>", "Recipient agent DID (did:arp:...) \u2014 the original handshake sender").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--decision <s>", "REQUIRED: accept or decline").option("--notes <s>", "Optional notes included in body.content").option(
7420
+ root.command("send-handshake-response").description("Accept or decline an inbound handshake from <recipient-did>. Server reuses the existing relationship row.").argument("<recipient-did>", "Recipient agent DID (did:arp:...) \u2014 the original handshake sender").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--decision <s>", "REQUIRED: accept or decline").option("--notes <s>", "Optional notes included in body.content").option(
7538
7421
  "--reason <code>",
7539
7422
  // REQUIRED when --decision=decline. Optional otherwise.
7540
7423
  // We don't use commander's requiredOption because it
7541
7424
  // would fire for the accept path too; validate manually
7542
7425
  // after decision is parsed.
7543
- `When --decision=decline: required reason code (one of: ${import_sdk26.DECLINE_REASONS.join(", ")}). Carried in body.content.reason.`
7544
- ).option("--reason-detail <s>", "Optional free-text elaboration alongside --reason (max 512 chars).").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk26.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(
7426
+ `When --decision=decline: required reason code (one of: ${import_sdk29.DECLINE_REASONS.join(", ")}). Carried in body.content.reason.`
7427
+ ).option("--reason-detail <s>", "Optional free-text elaboration alongside --reason (max 512 chars).").option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk29.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(
7545
7428
  "--json",
7546
7429
  "Machine-readable mode \u2014 emit a single JSON object on stdout ({ok, decision, eventId, relationshipId, relationshipEventIndex, serverTimestamp, serverEventHash, prevServerEventHash}; idempotent short-circuit adds {idempotent:true}). Prelude + banners move off stdout; on failure stderr carries `{code, message}`. Mutually exclusive with --verbose.",
7547
7430
  false
@@ -7559,23 +7442,23 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7559
7442
  "send-handshake-response: --verbose and --json are mutually exclusive. --json emits the structured server response; --verbose adds envelope + response dumps that would break `--json | jq`."
7560
7443
  );
7561
7444
  }
7562
- if (!(0, import_sdk26.isValidDid)(recipientDid)) {
7445
+ if (!(0, import_sdk29.isValidDid)(recipientDid)) {
7563
7446
  throw new Error(`send-handshake-response: <recipient-did> must be a valid did:arp identifier (base58btc-encoded 32-byte Ed25519 pubkey) (got '${recipientDid}')`);
7564
7447
  }
7565
7448
  const decision = parseDecision(opts.decision);
7566
7449
  const ttlSeconds = parseTtl4(opts.ttl);
7567
7450
  let declinePayload = null;
7568
- if (decision === import_sdk26.HandshakeDecisions.DECLINE) {
7451
+ if (decision === import_sdk29.HandshakeDecisions.DECLINE) {
7569
7452
  const reason = parseDeclineReason("send-handshake-response", opts.reason);
7570
7453
  const detail = parseReasonDetail("send-handshake-response", opts.reasonDetail);
7571
7454
  declinePayload = detail ? { reason, reasonDetail: detail } : { reason };
7572
7455
  }
7573
7456
  const api = new ArpApiClient(opts.server);
7574
- progress(opts.json, import_chalk29.default.dim(`Server: ${api.serverUrl}`));
7575
- const sender = resolveSenderAgent("send-handshake-response", opts.server, opts.fromDid);
7576
- progress(opts.json, import_chalk29.default.dim(`Sender: ${sender.did}`));
7577
- progress(opts.json, import_chalk29.default.dim(`Recipient: ${recipientDid}`));
7578
- progress(opts.json, import_chalk29.default.dim(`Decision: ${decision}`));
7457
+ progress(opts.json, import_chalk31.default.dim(`Server: ${api.serverUrl}`));
7458
+ const sender = resolveSenderAgent("send-handshake-response", opts.server, opts.fromDid, opts.from);
7459
+ progress(opts.json, import_chalk31.default.dim(`Sender: ${sender.did}`));
7460
+ progress(opts.json, import_chalk31.default.dim(`Recipient: ${recipientDid}`));
7461
+ progress(opts.json, import_chalk31.default.dim(`Decision: ${decision}`));
7579
7462
  const signer = makeSigner(sender);
7580
7463
  if (!opts.force) {
7581
7464
  try {
@@ -7605,13 +7488,13 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7605
7488
  });
7606
7489
  return;
7607
7490
  }
7608
- progress(opts.json, import_chalk29.default.yellow(`
7491
+ progress(opts.json, import_chalk31.default.yellow(`
7609
7492
  [--idempotency] Relationship ${existing.relationshipId} with ${recipientDid} is already 'active'.`));
7610
7493
  progress(
7611
7494
  opts.json,
7612
- import_chalk29.default.dim(`A previous accept from this signer (event ${previousResponseFromMe.eventId}) landed successfully. Skipping re-send (use --force to override).`)
7495
+ import_chalk31.default.dim(`A previous accept from this signer (event ${previousResponseFromMe.eventId}) landed successfully. Skipping re-send (use --force to override).`)
7613
7496
  );
7614
- progress(opts.json, import_chalk29.default.dim(`Last event index: ${existing.lastEventIndex}, last server event hash: ${existing.lastServerEventHash ?? "(none)"}`));
7497
+ progress(opts.json, import_chalk31.default.dim(`Last event index: ${existing.lastEventIndex}, last server event hash: ${existing.lastServerEventHash ?? "(none)"}`));
7615
7498
  return;
7616
7499
  }
7617
7500
  throw new Error(
@@ -7622,7 +7505,7 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7622
7505
  if (probeErr instanceof Error && /CLOSED|terminated|already 'active' from a previous ACCEPT|original initiator/i.test(probeErr.message)) {
7623
7506
  throw probeErr;
7624
7507
  }
7625
- progress(opts.json, import_chalk29.default.dim(`(idempotency probe failed; proceeding anyway: ${probeErr.message})`));
7508
+ progress(opts.json, import_chalk31.default.dim(`(idempotency probe failed; proceeding anyway: ${probeErr.message})`));
7626
7509
  }
7627
7510
  }
7628
7511
  const content = { decision };
@@ -7634,25 +7517,25 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7634
7517
  const body = { type: "handshake_response", content };
7635
7518
  const nextSequence = (sender.lastSenderSequence ?? 0) + 1;
7636
7519
  const protectedBlock = {
7637
- protocol_version: import_sdk26.CURRENT_PROTOCOL_VERSION,
7638
- purpose: import_sdk26.Purpose.ENVELOPE,
7639
- message_id: (0, import_sdk26.uuidV4)(),
7520
+ protocol_version: import_sdk29.CURRENT_PROTOCOL_VERSION,
7521
+ purpose: import_sdk29.Purpose.ENVELOPE,
7522
+ message_id: (0, import_sdk29.uuidV4)(),
7640
7523
  sender_did: sender.did,
7641
7524
  recipient_did: recipientDid,
7642
7525
  relationship_id: null,
7643
7526
  sender_sequence: nextSequence,
7644
- sender_nonce: (0, import_sdk26.senderNonce)(),
7645
- timestamp: (0, import_sdk26.rfc3339)(),
7646
- expires_at: (0, import_sdk26.expiresAt)(ttlSeconds),
7527
+ sender_nonce: (0, import_sdk29.senderNonce)(),
7528
+ timestamp: (0, import_sdk29.rfc3339)(),
7529
+ expires_at: (0, import_sdk29.expiresAt)(ttlSeconds),
7647
7530
  delivery_id: null
7648
7531
  };
7649
- const envelope = (0, import_sdk26.signEnvelope)({
7532
+ const envelope = (0, import_sdk29.signEnvelope)({
7650
7533
  protected: protectedBlock,
7651
7534
  body,
7652
7535
  identitySecretKey: signer.identitySecretKey
7653
7536
  });
7654
7537
  if (opts.verbose) {
7655
- console.log(import_chalk29.default.bold("\nEnvelope (pre-send):"));
7538
+ console.log(import_chalk31.default.bold("\nEnvelope (pre-send):"));
7656
7539
  console.log(formatJson(envelope));
7657
7540
  }
7658
7541
  const result = await api.ingest(envelope);
@@ -7673,23 +7556,23 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7673
7556
  });
7674
7557
  return;
7675
7558
  }
7676
- console.log(import_chalk29.default.green("\nDelivered."));
7677
- console.log(`${import_chalk29.default.bold("Event id")}: ${import_chalk29.default.cyan(result.eventId)}`);
7678
- console.log(`${import_chalk29.default.bold("Relationship id")}: ${import_chalk29.default.cyan(result.relationshipId)}`);
7679
- console.log(`${import_chalk29.default.bold("Chain index")}: ${import_chalk29.default.cyan(String(result.relationshipEventIndex))}`);
7680
- console.log(`${import_chalk29.default.bold("Server timestamp")}: ${import_chalk29.default.cyan(result.serverTimestamp)}`);
7681
- console.log(`${import_chalk29.default.bold("Signed message hash")}: ${import_chalk29.default.cyan(result.signedMessageHash)}`);
7682
- console.log(`${import_chalk29.default.bold("Server event hash")}: ${import_chalk29.default.cyan(result.serverEventHash)}`);
7559
+ console.log(import_chalk31.default.green("\nDelivered."));
7560
+ console.log(`${import_chalk31.default.bold("Event id")}: ${import_chalk31.default.cyan(result.eventId)}`);
7561
+ console.log(`${import_chalk31.default.bold("Relationship id")}: ${import_chalk31.default.cyan(result.relationshipId)}`);
7562
+ console.log(`${import_chalk31.default.bold("Chain index")}: ${import_chalk31.default.cyan(String(result.relationshipEventIndex))}`);
7563
+ console.log(`${import_chalk31.default.bold("Server timestamp")}: ${import_chalk31.default.cyan(result.serverTimestamp)}`);
7564
+ console.log(`${import_chalk31.default.bold("Signed message hash")}: ${import_chalk31.default.cyan(result.signedMessageHash)}`);
7565
+ console.log(`${import_chalk31.default.bold("Server event hash")}: ${import_chalk31.default.cyan(result.serverEventHash)}`);
7683
7566
  if (result.prevServerEventHash) {
7684
- console.log(`${import_chalk29.default.bold("Prev server event hash")}: ${import_chalk29.default.cyan(result.prevServerEventHash)}`);
7567
+ console.log(`${import_chalk31.default.bold("Prev server event hash")}: ${import_chalk31.default.cyan(result.prevServerEventHash)}`);
7685
7568
  } else {
7686
- console.log(`${import_chalk29.default.bold("Prev server event hash")}: ${import_chalk29.default.dim("(null \u2014 first event of this relationship)")}`);
7569
+ console.log(`${import_chalk31.default.bold("Prev server event hash")}: ${import_chalk31.default.dim("(null \u2014 first event of this relationship)")}`);
7687
7570
  }
7688
7571
  if (opts.verbose) {
7689
- console.log(import_chalk29.default.bold("\nFull server response:"));
7572
+ console.log(import_chalk31.default.bold("\nFull server response:"));
7690
7573
  console.log(formatJson(result));
7691
7574
  }
7692
- console.log(import_chalk29.default.dim(`
7575
+ console.log(import_chalk31.default.dim(`
7693
7576
  Local sender_sequence advanced to ${nextSequence}.`));
7694
7577
  }
7695
7578
  function parseDecision(raw) {
@@ -7711,8 +7594,8 @@ function parseTtl4(raw) {
7711
7594
  }
7712
7595
  function classifyIdempotencyOutcome(decision, existing) {
7713
7596
  if (!existing) return { kind: "proceed" };
7714
- if (existing.state === import_sdk26.RelationshipStates.ACTIVE) {
7715
- if (decision === import_sdk26.HandshakeDecisions.DECLINE) {
7597
+ if (existing.state === import_sdk29.RelationshipStates.ACTIVE) {
7598
+ if (decision === import_sdk29.HandshakeDecisions.DECLINE) {
7716
7599
  return {
7717
7600
  kind: "error",
7718
7601
  message: `send-handshake-response: relationship ${existing.relationshipId} is already 'active' from a previous ACCEPT. A decline cannot reverse that \u2014 the active relationship is now under FSM control. If you want to terminate, close the relationship explicitly; pass --force to ignore this check and send the decline (which the server will reject with DOM_INVALID_TRANSITION).`
@@ -7720,7 +7603,7 @@ function classifyIdempotencyOutcome(decision, existing) {
7720
7603
  }
7721
7604
  return { kind: "short-circuit" };
7722
7605
  }
7723
- if (existing.state === import_sdk26.RelationshipStates.CLOSED) {
7606
+ if (existing.state === import_sdk29.RelationshipStates.CLOSED) {
7724
7607
  return {
7725
7608
  kind: "error",
7726
7609
  message: `send-handshake-response: relationship ${existing.relationshipId} is CLOSED. Cannot respond to handshake on a terminated relationship \u2014 start a fresh handshake instead.`
@@ -7740,20 +7623,20 @@ async function findExistingRelationship(api, signer, senderDid, recipientDid) {
7740
7623
  }
7741
7624
 
7742
7625
  // src/commands/watch.ts
7743
- var import_chalk30 = __toESM(require("chalk"));
7626
+ var import_chalk32 = __toESM(require("chalk"));
7744
7627
  init_api();
7745
7628
  function registerWatchCommand(root) {
7746
- 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("--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) => {
7629
+ 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) => {
7747
7630
  await runWatch(relationshipId, opts);
7748
7631
  });
7749
7632
  }
7750
7633
  async function runWatch(relationshipId, opts) {
7751
- const local = resolveSenderAgent("watch", opts.server, opts.fromDid);
7634
+ const local = resolveSenderAgent("watch", opts.server, opts.fromDid, opts.from);
7752
7635
  const api = new ArpApiClient(opts.server);
7753
7636
  if (!opts.json) {
7754
- console.log(import_chalk30.default.dim(`Server: ${api.serverUrl}`));
7755
- console.log(import_chalk30.default.dim(`Signer: ${local.did}`));
7756
- console.log(import_chalk30.default.dim(`Watching: ${relationshipId}`));
7637
+ console.log(import_chalk32.default.dim(`Server: ${api.serverUrl}`));
7638
+ console.log(import_chalk32.default.dim(`Signer: ${local.did}`));
7639
+ console.log(import_chalk32.default.dim(`Watching: ${relationshipId}`));
7757
7640
  }
7758
7641
  const controller = new AbortController();
7759
7642
  let userAborted = false;
@@ -7772,7 +7655,7 @@ async function runWatch(relationshipId, opts) {
7772
7655
  }
7773
7656
  if (event.type === "heartbeat") continue;
7774
7657
  if (event.type === "connected") {
7775
- console.log(import_chalk30.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
7658
+ console.log(import_chalk32.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
7776
7659
  continue;
7777
7660
  }
7778
7661
  if (event.type === "envelope") {
@@ -7786,7 +7669,7 @@ async function runWatch(relationshipId, opts) {
7786
7669
  }
7787
7670
  continue;
7788
7671
  }
7789
- console.log(import_chalk30.default.dim(`(unknown event: ${event.type})`));
7672
+ console.log(import_chalk32.default.dim(`(unknown event: ${event.type})`));
7790
7673
  }
7791
7674
  if (!userAborted) {
7792
7675
  throw new Error(`watch ${relationshipId}: stream ended unexpectedly (server may have restarted, or the change stream errored). Re-run to reconnect.`);
@@ -7794,7 +7677,7 @@ async function runWatch(relationshipId, opts) {
7794
7677
  } catch (err) {
7795
7678
  const name = err.name;
7796
7679
  if (name === "AbortError" || userAborted) {
7797
- if (!opts.json) console.log(import_chalk30.default.dim("\nstream closed."));
7680
+ if (!opts.json) console.log(import_chalk32.default.dim("\nstream closed."));
7798
7681
  return;
7799
7682
  }
7800
7683
  throw err;
@@ -7808,21 +7691,21 @@ function formatWatchLine(ev, selfDid, opts = {}) {
7808
7691
  const type = ev.type.padEnd(20);
7809
7692
  const direction = directionLabel2(ev, selfDid, opts);
7810
7693
  const hash = opts.fullIds ? ev.serverEventHash : hashHead4(ev.serverEventHash);
7811
- return `${import_chalk30.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk30.default.cyan(hash)}`;
7694
+ return `${import_chalk32.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk32.default.cyan(hash)}`;
7812
7695
  }
7813
7696
  function directionLabel2(ev, selfDid, opts = {}) {
7814
7697
  const senderHead = opts.fullIds ? ev.senderDid : didHead4(ev.senderDid);
7815
7698
  const recipientHead = opts.fullIds ? ev.recipientDid : didHead4(ev.recipientDid);
7816
- if (ev.senderDid === selfDid) return `${import_chalk30.default.bold("me")} \u2192 ${import_chalk30.default.dim(recipientHead)}`;
7817
- if (ev.recipientDid === selfDid) return `${import_chalk30.default.dim(senderHead)} \u2192 ${import_chalk30.default.bold("me")}`;
7818
- return `${import_chalk30.default.dim(senderHead)} \u2192 ${import_chalk30.default.dim(recipientHead)}`;
7699
+ if (ev.senderDid === selfDid) return `${import_chalk32.default.bold("me")} \u2192 ${import_chalk32.default.dim(recipientHead)}`;
7700
+ if (ev.recipientDid === selfDid) return `${import_chalk32.default.dim(senderHead)} \u2192 ${import_chalk32.default.bold("me")}`;
7701
+ return `${import_chalk32.default.dim(senderHead)} \u2192 ${import_chalk32.default.dim(recipientHead)}`;
7819
7702
  }
7820
7703
  function didHead4(did) {
7821
7704
  if (did.length <= 20) return did;
7822
7705
  return `${did.slice(0, 20)}...`;
7823
7706
  }
7824
7707
  function hashHead4(hash) {
7825
- if (!hash) return import_chalk30.default.dim("(none)");
7708
+ if (!hash) return import_chalk32.default.dim("(none)");
7826
7709
  if (hash.length <= 14) return hash;
7827
7710
  return `${hash.slice(0, 14)}...`;
7828
7711
  }
@@ -7834,12 +7717,12 @@ function formatClock(iso) {
7834
7717
  }
7835
7718
 
7836
7719
  // src/commands/whoami.ts
7837
- var import_chalk31 = __toESM(require("chalk"));
7720
+ var import_chalk33 = __toESM(require("chalk"));
7838
7721
  init_api();
7839
7722
  function registerWhoamiCommand(root) {
7840
7723
  root.command("whoami").description(
7841
7724
  "Identify the local agent: print DID + settlement pubkey + identity pubkey (with --local), and/or fetch the server profile via signed GET /agents/:did. When <did> is omitted, uses the same sole-agent resolution as other signed commands."
7842
- ).argument("[did]", "Agent DID (did:arp:...) \u2014 omit when there is exactly ONE local agent (sole-agent fallback)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Explicit sender DID \u2014 same precedence as the positional arg, surfaced for symmetry with other commands").option(
7725
+ ).argument("[did]", "Agent DID (did:arp:...) \u2014 omit when there is exactly ONE local agent (sole-agent fallback)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Explicit sender DID \u2014 same precedence as the positional arg, surfaced for symmetry with other commands").option("--from <name>", "Signer agent NAME (handle) \u2014 alternative to --from-did, resolved against your local agents").option(
7843
7726
  "--local",
7844
7727
  // Persona scripts want the local settlement pubkey for
7845
7728
  // `--payer-settlement-pubkey` / on-chain ops without a
@@ -7851,7 +7734,8 @@ function registerWhoamiCommand(root) {
7851
7734
  ).option("--json", "JSON output (jq-pipeable). Combines local + server data when --local is unset, or just local when --local is set.", false).action(async (didArg, opts, cmd) => {
7852
7735
  try {
7853
7736
  const explicitDid = didArg ?? opts.fromDid;
7854
- const local = resolveSenderAgent("whoami", opts.server, explicitDid);
7737
+ const explicitFrom = opts.from;
7738
+ const local = resolveSenderAgent("whoami", opts.server, explicitDid, explicitFrom);
7855
7739
  const api = new ArpApiClient(opts.server);
7856
7740
  const credential = readCredential(api.serverUrl);
7857
7741
  const localJson = {
@@ -7864,12 +7748,12 @@ function registerWhoamiCommand(root) {
7864
7748
  if (opts.json) {
7865
7749
  console.log(formatJson({ ...localJson, account: credential ? { wallet: credential.wallet } : null }));
7866
7750
  } else {
7867
- console.log(import_chalk31.default.bold("Local agent:"));
7868
- console.log(` DID: ${import_chalk31.default.cyan(local.did)}`);
7869
- console.log(` Settlement pubkey: ${import_chalk31.default.cyan(local.settlementPublicKeyB58)}`);
7870
- console.log(` Identity pubkey: ${import_chalk31.default.cyan(local.identityPublicKeyB58)}`);
7751
+ console.log(import_chalk33.default.bold("Local agent:"));
7752
+ console.log(` DID: ${import_chalk33.default.cyan(local.did)}`);
7753
+ console.log(` Settlement pubkey: ${import_chalk33.default.cyan(local.settlementPublicKeyB58)}`);
7754
+ console.log(` Identity pubkey: ${import_chalk33.default.cyan(local.identityPublicKeyB58)}`);
7871
7755
  if (local.name) console.log(` Name: ${local.name}`);
7872
- console.log(` Account: ${credential ? import_chalk31.default.cyan(credential.wallet) : import_chalk31.default.dim("not logged in (heyarp login)")}`);
7756
+ console.log(` Account: ${credential ? import_chalk33.default.cyan(credential.wallet) : import_chalk33.default.dim("not logged in (heyarp login)")}`);
7873
7757
  }
7874
7758
  return;
7875
7759
  }
@@ -7887,19 +7771,19 @@ function registerWhoamiCommand(root) {
7887
7771
  if (opts.json) {
7888
7772
  console.log(formatJson({ local: localJson, account, server: agent }));
7889
7773
  } else {
7890
- console.log(import_chalk31.default.dim(`Server: ${api.serverUrl}`));
7891
- console.log(import_chalk31.default.bold("\nLocal agent:"));
7892
- console.log(` DID: ${import_chalk31.default.cyan(local.did)}`);
7893
- console.log(` Settlement pubkey: ${import_chalk31.default.cyan(local.settlementPublicKeyB58)}`);
7894
- console.log(` Identity pubkey: ${import_chalk31.default.cyan(local.identityPublicKeyB58)}`);
7895
- console.log(import_chalk31.default.bold("\nAccount:"));
7774
+ console.log(import_chalk33.default.dim(`Server: ${api.serverUrl}`));
7775
+ console.log(import_chalk33.default.bold("\nLocal agent:"));
7776
+ console.log(` DID: ${import_chalk33.default.cyan(local.did)}`);
7777
+ console.log(` Settlement pubkey: ${import_chalk33.default.cyan(local.settlementPublicKeyB58)}`);
7778
+ console.log(` Identity pubkey: ${import_chalk33.default.cyan(local.identityPublicKeyB58)}`);
7779
+ console.log(import_chalk33.default.bold("\nAccount:"));
7896
7780
  if (account) {
7897
- console.log(` Wallet: ${import_chalk31.default.cyan(account.wallet)}`);
7781
+ console.log(` Wallet: ${import_chalk33.default.cyan(account.wallet)}`);
7898
7782
  console.log(` Agents registered: ${account.agentCount}`);
7899
7783
  } else {
7900
- console.log(` ${import_chalk31.default.dim("not logged in (heyarp login)")}`);
7784
+ console.log(` ${import_chalk33.default.dim("not logged in (heyarp login)")}`);
7901
7785
  }
7902
- console.log(import_chalk31.default.bold("\nServer profile:"));
7786
+ console.log(import_chalk33.default.bold("\nServer profile:"));
7903
7787
  console.log(formatJson(agent));
7904
7788
  }
7905
7789
  } catch (err) {
@@ -7909,9 +7793,49 @@ function registerWhoamiCommand(root) {
7909
7793
  });
7910
7794
  }
7911
7795
 
7796
+ // src/commands/whois.ts
7797
+ var import_sdk30 = require("@heyanon-arp/sdk");
7798
+ var import_chalk34 = __toESM(require("chalk"));
7799
+ init_api();
7800
+ function registerWhoisCommand(root) {
7801
+ 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) => {
7802
+ const api = new ArpApiClient(opts.server);
7803
+ progress(opts.json, import_chalk34.default.dim(`Server: ${api.serverUrl}`));
7804
+ const profile = await resolveProfile(api, input);
7805
+ if (opts.json) {
7806
+ jsonOut(profile);
7807
+ return;
7808
+ }
7809
+ printProfile(profile);
7810
+ });
7811
+ }
7812
+ async function resolveProfile(api, input) {
7813
+ if (input.startsWith("did:arp:")) {
7814
+ if (!(0, import_sdk30.isValidDid)(input)) {
7815
+ throw new Error(`whois: '${input}' starts with did:arp: but is not a valid DID (base58btc-encoded 32-byte Ed25519 pubkey).`);
7816
+ }
7817
+ return api.discoverProfile(input);
7818
+ }
7819
+ const name = (0, import_sdk30.normalizeName)(input);
7820
+ if (!(0, import_sdk30.isValidAgentName)(name)) {
7821
+ throw new Error(`whois: '${input}' is neither a DID (did:arp:...) nor a valid agent name (lowercase a-z0-9_, 3-32 chars).`);
7822
+ }
7823
+ return api.discoverByName(name);
7824
+ }
7825
+ function printProfile(p) {
7826
+ console.log(`${import_chalk34.default.bold("Name")}: ${import_chalk34.default.cyan(p.name ?? "(unnamed)")}`);
7827
+ console.log(`${import_chalk34.default.bold("DID")}: ${import_chalk34.default.cyan(p.did)}`);
7828
+ if (p.description) console.log(`${import_chalk34.default.bold("Description")}: ${p.description}`);
7829
+ if (p.tags.length > 0) console.log(`${import_chalk34.default.bold("Tags")}: ${p.tags.join(", ")}`);
7830
+ console.log(`${import_chalk34.default.bold("Registered")}: ${p.registeredAt}`);
7831
+ const rep = p.reputation;
7832
+ console.log(`${import_chalk34.default.bold("Reputation")}: composite ${rep.scores.composite}/100${rep.computed ? "" : import_chalk34.default.dim(" (cold-start \u2014 no settled cycles yet)")}`);
7833
+ console.log(`${import_chalk34.default.bold("Online")}: ${p.liveness.online ? import_chalk34.default.green("yes") : import_chalk34.default.dim("no")}`);
7834
+ }
7835
+
7912
7836
  // src/commands/work.ts
7913
- var import_sdk27 = require("@heyanon-arp/sdk");
7914
- var import_chalk32 = __toESM(require("chalk"));
7837
+ var import_sdk31 = require("@heyanon-arp/sdk");
7838
+ var import_chalk35 = __toESM(require("chalk"));
7915
7839
  init_api();
7916
7840
  function registerWorkCommands(root) {
7917
7841
  const cmd = root.command("work").description("Work envelopes inside an ACCEPTED delegation: request / respond");
@@ -7919,13 +7843,13 @@ function registerWorkCommands(root) {
7919
7843
  registerRespond(cmd);
7920
7844
  }
7921
7845
  function registerRequest(parent) {
7922
- parent.command("request").description("Send a work_request to <recipient-did> under <delegation-id> (must be ACCEPTED).").argument("<recipient-did>", "Recipient agent DID (the payee \u2014 the OTHER side of the delegation pair)").argument("<delegation-id>", "Parent delegation id (UUID, must be ACCEPTED)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--request-id <id>", "Override the auto-generated request id (must be unique within the delegation)").option(
7846
+ parent.command("request").description("Send a work_request to <recipient-did> under <delegation-id> (must be ACCEPTED).").argument("<recipient>", "Recipient \u2014 agent name (handle) or DID (the payee \u2014 the OTHER side of the delegation pair)").argument("<delegation-id>", "Parent delegation id (UUID, must be ACCEPTED)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--request-id <id>", "Override the auto-generated request id (must be unique within the delegation)").option(
7923
7847
  "--params <json>",
7924
7848
  "JSON object payload as a literal string. Defaults to {}. Mutually exclusive with --params-file. Brittle against shell quoting \u2014 prefer --params-file for non-trivial bodies."
7925
7849
  ).option(
7926
7850
  "--params-file <path>",
7927
7851
  "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."
7928
- ).option("--ttl <seconds>", `Envelope TTL in seconds (max ${import_sdk27.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(
7852
+ ).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(
7929
7853
  "--json",
7930
7854
  '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.',
7931
7855
  false
@@ -7939,24 +7863,24 @@ async function runRequest(recipientDid, delegationId, opts) {
7939
7863
  "work request: --verbose and --json are mutually exclusive. --json emits the structured server response; --verbose adds dumps that would break `--json | jq`."
7940
7864
  );
7941
7865
  }
7942
- requireDid3("work request", recipientDid, "<recipient-did>");
7866
+ recipientDid = await resolveRecipient(opts.server, "work request", recipientDid, { json: opts.json });
7943
7867
  delegationId = requireUuidNormalised3("work request", delegationId, "<delegation-id>");
7944
7868
  const ttlSeconds = parseTtl5("work request", opts.ttl);
7945
7869
  const params = parseParamsInput("work request", opts);
7946
7870
  const requestId = parseRequestId("work request", opts.requestId);
7947
7871
  const api = new ArpApiClient(opts.server);
7948
- const sender = resolveSenderAgent("work request", opts.server, opts.fromDid);
7872
+ const sender = resolveSenderAgent("work request", opts.server, opts.fromDid, opts.from);
7949
7873
  const content = {
7950
7874
  delegation_id: delegationId,
7951
7875
  request_id: requestId,
7952
7876
  params
7953
7877
  };
7954
7878
  const body = { type: "work_request", content };
7955
- progress(opts.json, import_chalk32.default.dim(`Server: ${api.serverUrl}`));
7956
- progress(opts.json, import_chalk32.default.dim(`Sender: ${sender.did}`));
7957
- progress(opts.json, import_chalk32.default.dim(`Recipient: ${recipientDid}`));
7958
- progress(opts.json, import_chalk32.default.dim(`Delegation: ${delegationId}`));
7959
- progress(opts.json, import_chalk32.default.dim(`Request id: ${requestId}`));
7879
+ progress(opts.json, import_chalk35.default.dim(`Server: ${api.serverUrl}`));
7880
+ progress(opts.json, import_chalk35.default.dim(`Sender: ${sender.did}`));
7881
+ progress(opts.json, import_chalk35.default.dim(`Recipient: ${recipientDid}`));
7882
+ progress(opts.json, import_chalk35.default.dim(`Delegation: ${delegationId}`));
7883
+ progress(opts.json, import_chalk35.default.dim(`Request id: ${requestId}`));
7960
7884
  const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
7961
7885
  if (opts.json) {
7962
7886
  jsonOut({
@@ -7973,14 +7897,14 @@ async function runRequest(recipientDid, delegationId, opts) {
7973
7897
  });
7974
7898
  } else {
7975
7899
  printIngestResult3(result);
7976
- console.log(import_chalk32.default.dim(`
7900
+ console.log(import_chalk35.default.dim(`
7977
7901
  The payee can reply with:`));
7978
- console.log(import_chalk32.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --output '<json>'`));
7979
- console.log(import_chalk32.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --error CODE:message`));
7902
+ console.log(import_chalk35.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --output '<json>'`));
7903
+ console.log(import_chalk35.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --error CODE:message`));
7980
7904
  }
7981
7905
  }
7982
7906
  function registerRespond(parent) {
7983
- parent.command("respond").description("Send a work_response under <relationship-id> for <delegation-id> / <request-id>. Payee-only.").argument("<relationship-id>", "Relationship UUID").argument("<delegation-id>", "Parent delegation id (UUID)").argument("<request-id>", "Request id supplied on the work_request").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server").option("--output <json>", "Success payload as a JSON object literal. Mutually exclusive with --error and --output-file.").option(
7907
+ parent.command("respond").description("Send a work_response under <relationship-id> for <delegation-id> / <request-id>. Payee-only.").argument("<relationship-id>", "Relationship UUID").argument("<delegation-id>", "Parent delegation id (UUID)").argument("<request-id>", "Request id supplied on the work_request").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender 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("--output <json>", "Success payload as a JSON object literal. Mutually exclusive with --error and --output-file.").option(
7984
7908
  "--output-file <path>",
7985
7909
  "Read the success payload from a file. Mutually exclusive with --output and --error. Use this for any payload large or quote-heavy enough to fight your shell."
7986
7910
  ).option("--error <code:message>", "Failure payload as `CODE:message`. Mutually exclusive with --output / --output-file.").option("--ttl <seconds>", "Envelope TTL in seconds", "3600").option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
@@ -8002,7 +7926,7 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
8002
7926
  const ttlSeconds = parseTtl5("work respond", opts.ttl);
8003
7927
  const responsePayload = parseResponsePayload("work respond", opts);
8004
7928
  const api = new ArpApiClient(opts.server);
8005
- const sender = resolveSenderAgent("work respond", opts.server, opts.fromDid);
7929
+ const sender = resolveSenderAgent("work respond", opts.server, opts.fromDid, opts.from);
8006
7930
  const signer = makeSigner(sender);
8007
7931
  const recipientDid = await resolveResponseRecipient("work respond", api, signer, { relationshipId, delegationId, requestId, selfDid: sender.did });
8008
7932
  const content = {
@@ -8011,13 +7935,13 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
8011
7935
  ...responsePayload
8012
7936
  };
8013
7937
  const body = { type: "work_response", content };
8014
- progress(opts.json, import_chalk32.default.dim(`Server: ${api.serverUrl}`));
8015
- progress(opts.json, import_chalk32.default.dim(`Sender: ${sender.did}`));
8016
- progress(opts.json, import_chalk32.default.dim(`Recipient: ${recipientDid}`));
8017
- progress(opts.json, import_chalk32.default.dim(`Relationship: ${relationshipId}`));
8018
- progress(opts.json, import_chalk32.default.dim(`Delegation: ${delegationId}`));
8019
- progress(opts.json, import_chalk32.default.dim(`Request id: ${requestId}`));
8020
- progress(opts.json, import_chalk32.default.dim(`Outcome: ${responsePayload.output ? "success" : "error"}`));
7938
+ progress(opts.json, import_chalk35.default.dim(`Server: ${api.serverUrl}`));
7939
+ progress(opts.json, import_chalk35.default.dim(`Sender: ${sender.did}`));
7940
+ progress(opts.json, import_chalk35.default.dim(`Recipient: ${recipientDid}`));
7941
+ progress(opts.json, import_chalk35.default.dim(`Relationship: ${relationshipId}`));
7942
+ progress(opts.json, import_chalk35.default.dim(`Delegation: ${delegationId}`));
7943
+ progress(opts.json, import_chalk35.default.dim(`Request id: ${requestId}`));
7944
+ progress(opts.json, import_chalk35.default.dim(`Outcome: ${responsePayload.output ? "success" : "error"}`));
8021
7945
  const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
8022
7946
  if (opts.json) {
8023
7947
  jsonOut({
@@ -8039,26 +7963,26 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
8039
7963
  async function sendWorkEnvelope(args) {
8040
7964
  const nextSequence = (args.sender.lastSenderSequence ?? 0) + 1;
8041
7965
  const protectedBlock = {
8042
- protocol_version: import_sdk27.CURRENT_PROTOCOL_VERSION,
8043
- purpose: import_sdk27.Purpose.ENVELOPE,
8044
- message_id: (0, import_sdk27.uuidV4)(),
7966
+ protocol_version: import_sdk31.CURRENT_PROTOCOL_VERSION,
7967
+ purpose: import_sdk31.Purpose.ENVELOPE,
7968
+ message_id: (0, import_sdk31.uuidV4)(),
8045
7969
  sender_did: args.sender.did,
8046
7970
  recipient_did: args.recipientDid,
8047
7971
  relationship_id: null,
8048
7972
  sender_sequence: nextSequence,
8049
- sender_nonce: (0, import_sdk27.senderNonce)(),
8050
- timestamp: (0, import_sdk27.rfc3339)(),
8051
- expires_at: (0, import_sdk27.expiresAt)(args.ttlSeconds),
7973
+ sender_nonce: (0, import_sdk31.senderNonce)(),
7974
+ timestamp: (0, import_sdk31.rfc3339)(),
7975
+ expires_at: (0, import_sdk31.expiresAt)(args.ttlSeconds),
8052
7976
  delivery_id: null
8053
7977
  };
8054
7978
  const signer = makeSigner(args.sender);
8055
- const envelope = (0, import_sdk27.signEnvelope)({
7979
+ const envelope = (0, import_sdk31.signEnvelope)({
8056
7980
  protected: protectedBlock,
8057
7981
  body: args.body,
8058
7982
  identitySecretKey: signer.identitySecretKey
8059
7983
  });
8060
7984
  if (args.verbose) {
8061
- console.log(import_chalk32.default.bold("\nEnvelope (pre-send):"));
7985
+ console.log(import_chalk35.default.bold("\nEnvelope (pre-send):"));
8062
7986
  console.log(formatJson(envelope));
8063
7987
  }
8064
7988
  try {
@@ -8066,7 +7990,7 @@ async function sendWorkEnvelope(args) {
8066
7990
  updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
8067
7991
  return result;
8068
7992
  } catch (err) {
8069
- if (err instanceof ApiError && (0, import_sdk27.isPostCommitErrorCode)(err.payload.code)) {
7993
+ if (err instanceof ApiError && (0, import_sdk31.isPostCommitErrorCode)(err.payload.code)) {
8070
7994
  updateAgentLocal(args.server, args.sender.did, { lastSenderSequence: nextSequence });
8071
7995
  }
8072
7996
  throw err;
@@ -8078,7 +8002,7 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
8078
8002
  const page = await api.listWorkLogs(args.relationshipId, signer, { delegationId: args.delegationId, limit: 100, after });
8079
8003
  const row = page.find((w) => w.requestId === args.requestId);
8080
8004
  if (row) {
8081
- if (row.state !== import_sdk27.WorkLogStates.REQUESTED) {
8005
+ if (row.state !== import_sdk31.WorkLogStates.REQUESTED) {
8082
8006
  throw new Error(
8083
8007
  `${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.`
8084
8008
  );
@@ -8098,12 +8022,12 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
8098
8022
  );
8099
8023
  }
8100
8024
  function printIngestResult3(result) {
8101
- console.log(import_chalk32.default.green("\nDelivered."));
8102
- console.log(`${import_chalk32.default.bold("Event id")}: ${import_chalk32.default.cyan(result.eventId)}`);
8103
- console.log(`${import_chalk32.default.bold("Relationship id")}: ${import_chalk32.default.cyan(result.relationshipId)}`);
8104
- console.log(`${import_chalk32.default.bold("Chain index")}: ${import_chalk32.default.cyan(String(result.relationshipEventIndex))}`);
8105
- console.log(`${import_chalk32.default.bold("Server timestamp")}: ${import_chalk32.default.cyan(result.serverTimestamp)}`);
8106
- console.log(`${import_chalk32.default.bold("Server event hash")}: ${import_chalk32.default.cyan(result.serverEventHash)}`);
8025
+ console.log(import_chalk35.default.green("\nDelivered."));
8026
+ console.log(`${import_chalk35.default.bold("Event id")}: ${import_chalk35.default.cyan(result.eventId)}`);
8027
+ console.log(`${import_chalk35.default.bold("Relationship id")}: ${import_chalk35.default.cyan(result.relationshipId)}`);
8028
+ console.log(`${import_chalk35.default.bold("Chain index")}: ${import_chalk35.default.cyan(String(result.relationshipEventIndex))}`);
8029
+ console.log(`${import_chalk35.default.bold("Server timestamp")}: ${import_chalk35.default.cyan(result.serverTimestamp)}`);
8030
+ console.log(`${import_chalk35.default.bold("Server event hash")}: ${import_chalk35.default.cyan(result.serverEventHash)}`);
8107
8031
  }
8108
8032
  function parseJsonObject(cmdName, flagName, raw) {
8109
8033
  let parsed;
@@ -8195,7 +8119,7 @@ function parseTtl5(cmdName, raw) {
8195
8119
  }
8196
8120
  function parseRequestId(cmdName, raw) {
8197
8121
  if (raw === void 0 || raw === "") {
8198
- return (0, import_sdk27.uuidV4)();
8122
+ return (0, import_sdk31.uuidV4)();
8199
8123
  }
8200
8124
  if (raw.length === 0) {
8201
8125
  throw new Error(`${cmdName}: --request-id must be a non-empty string`);
@@ -8209,19 +8133,14 @@ function requireUuidNormalised3(cmdName, raw, label) {
8209
8133
  function requireUuid4(cmdName, raw, label) {
8210
8134
  requireUuid(cmdName, raw, label);
8211
8135
  }
8212
- function requireDid3(cmdName, did, label) {
8213
- if (typeof did !== "string" || !did.startsWith("did:arp:") || did.length <= "did:arp:".length) {
8214
- throw new Error(`${cmdName}: ${label} must look like 'did:arp:...' (got '${did}')`);
8215
- }
8216
- }
8217
8136
 
8218
8137
  // src/commands/work-list.ts
8219
- var import_sdk28 = require("@heyanon-arp/sdk");
8220
- var import_chalk33 = __toESM(require("chalk"));
8138
+ var import_sdk32 = require("@heyanon-arp/sdk");
8139
+ var import_chalk36 = __toESM(require("chalk"));
8221
8140
  init_api();
8222
- var ALLOWED_STATES3 = new Set(import_sdk28.WORK_LOG_STATES);
8141
+ var ALLOWED_STATES3 = new Set(import_sdk32.WORK_LOG_STATES);
8223
8142
  function registerWorkListCommand(root) {
8224
- 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(
8143
+ 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(
8225
8144
  "--verbose",
8226
8145
  'After the summary, print a framed "Full work-log payloads (N rows)" block \u2014 each row labelled with full delegationId + requestId and dumped as JSON, including `requestParams` (the work_request payload the worker was asked) and `responseOutput` / `responseError`. Mutually exclusive with --json.',
8227
8146
  false
@@ -8242,11 +8161,11 @@ async function runWorkList(relationshipId, opts) {
8242
8161
  const limit = parseLimit7(opts.limit);
8243
8162
  const state = parseState3(opts.state);
8244
8163
  const api = new ArpApiClient(opts.server);
8245
- const sender = resolveSenderAgent("work-list", opts.server, opts.fromDid);
8164
+ const sender = resolveSenderAgent("work-list", opts.server, opts.fromDid, opts.from);
8246
8165
  if (!opts.json) {
8247
- console.log(import_chalk33.default.dim(`Server: ${api.serverUrl}`));
8248
- console.log(import_chalk33.default.dim(`Signer: ${sender.did}`));
8249
- console.log(import_chalk33.default.dim(`Relationship: ${relationshipId}`));
8166
+ console.log(import_chalk36.default.dim(`Server: ${api.serverUrl}`));
8167
+ console.log(import_chalk36.default.dim(`Signer: ${sender.did}`));
8168
+ console.log(import_chalk36.default.dim(`Relationship: ${relationshipId}`));
8250
8169
  }
8251
8170
  const query = { limit };
8252
8171
  if (state) query.state = state;
@@ -8259,7 +8178,7 @@ async function runWorkList(relationshipId, opts) {
8259
8178
  return;
8260
8179
  }
8261
8180
  if (rows.length === 0) {
8262
- console.log(import_chalk33.default.dim("\n(no work-logs for this relationship)"));
8181
+ console.log(import_chalk36.default.dim("\n(no work-logs for this relationship)"));
8263
8182
  return;
8264
8183
  }
8265
8184
  console.log("");
@@ -8276,36 +8195,36 @@ async function runWorkList(relationshipId, opts) {
8276
8195
  }));
8277
8196
  }
8278
8197
  const lastId = rows[rows.length - 1].id;
8279
- console.log(import_chalk33.default.dim(`
8198
+ console.log(import_chalk36.default.dim(`
8280
8199
  ${rows.length} work-log row(s). Paginate with --after ${lastId}.`));
8281
8200
  }
8282
8201
  function formatWorkLogLine(w, selfDid, opts = {}) {
8283
8202
  const delegationPart = opts.fullIds ? w.delegationId : idHead3(w.delegationId);
8284
8203
  const requestPart = opts.fullIds ? w.requestId : truncate3(w.requestId, 16);
8285
- const id = import_chalk33.default.bold(`${delegationPart}/${requestPart}`);
8204
+ const id = import_chalk36.default.bold(`${delegationPart}/${requestPart}`);
8286
8205
  const state = colorState2(w.state).padEnd(stateColumnWidth2());
8287
8206
  const peerCallerHead = opts.fullIds ? w.callerDid : didHead5(w.callerDid);
8288
8207
  const peerPayeeHead = opts.fullIds ? w.payeeDid : didHead5(w.payeeDid);
8289
- const direction = w.callerDid === selfDid ? `${import_chalk33.default.bold("me")} \u2192 ${import_chalk33.default.dim(peerPayeeHead)}` : `${import_chalk33.default.dim(peerCallerHead)} \u2192 ${import_chalk33.default.bold("me")}`;
8208
+ const direction = w.callerDid === selfDid ? `${import_chalk36.default.bold("me")} \u2192 ${import_chalk36.default.dim(peerPayeeHead)}` : `${import_chalk36.default.dim(peerCallerHead)} \u2192 ${import_chalk36.default.bold("me")}`;
8290
8209
  const outcome = formatOutcome(w);
8291
8210
  return `${id} ${state} ${direction} ${outcome}`;
8292
8211
  }
8293
8212
  function colorState2(s) {
8294
8213
  switch (s) {
8295
- case import_sdk28.WorkLogStates.REQUESTED:
8296
- return import_chalk33.default.yellow("requested");
8297
- case import_sdk28.WorkLogStates.RESPONDED:
8298
- return import_chalk33.default.green("responded");
8214
+ case import_sdk32.WorkLogStates.REQUESTED:
8215
+ return import_chalk36.default.yellow("requested");
8216
+ case import_sdk32.WorkLogStates.RESPONDED:
8217
+ return import_chalk36.default.green("responded");
8299
8218
  }
8300
8219
  }
8301
8220
  function stateColumnWidth2() {
8302
8221
  return 9;
8303
8222
  }
8304
8223
  function formatOutcome(w) {
8305
- if (w.state === import_sdk28.WorkLogStates.REQUESTED) return import_chalk33.default.dim("(in flight)");
8306
- if (w.responseError) return import_chalk33.default.red(`error ${w.responseError.code}: ${truncate3(w.responseError.message, 32)}`);
8307
- if (w.responseOutput) return import_chalk33.default.cyan("ok");
8308
- return import_chalk33.default.dim("(empty response)");
8224
+ if (w.state === import_sdk32.WorkLogStates.REQUESTED) return import_chalk36.default.dim("(in flight)");
8225
+ if (w.responseError) return import_chalk36.default.red(`error ${w.responseError.code}: ${truncate3(w.responseError.message, 32)}`);
8226
+ if (w.responseOutput) return import_chalk36.default.cyan("ok");
8227
+ return import_chalk36.default.dim("(empty response)");
8309
8228
  }
8310
8229
  function idHead3(id) {
8311
8230
  if (id.length <= 12) return id;
@@ -8412,6 +8331,8 @@ async function main() {
8412
8331
  registerAssetsCommand(program);
8413
8332
  registerEscrowCommands(program);
8414
8333
  registerWhoamiCommand(program);
8334
+ registerWhoisCommand(program);
8335
+ registerNameCommand(program);
8415
8336
  registerLifecycleCommands(program);
8416
8337
  registerSendHandshakeCommand(program);
8417
8338
  registerSendHandshakeResponseCommand(program);