@heyanon-arp/cli 0.0.26 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -736,7 +736,7 @@ var import_commander = require("commander");
736
736
  // package.json
737
737
  var package_default = {
738
738
  name: "@heyanon-arp/cli",
739
- version: "0.0.26",
739
+ version: "0.0.27",
740
740
  description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
741
741
  license: "MIT",
742
742
  keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
@@ -7403,9 +7403,258 @@ function bar(score) {
7403
7403
  return `${"\u2588".repeat(filled)}${"\u2591".repeat(10 - filled)}`;
7404
7404
  }
7405
7405
 
7406
+ // src/commands/selftest.ts
7407
+ var import_node_fs10 = require("fs");
7408
+ var import_node_os2 = require("os");
7409
+ var import_node_path7 = require("path");
7410
+ var import_web33 = require("@solana/web3.js");
7411
+ var import_chalk31 = __toESM(require("chalk"));
7412
+ init_api();
7413
+ var LIVENESS_THRESHOLD_SECONDS = 15 * 60;
7414
+ var DEFAULT_MIN_SOL = { worker: 1, both: 1, buyer: 1 };
7415
+ function registerSelftestCommand(root) {
7416
+ root.command("selftest").description(
7417
+ "Self-check: is THIS agent set up + operational (shield, login, registration, funding, skills, worker monitor)? No DID arg. Exit 1 only on a definite failure."
7418
+ ).option("--role <role>", "buyer | worker | both \u2014 scopes role-specific checks (default: inferred from installed skills, else both)").option("--skills-dir <path>", "Extra directory to search for the arp-*-flow skill files (in addition to $ARP_SKILLS_DIR and known framework dirs)").option("--min-sol <n>", "Minimum settlement balance in SOL to pass the funding check (default: 1.0)").option("--stall-min <n>", "Worker heartbeat freshness window in minutes; the file must be newer than 2\xD7 this (default: 5)", "5").option("--rpc-url <url>", "Solana RPC for the funding check (default: --rpc-url > ARP_ESCROW_RPC_URL > config rpcUrl > built-in)").option("--server <url>", "Override ARP server base URL").option("--json", "Machine-readable: single JSON object on stdout. Pipe-safe.", false).action(async (opts) => {
7419
+ await runSelftest(opts);
7420
+ });
7421
+ }
7422
+ async function runSelftest(opts) {
7423
+ const result = await selftest(opts);
7424
+ if (opts.json) {
7425
+ console.log(JSON.stringify(result));
7426
+ } else {
7427
+ console.log(formatSelftestReport(result));
7428
+ }
7429
+ if (!result.ok) process.exitCode = 1;
7430
+ }
7431
+ async function selftest(opts, deps = {}) {
7432
+ const api = deps.api ?? new ArpApiClient(opts.server);
7433
+ const server = api.serverUrl;
7434
+ const skillDirs = skillSearchDirs(opts.skillsDir);
7435
+ const role = resolveRole(opts.role, skillDirs);
7436
+ const checks = [];
7437
+ checks.push(checkOpengrep());
7438
+ checks.push(await checkLogin(api));
7439
+ checks.push(checkSkills(skillDirs, role));
7440
+ const agents = deps.agents ?? listAgents().filter((r) => r.serverUrl === server).map((r) => r.agent);
7441
+ if (agents.length === 0) {
7442
+ checks.push({ id: "registration", status: "fail", detail: `no local agent registered for ${server}`, fix: "heyarp register (or heyarp recover --from-keys)" });
7443
+ } else {
7444
+ for (const agent of agents) {
7445
+ checks.push(await checkRegistration(api, agent));
7446
+ checks.push(await checkFunding(agent, role, opts));
7447
+ if (role === "worker" || role === "both") checks.push(await checkWorkerLiveness(api, agent, opts));
7448
+ }
7449
+ }
7450
+ const ok = !checks.some((c) => c.status === "fail");
7451
+ return { server, role, ok, checks };
7452
+ }
7453
+ function checkOpengrep() {
7454
+ const heyshieldHome = process.env.HEYSHIELD_HOME && process.env.HEYSHIELD_HOME.length > 0 ? process.env.HEYSHIELD_HOME : (0, import_node_path7.join)((0, import_node_os2.homedir)(), ".heyshield");
7455
+ const bin = (0, import_node_path7.join)(heyshieldHome, "opengrep", "bin", "opengrep");
7456
+ if ((0, import_node_fs10.existsSync)(bin)) return { id: "opengrep", status: "pass", detail: `opengrep present (${bin})` };
7457
+ return { id: "opengrep", status: "warn", detail: `opengrep not found at ${bin} \u2014 L2 code/script scan unavailable (L0/L4 still active)`, fix: "heyshield install-opengrep" };
7458
+ }
7459
+ async function checkLogin(api) {
7460
+ const cred = readCredential(api.serverUrl);
7461
+ if (!cred) return { id: "login", status: "fail", detail: `not logged in to ${api.serverUrl}`, fix: "heyarp login" };
7462
+ try {
7463
+ await api.accountWhoami(cred.token);
7464
+ return { id: "login", status: "pass", detail: `logged in as ${cred.wallet} (token valid)` };
7465
+ } catch (err) {
7466
+ if (err instanceof ApiError && (err.status === 401 || err.status === 403)) {
7467
+ return {
7468
+ id: "login",
7469
+ status: "fail",
7470
+ detail: `login token for ${api.serverUrl} was rejected (${err.message}) \u2014 revoked/expired`,
7471
+ fix: "heyarp login (then re-register with --from-keys if the agent is also gone)"
7472
+ };
7473
+ }
7474
+ return {
7475
+ id: "login",
7476
+ status: "unknown",
7477
+ detail: `credential present (${cred.wallet}) but token NOT verified \u2014 server unreachable (${msg(err)})`,
7478
+ fix: "re-run online; if a later request is rejected, run `heyarp login`"
7479
+ };
7480
+ }
7481
+ }
7482
+ async function checkRegistration(api, agent) {
7483
+ try {
7484
+ await api.getDidDocument(agent.did);
7485
+ return { id: "registration", did: agent.did, status: "pass", detail: `${agent.did} registered on ${api.serverUrl}` };
7486
+ } catch (err) {
7487
+ if (err instanceof ApiError && err.status === 404) {
7488
+ return {
7489
+ id: "registration",
7490
+ did: agent.did,
7491
+ status: "fail",
7492
+ detail: `${agent.did} not found on ${api.serverUrl} \u2014 local keys exist but the server doesn't know this DID (server reset?)`,
7493
+ fix: "heyarp login + heyarp register --from-keys <exported-keys>"
7494
+ };
7495
+ }
7496
+ return { id: "registration", did: agent.did, status: "unknown", detail: `${agent.did} present locally; server registration not verified (${msg(err)})` };
7497
+ }
7498
+ }
7499
+ async function checkFunding(agent, role, opts) {
7500
+ const min = parseMinSol(opts.minSol, role);
7501
+ try {
7502
+ const rpc = resolveRpcUrl({ rpcUrl: opts.rpcUrl });
7503
+ const conn = new import_web33.Connection(rpc, "confirmed");
7504
+ const lamports = await conn.getBalance(new import_web33.PublicKey(agent.settlementPublicKeyB58));
7505
+ const sol = lamports / 1e9;
7506
+ if (sol >= min) return { id: "funding", did: agent.did, status: "pass", detail: `settlement ${agent.settlementPublicKeyB58} has ${sol} SOL (>= ${min})` };
7507
+ const low = role === "buyer" ? "warn" : "fail";
7508
+ return {
7509
+ id: "funding",
7510
+ did: agent.did,
7511
+ status: low,
7512
+ detail: `settlement ${agent.settlementPublicKeyB58} has ${sol} SOL (< ${min} needed)`,
7513
+ fix: "fund the settlement key with SOL (faucet / transfer)"
7514
+ };
7515
+ } catch (err) {
7516
+ return {
7517
+ id: "funding",
7518
+ did: agent.did,
7519
+ status: "unknown",
7520
+ detail: `could not read settlement balance for ${agent.did} (${msg(err)})`,
7521
+ fix: "set a reachable RPC: heyarp config set rpcUrl <url> (or --rpc-url)"
7522
+ };
7523
+ }
7524
+ }
7525
+ function checkSkills(dirs, role) {
7526
+ const roles = role === "both" ? ["worker", "buyer"] : [role];
7527
+ const missing = [];
7528
+ const foundAt = [];
7529
+ for (const r of roles) {
7530
+ const hit = findSkill(dirs, r);
7531
+ if (hit) foundAt.push(`${r}\u2192${hit}`);
7532
+ else missing.push(r);
7533
+ }
7534
+ if (missing.length === 0) return { id: "skills", status: "pass", detail: `found: ${foundAt.join(", ")}` };
7535
+ return {
7536
+ id: "skills",
7537
+ status: "unknown",
7538
+ detail: `skill(s) not found in known dirs for: ${missing.map((r) => `arp-${r}-flow`).join(", ")} (searched ${dirs.join(", ")})`,
7539
+ fix: "install the skill, or point selftest at it: --skills-dir <path> / export ARP_SKILLS_DIR=<path>"
7540
+ };
7541
+ }
7542
+ async function checkWorkerLiveness(api, agent, opts) {
7543
+ const stallMin = parsePositive(opts.stallMin, 5);
7544
+ const windowSec = stallMin * 60 * 2;
7545
+ const hbPath = process.env.ARP_WORKER_DISPATCHED && process.env.ARP_WORKER_DISPATCHED.length > 0 ? process.env.ARP_WORKER_DISPATCHED : (0, import_node_path7.join)((0, import_node_os2.homedir)(), ".heyarp-worker", "dispatched.txt");
7546
+ let hbFresh = false;
7547
+ let hbNote = "no local heartbeat file";
7548
+ const hbExists = (0, import_node_fs10.existsSync)(hbPath);
7549
+ if (hbExists) {
7550
+ const ageSec = Math.max(0, Math.floor((Date.now() - (0, import_node_fs10.statSync)(hbPath).mtimeMs) / 1e3));
7551
+ hbFresh = ageSec <= windowSec;
7552
+ hbNote = `heartbeat ${Math.floor(ageSec / 60)}m old`;
7553
+ }
7554
+ let serverSeen = "unknown";
7555
+ let serverNote = "server activity not checked";
7556
+ try {
7557
+ const s = await api.getActivitySummary(agent.did);
7558
+ const asOf = new Date(s.asOf).getTime();
7559
+ const seenAge = s.lastSeenAt ? Math.floor((asOf - new Date(s.lastSeenAt).getTime()) / 1e3) : null;
7560
+ const evtAge = s.lastEventAt ? Math.floor((asOf - new Date(s.lastEventAt).getTime()) / 1e3) : null;
7561
+ const recent = seenAge !== null && seenAge <= LIVENESS_THRESHOLD_SECONDS || evtAge !== null && evtAge <= LIVENESS_THRESHOLD_SECONDS || s.inboxStreamActive === true;
7562
+ serverSeen = recent ? "listening" : "dormant";
7563
+ serverNote = recent ? `server saw activity ${seenAge ?? evtAge ?? 0}s ago` : "server: no recent activity";
7564
+ } catch (err) {
7565
+ serverSeen = "unknown";
7566
+ serverNote = `server activity not available (${msg(err)})`;
7567
+ }
7568
+ const detail = `${hbNote}; ${serverNote}`;
7569
+ if (hbFresh || serverSeen === "listening") return { id: "worker_liveness", did: agent.did, status: "pass", detail };
7570
+ if (serverSeen === "dormant" || hbExists) {
7571
+ return {
7572
+ id: "worker_liveness",
7573
+ did: agent.did,
7574
+ status: "warn",
7575
+ detail: `${detail} \u2014 monitor may not be running`,
7576
+ fix: "start the worker / verify your cron is invoking arp_worker_watch.sh every ~1m"
7577
+ };
7578
+ }
7579
+ return {
7580
+ id: "worker_liveness",
7581
+ did: agent.did,
7582
+ status: "unknown",
7583
+ detail: `${detail} \u2014 no liveness signal yet (fresh install or offline)`,
7584
+ fix: "start the worker and re-run selftest"
7585
+ };
7586
+ }
7587
+ var msg = (err) => err instanceof Error ? err.message : String(err);
7588
+ function skillSearchDirs(extra) {
7589
+ const dirs = [];
7590
+ if (process.env.ARP_SKILLS_DIR && process.env.ARP_SKILLS_DIR.length > 0) dirs.push(process.env.ARP_SKILLS_DIR);
7591
+ if (extra && extra.length > 0) dirs.push(extra);
7592
+ const home = (0, import_node_os2.homedir)();
7593
+ dirs.push((0, import_node_path7.join)(home, ".claude", "skills"), (0, import_node_path7.join)(home, ".hermes", "skills"), (0, import_node_path7.join)(home, ".openclaw", "skills"));
7594
+ return dirs;
7595
+ }
7596
+ function findSkill(dirs, role) {
7597
+ const base = `arp-${role}-flow`;
7598
+ for (const d of dirs) {
7599
+ const candidates = [(0, import_node_path7.join)(d, base, "SKILL.md"), (0, import_node_path7.join)(d, `${base}.md`), (0, import_node_path7.join)(d, base)];
7600
+ for (const c of candidates) {
7601
+ if ((0, import_node_fs10.existsSync)(c)) return c;
7602
+ }
7603
+ }
7604
+ return null;
7605
+ }
7606
+ function resolveRole(flag, skillDirs) {
7607
+ if (flag === "worker" || flag === "buyer" || flag === "both") return flag;
7608
+ const hasWorker = findSkill(skillDirs, "worker") !== null;
7609
+ const hasBuyer = findSkill(skillDirs, "buyer") !== null;
7610
+ if (hasWorker && !hasBuyer) return "worker";
7611
+ if (hasBuyer && !hasWorker) return "buyer";
7612
+ return "both";
7613
+ }
7614
+ function parseMinSol(raw, role) {
7615
+ if (raw !== void 0 && raw !== "") {
7616
+ const n = Number.parseFloat(raw);
7617
+ if (Number.isFinite(n) && n >= 0) return n;
7618
+ }
7619
+ return DEFAULT_MIN_SOL[role];
7620
+ }
7621
+ function parsePositive(raw, fallback) {
7622
+ if (raw !== void 0 && raw !== "") {
7623
+ const n = Number.parseFloat(raw);
7624
+ if (Number.isFinite(n) && n > 0) return n;
7625
+ }
7626
+ return fallback;
7627
+ }
7628
+ var ICON = { pass: import_chalk31.default.green("\u2713"), warn: import_chalk31.default.yellow("\u26A0"), unknown: import_chalk31.default.dim("?"), fail: import_chalk31.default.red("\u2717") };
7629
+ function formatSelftestReport(r) {
7630
+ const lines = [];
7631
+ lines.push(`${import_chalk31.default.dim("Server:")} ${r.server} ${import_chalk31.default.dim("Role:")} ${r.role}`);
7632
+ const render = (c, indent) => {
7633
+ lines.push(`${indent}${ICON[c.status]} ${import_chalk31.default.bold(c.id)} ${c.detail}`);
7634
+ if (c.fix && c.status !== "pass") lines.push(`${indent} ${import_chalk31.default.dim("fix:")} ${c.fix}`);
7635
+ };
7636
+ lines.push("");
7637
+ for (const c of r.checks.filter((c2) => !c2.did)) render(c, " ");
7638
+ const dids = [...new Set(r.checks.filter((c) => c.did).map((c) => c.did))];
7639
+ for (const did of dids) {
7640
+ lines.push("");
7641
+ lines.push(` ${import_chalk31.default.dim("agent")} ${did}`);
7642
+ for (const c of r.checks.filter((c2) => c2.did === did)) render(c, " ");
7643
+ }
7644
+ lines.push("");
7645
+ const fails = r.checks.filter((c) => c.status === "fail").length;
7646
+ const advisories = r.checks.filter((c) => c.status === "warn" || c.status === "unknown").length;
7647
+ if (r.ok) {
7648
+ lines.push(`${import_chalk31.default.bold("Verdict:")} ${import_chalk31.default.green("READY")}${advisories > 0 ? import_chalk31.default.dim(` (${advisories} advisory)`) : ""}`);
7649
+ } else {
7650
+ lines.push(`${import_chalk31.default.bold("Verdict:")} ${import_chalk31.default.red("NOT READY")} \u2014 ${fails} blocking check(s) failed`);
7651
+ }
7652
+ return lines.join("\n");
7653
+ }
7654
+
7406
7655
  // src/commands/send-handshake.ts
7407
7656
  var import_sdk28 = require("@heyanon-arp/sdk");
7408
- var import_chalk31 = __toESM(require("chalk"));
7657
+ var import_chalk32 = __toESM(require("chalk"));
7409
7658
  init_api();
7410
7659
  function registerSendHandshakeCommand(root) {
7411
7660
  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("--require-online", "Abort (exit 1, CLI_RECIPIENT_OFFLINE) if the recipient is not reachable now, instead of warning and sending to their inbox", false).option("--verbose", "Print the full envelope before sending and the full server response. Mutually exclusive with --json.", false).option(
@@ -7425,10 +7674,10 @@ async function runSendHandshake(recipientDid, opts) {
7425
7674
  recipientDid = await resolveRecipient(opts.server, "send-handshake", recipientDid, { json: opts.json });
7426
7675
  const ttlSeconds = parseTtl3(opts.ttl);
7427
7676
  const api = new ArpApiClient(opts.server);
7428
- progress(opts.json, import_chalk31.default.dim(`Server: ${api.serverUrl}`));
7677
+ progress(opts.json, import_chalk32.default.dim(`Server: ${api.serverUrl}`));
7429
7678
  const sender = resolveSenderAgent("send-handshake", opts.server, opts.fromDid, opts.from);
7430
- progress(opts.json, import_chalk31.default.dim(`Sender: ${sender.did}`));
7431
- progress(opts.json, import_chalk31.default.dim(`Recipient: ${recipientDid}`));
7679
+ progress(opts.json, import_chalk32.default.dim(`Sender: ${sender.did}`));
7680
+ progress(opts.json, import_chalk32.default.dim(`Recipient: ${recipientDid}`));
7432
7681
  await guardRecipientReachable(api, recipientDid, { requireOnline: opts.requireOnline });
7433
7682
  const content = {};
7434
7683
  if (opts.greeting) content.greeting = opts.greeting;
@@ -7455,7 +7704,7 @@ async function runSendHandshake(recipientDid, opts) {
7455
7704
  identitySecretKey: signer.identitySecretKey
7456
7705
  });
7457
7706
  if (opts.verbose) {
7458
- console.log(import_chalk31.default.bold("\nEnvelope (pre-send):"));
7707
+ console.log(import_chalk32.default.bold("\nEnvelope (pre-send):"));
7459
7708
  console.log(formatJson(envelope));
7460
7709
  }
7461
7710
  const result = await api.ingest(envelope);
@@ -7475,23 +7724,23 @@ async function runSendHandshake(recipientDid, opts) {
7475
7724
  });
7476
7725
  return;
7477
7726
  }
7478
- console.log(import_chalk31.default.green("\nDelivered."));
7479
- console.log(`${import_chalk31.default.bold("Event id")}: ${import_chalk31.default.cyan(result.eventId)}`);
7480
- console.log(`${import_chalk31.default.bold("Relationship id")}: ${import_chalk31.default.cyan(result.relationshipId)}`);
7481
- console.log(`${import_chalk31.default.bold("Chain index")}: ${import_chalk31.default.cyan(String(result.relationshipEventIndex))}`);
7482
- console.log(`${import_chalk31.default.bold("Server timestamp")}: ${import_chalk31.default.cyan(result.serverTimestamp)}`);
7483
- console.log(`${import_chalk31.default.bold("Signed message hash")}: ${import_chalk31.default.cyan(result.signedMessageHash)}`);
7484
- console.log(`${import_chalk31.default.bold("Server event hash")}: ${import_chalk31.default.cyan(result.serverEventHash)}`);
7727
+ console.log(import_chalk32.default.green("\nDelivered."));
7728
+ console.log(`${import_chalk32.default.bold("Event id")}: ${import_chalk32.default.cyan(result.eventId)}`);
7729
+ console.log(`${import_chalk32.default.bold("Relationship id")}: ${import_chalk32.default.cyan(result.relationshipId)}`);
7730
+ console.log(`${import_chalk32.default.bold("Chain index")}: ${import_chalk32.default.cyan(String(result.relationshipEventIndex))}`);
7731
+ console.log(`${import_chalk32.default.bold("Server timestamp")}: ${import_chalk32.default.cyan(result.serverTimestamp)}`);
7732
+ console.log(`${import_chalk32.default.bold("Signed message hash")}: ${import_chalk32.default.cyan(result.signedMessageHash)}`);
7733
+ console.log(`${import_chalk32.default.bold("Server event hash")}: ${import_chalk32.default.cyan(result.serverEventHash)}`);
7485
7734
  if (result.prevServerEventHash) {
7486
- console.log(`${import_chalk31.default.bold("Prev server event hash")}: ${import_chalk31.default.cyan(result.prevServerEventHash)}`);
7735
+ console.log(`${import_chalk32.default.bold("Prev server event hash")}: ${import_chalk32.default.cyan(result.prevServerEventHash)}`);
7487
7736
  } else {
7488
- console.log(`${import_chalk31.default.bold("Prev server event hash")}: ${import_chalk31.default.dim("(null \u2014 first event of this relationship)")}`);
7737
+ console.log(`${import_chalk32.default.bold("Prev server event hash")}: ${import_chalk32.default.dim("(null \u2014 first event of this relationship)")}`);
7489
7738
  }
7490
7739
  if (opts.verbose) {
7491
- console.log(import_chalk31.default.bold("\nFull server response:"));
7740
+ console.log(import_chalk32.default.bold("\nFull server response:"));
7492
7741
  console.log(formatJson(result));
7493
7742
  }
7494
- console.log(import_chalk31.default.dim(`
7743
+ console.log(import_chalk32.default.dim(`
7495
7744
  Local sender_sequence advanced to ${nextSequence}.`));
7496
7745
  }
7497
7746
  function parseTtl3(raw) {
@@ -7505,7 +7754,7 @@ function parseTtl3(raw) {
7505
7754
 
7506
7755
  // src/commands/send-handshake-response.ts
7507
7756
  var import_sdk29 = require("@heyanon-arp/sdk");
7508
- var import_chalk32 = __toESM(require("chalk"));
7757
+ var import_chalk33 = __toESM(require("chalk"));
7509
7758
  init_api();
7510
7759
  var ALLOWED_DECISIONS = new Set(import_sdk29.HANDSHAKE_DECISIONS);
7511
7760
  function registerSendHandshakeResponseCommand(root) {
@@ -7546,11 +7795,11 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7546
7795
  declinePayload = detail ? { reason, reasonDetail: detail } : { reason };
7547
7796
  }
7548
7797
  const api = new ArpApiClient(opts.server);
7549
- progress(opts.json, import_chalk32.default.dim(`Server: ${api.serverUrl}`));
7798
+ progress(opts.json, import_chalk33.default.dim(`Server: ${api.serverUrl}`));
7550
7799
  const sender = resolveSenderAgent("send-handshake-response", opts.server, opts.fromDid, opts.from);
7551
- progress(opts.json, import_chalk32.default.dim(`Sender: ${sender.did}`));
7552
- progress(opts.json, import_chalk32.default.dim(`Recipient: ${recipientDid}`));
7553
- progress(opts.json, import_chalk32.default.dim(`Decision: ${decision}`));
7800
+ progress(opts.json, import_chalk33.default.dim(`Sender: ${sender.did}`));
7801
+ progress(opts.json, import_chalk33.default.dim(`Recipient: ${recipientDid}`));
7802
+ progress(opts.json, import_chalk33.default.dim(`Decision: ${decision}`));
7554
7803
  const signer = makeSigner(sender);
7555
7804
  if (!opts.force) {
7556
7805
  try {
@@ -7580,13 +7829,13 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7580
7829
  });
7581
7830
  return;
7582
7831
  }
7583
- progress(opts.json, import_chalk32.default.yellow(`
7832
+ progress(opts.json, import_chalk33.default.yellow(`
7584
7833
  [--idempotency] Relationship ${existing.relationshipId} with ${recipientDid} is already 'active'.`));
7585
7834
  progress(
7586
7835
  opts.json,
7587
- import_chalk32.default.dim(`A previous accept from this signer (event ${previousResponseFromMe.eventId}) landed successfully. Skipping re-send (use --force to override).`)
7836
+ import_chalk33.default.dim(`A previous accept from this signer (event ${previousResponseFromMe.eventId}) landed successfully. Skipping re-send (use --force to override).`)
7588
7837
  );
7589
- progress(opts.json, import_chalk32.default.dim(`Last event index: ${existing.lastEventIndex}, last server event hash: ${existing.lastServerEventHash ?? "(none)"}`));
7838
+ progress(opts.json, import_chalk33.default.dim(`Last event index: ${existing.lastEventIndex}, last server event hash: ${existing.lastServerEventHash ?? "(none)"}`));
7590
7839
  return;
7591
7840
  }
7592
7841
  throw new Error(
@@ -7597,7 +7846,7 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7597
7846
  if (probeErr instanceof Error && /CLOSED|terminated|already 'active' from a previous ACCEPT|original initiator/i.test(probeErr.message)) {
7598
7847
  throw probeErr;
7599
7848
  }
7600
- progress(opts.json, import_chalk32.default.dim(`(idempotency probe failed; proceeding anyway: ${probeErr.message})`));
7849
+ progress(opts.json, import_chalk33.default.dim(`(idempotency probe failed; proceeding anyway: ${probeErr.message})`));
7601
7850
  }
7602
7851
  }
7603
7852
  const content = { decision };
@@ -7627,7 +7876,7 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7627
7876
  identitySecretKey: signer.identitySecretKey
7628
7877
  });
7629
7878
  if (opts.verbose) {
7630
- console.log(import_chalk32.default.bold("\nEnvelope (pre-send):"));
7879
+ console.log(import_chalk33.default.bold("\nEnvelope (pre-send):"));
7631
7880
  console.log(formatJson(envelope));
7632
7881
  }
7633
7882
  const result = await api.ingest(envelope);
@@ -7648,23 +7897,23 @@ async function runSendHandshakeResponse(recipientDid, opts) {
7648
7897
  });
7649
7898
  return;
7650
7899
  }
7651
- console.log(import_chalk32.default.green("\nDelivered."));
7652
- console.log(`${import_chalk32.default.bold("Event id")}: ${import_chalk32.default.cyan(result.eventId)}`);
7653
- console.log(`${import_chalk32.default.bold("Relationship id")}: ${import_chalk32.default.cyan(result.relationshipId)}`);
7654
- console.log(`${import_chalk32.default.bold("Chain index")}: ${import_chalk32.default.cyan(String(result.relationshipEventIndex))}`);
7655
- console.log(`${import_chalk32.default.bold("Server timestamp")}: ${import_chalk32.default.cyan(result.serverTimestamp)}`);
7656
- console.log(`${import_chalk32.default.bold("Signed message hash")}: ${import_chalk32.default.cyan(result.signedMessageHash)}`);
7657
- console.log(`${import_chalk32.default.bold("Server event hash")}: ${import_chalk32.default.cyan(result.serverEventHash)}`);
7900
+ console.log(import_chalk33.default.green("\nDelivered."));
7901
+ console.log(`${import_chalk33.default.bold("Event id")}: ${import_chalk33.default.cyan(result.eventId)}`);
7902
+ console.log(`${import_chalk33.default.bold("Relationship id")}: ${import_chalk33.default.cyan(result.relationshipId)}`);
7903
+ console.log(`${import_chalk33.default.bold("Chain index")}: ${import_chalk33.default.cyan(String(result.relationshipEventIndex))}`);
7904
+ console.log(`${import_chalk33.default.bold("Server timestamp")}: ${import_chalk33.default.cyan(result.serverTimestamp)}`);
7905
+ console.log(`${import_chalk33.default.bold("Signed message hash")}: ${import_chalk33.default.cyan(result.signedMessageHash)}`);
7906
+ console.log(`${import_chalk33.default.bold("Server event hash")}: ${import_chalk33.default.cyan(result.serverEventHash)}`);
7658
7907
  if (result.prevServerEventHash) {
7659
- console.log(`${import_chalk32.default.bold("Prev server event hash")}: ${import_chalk32.default.cyan(result.prevServerEventHash)}`);
7908
+ console.log(`${import_chalk33.default.bold("Prev server event hash")}: ${import_chalk33.default.cyan(result.prevServerEventHash)}`);
7660
7909
  } else {
7661
- console.log(`${import_chalk32.default.bold("Prev server event hash")}: ${import_chalk32.default.dim("(null \u2014 first event of this relationship)")}`);
7910
+ console.log(`${import_chalk33.default.bold("Prev server event hash")}: ${import_chalk33.default.dim("(null \u2014 first event of this relationship)")}`);
7662
7911
  }
7663
7912
  if (opts.verbose) {
7664
- console.log(import_chalk32.default.bold("\nFull server response:"));
7913
+ console.log(import_chalk33.default.bold("\nFull server response:"));
7665
7914
  console.log(formatJson(result));
7666
7915
  }
7667
- console.log(import_chalk32.default.dim(`
7916
+ console.log(import_chalk33.default.dim(`
7668
7917
  Local sender_sequence advanced to ${nextSequence}.`));
7669
7918
  }
7670
7919
  function parseDecision(raw) {
@@ -7715,7 +7964,7 @@ async function findExistingRelationship(api, signer, senderDid, recipientDid) {
7715
7964
  }
7716
7965
 
7717
7966
  // src/commands/stats.ts
7718
- var import_chalk33 = __toESM(require("chalk"));
7967
+ var import_chalk34 = __toESM(require("chalk"));
7719
7968
  init_api();
7720
7969
  function registerStatsCommand(root) {
7721
7970
  root.command("stats").description("Show an agent's public stats \u2014 counters, 0..100 scores, derived rates, and settled on-chain volume by asset. Public, no auth.").argument("<agent>", "Agent name (handle) or did:arp:<base58btc>").option("--server <url>", "Override ARP server base URL").option("--json", "Emit the stats as JSON on stdout.", false).action(async (agent, opts) => {
@@ -7728,8 +7977,8 @@ function registerStatsCommand(root) {
7728
7977
  }
7729
7978
  const j = false;
7730
7979
  const { counters: c, scores: s, rates: r, volume: v } = stats;
7731
- progress(j, import_chalk33.default.bold(`Stats \u2014 ${did}`));
7732
- progress(j, import_chalk33.default.dim(` ${stats.computed ? "computed" : "cold-start (no settled cycle yet)"}`));
7980
+ progress(j, import_chalk34.default.bold(`Stats \u2014 ${did}`));
7981
+ progress(j, import_chalk34.default.dim(` ${stats.computed ? "computed" : "cold-start (no settled cycle yet)"}`));
7733
7982
  progress(j, "");
7734
7983
  progress(
7735
7984
  j,
@@ -7743,16 +7992,16 @@ function registerStatsCommand(root) {
7743
7992
  progress(j, ` escrows settled ${c.settledEscrows} / refunded ${c.refundedEscrows} \xB7 disputed ${c.disputedEscrows} (adverse ${c.disputesAdverse})`);
7744
7993
  progress(j, ` network distinct counterparts ${c.distinctCounterparts} \xB7 active relationships ${c.activeRelationships}`);
7745
7994
  progress(j, "");
7746
- progress(j, import_chalk33.default.dim(" earned (as payee):"));
7995
+ progress(j, import_chalk34.default.dim(" earned (as payee):"));
7747
7996
  renderAssets(v.earnedByAsset);
7748
- progress(j, import_chalk33.default.dim(" paid (as payer):"));
7997
+ progress(j, import_chalk34.default.dim(" paid (as payer):"));
7749
7998
  renderAssets(v.paidByAsset);
7750
7999
  if (v.firstSettledAt || v.lastSettledAt) {
7751
8000
  progress(j, "");
7752
- progress(j, import_chalk33.default.dim(` settled span: ${v.firstSettledAt ?? "?"} \u2192 ${v.lastSettledAt ?? "?"}`));
8001
+ progress(j, import_chalk34.default.dim(` settled span: ${v.firstSettledAt ?? "?"} \u2192 ${v.lastSettledAt ?? "?"}`));
7753
8002
  }
7754
8003
  progress(j, "");
7755
- progress(j, import_chalk33.default.dim(" Public, informational \u2014 derived from on-chain settlement; cached briefly."));
8004
+ progress(j, import_chalk34.default.dim(" Public, informational \u2014 derived from on-chain settlement; cached briefly."));
7756
8005
  });
7757
8006
  }
7758
8007
  function pct(r) {
@@ -7760,18 +8009,18 @@ function pct(r) {
7760
8009
  }
7761
8010
  function renderAssets(assets) {
7762
8011
  if (assets.length === 0) {
7763
- progress(false, import_chalk33.default.dim(" (none)"));
8012
+ progress(false, import_chalk34.default.dim(" (none)"));
7764
8013
  return;
7765
8014
  }
7766
8015
  for (const a of assets) {
7767
8016
  const label = a.symbol ?? `${a.mint.slice(0, 6)}\u2026`;
7768
8017
  const amount = a.amountDecimal ?? `${a.amountBaseUnits} base-units`;
7769
- progress(false, ` ${amount} ${label} ${import_chalk33.default.dim(`(${a.lockCount} lock${a.lockCount === 1 ? "" : "s"})`)}`);
8018
+ progress(false, ` ${amount} ${label} ${import_chalk34.default.dim(`(${a.lockCount} lock${a.lockCount === 1 ? "" : "s"})`)}`);
7770
8019
  }
7771
8020
  }
7772
8021
 
7773
8022
  // src/commands/watch.ts
7774
- var import_chalk34 = __toESM(require("chalk"));
8023
+ var import_chalk35 = __toESM(require("chalk"));
7775
8024
  init_api();
7776
8025
  function registerWatchCommand(root) {
7777
8026
  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) => {
@@ -7782,9 +8031,9 @@ async function runWatch(relationshipId, opts) {
7782
8031
  const local = resolveSenderAgent("watch", opts.server, opts.fromDid, opts.from);
7783
8032
  const api = new ArpApiClient(opts.server);
7784
8033
  if (!opts.json) {
7785
- console.log(import_chalk34.default.dim(`Server: ${api.serverUrl}`));
7786
- console.log(import_chalk34.default.dim(`Signer: ${local.did}`));
7787
- console.log(import_chalk34.default.dim(`Watching: ${relationshipId}`));
8034
+ console.log(import_chalk35.default.dim(`Server: ${api.serverUrl}`));
8035
+ console.log(import_chalk35.default.dim(`Signer: ${local.did}`));
8036
+ console.log(import_chalk35.default.dim(`Watching: ${relationshipId}`));
7788
8037
  }
7789
8038
  const controller = new AbortController();
7790
8039
  let userAborted = false;
@@ -7803,7 +8052,7 @@ async function runWatch(relationshipId, opts) {
7803
8052
  }
7804
8053
  if (event.type === "heartbeat") continue;
7805
8054
  if (event.type === "connected") {
7806
- console.log(import_chalk34.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
8055
+ console.log(import_chalk35.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
7807
8056
  continue;
7808
8057
  }
7809
8058
  if (event.type === "envelope") {
@@ -7817,7 +8066,7 @@ async function runWatch(relationshipId, opts) {
7817
8066
  }
7818
8067
  continue;
7819
8068
  }
7820
- console.log(import_chalk34.default.dim(`(unknown event: ${event.type})`));
8069
+ console.log(import_chalk35.default.dim(`(unknown event: ${event.type})`));
7821
8070
  }
7822
8071
  if (!userAborted) {
7823
8072
  throw new Error(`watch ${relationshipId}: stream ended unexpectedly (server may have restarted, or the change stream errored). Re-run to reconnect.`);
@@ -7825,7 +8074,7 @@ async function runWatch(relationshipId, opts) {
7825
8074
  } catch (err) {
7826
8075
  const name = err.name;
7827
8076
  if (name === "AbortError" || userAborted) {
7828
- if (!opts.json) console.log(import_chalk34.default.dim("\nstream closed."));
8077
+ if (!opts.json) console.log(import_chalk35.default.dim("\nstream closed."));
7829
8078
  return;
7830
8079
  }
7831
8080
  throw err;
@@ -7839,21 +8088,21 @@ function formatWatchLine(ev, selfDid, opts = {}) {
7839
8088
  const type = ev.type.padEnd(20);
7840
8089
  const direction = directionLabel2(ev, selfDid, opts);
7841
8090
  const hash = opts.fullIds ? ev.serverEventHash : hashHead4(ev.serverEventHash);
7842
- return `${import_chalk34.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk34.default.cyan(hash)}`;
8091
+ return `${import_chalk35.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk35.default.cyan(hash)}`;
7843
8092
  }
7844
8093
  function directionLabel2(ev, selfDid, opts = {}) {
7845
8094
  const senderHead = opts.fullIds ? ev.senderDid : didHead4(ev.senderDid);
7846
8095
  const recipientHead = opts.fullIds ? ev.recipientDid : didHead4(ev.recipientDid);
7847
- if (ev.senderDid === selfDid) return `${import_chalk34.default.bold("me")} \u2192 ${import_chalk34.default.dim(recipientHead)}`;
7848
- if (ev.recipientDid === selfDid) return `${import_chalk34.default.dim(senderHead)} \u2192 ${import_chalk34.default.bold("me")}`;
7849
- return `${import_chalk34.default.dim(senderHead)} \u2192 ${import_chalk34.default.dim(recipientHead)}`;
8096
+ if (ev.senderDid === selfDid) return `${import_chalk35.default.bold("me")} \u2192 ${import_chalk35.default.dim(recipientHead)}`;
8097
+ if (ev.recipientDid === selfDid) return `${import_chalk35.default.dim(senderHead)} \u2192 ${import_chalk35.default.bold("me")}`;
8098
+ return `${import_chalk35.default.dim(senderHead)} \u2192 ${import_chalk35.default.dim(recipientHead)}`;
7850
8099
  }
7851
8100
  function didHead4(did) {
7852
8101
  if (did.length <= 20) return did;
7853
8102
  return `${did.slice(0, 20)}...`;
7854
8103
  }
7855
8104
  function hashHead4(hash) {
7856
- if (!hash) return import_chalk34.default.dim("(none)");
8105
+ if (!hash) return import_chalk35.default.dim("(none)");
7857
8106
  if (hash.length <= 14) return hash;
7858
8107
  return `${hash.slice(0, 14)}...`;
7859
8108
  }
@@ -7865,7 +8114,7 @@ function formatClock(iso) {
7865
8114
  }
7866
8115
 
7867
8116
  // src/commands/whoami.ts
7868
- var import_chalk35 = __toESM(require("chalk"));
8117
+ var import_chalk36 = __toESM(require("chalk"));
7869
8118
  init_api();
7870
8119
  function registerWhoamiCommand(root) {
7871
8120
  root.command("whoami").description(
@@ -7896,12 +8145,12 @@ function registerWhoamiCommand(root) {
7896
8145
  if (opts.json) {
7897
8146
  console.log(formatJson({ ...localJson, account: credential ? { wallet: credential.wallet } : null }));
7898
8147
  } else {
7899
- console.log(import_chalk35.default.bold("Local agent:"));
7900
- console.log(` DID: ${import_chalk35.default.cyan(local.did)}`);
7901
- console.log(` Settlement pubkey: ${import_chalk35.default.cyan(local.settlementPublicKeyB58)}`);
7902
- console.log(` Identity pubkey: ${import_chalk35.default.cyan(local.identityPublicKeyB58)}`);
8148
+ console.log(import_chalk36.default.bold("Local agent:"));
8149
+ console.log(` DID: ${import_chalk36.default.cyan(local.did)}`);
8150
+ console.log(` Settlement pubkey: ${import_chalk36.default.cyan(local.settlementPublicKeyB58)}`);
8151
+ console.log(` Identity pubkey: ${import_chalk36.default.cyan(local.identityPublicKeyB58)}`);
7903
8152
  if (local.name) console.log(` Name: ${local.name}`);
7904
- console.log(` Account: ${credential ? import_chalk35.default.cyan(credential.wallet) : import_chalk35.default.dim("not logged in (heyarp login)")}`);
8153
+ console.log(` Account: ${credential ? import_chalk36.default.cyan(credential.wallet) : import_chalk36.default.dim("not logged in (heyarp login)")}`);
7905
8154
  }
7906
8155
  return;
7907
8156
  }
@@ -7919,19 +8168,19 @@ function registerWhoamiCommand(root) {
7919
8168
  if (opts.json) {
7920
8169
  console.log(formatJson({ local: localJson, account, server: agent }));
7921
8170
  } else {
7922
- console.log(import_chalk35.default.dim(`Server: ${api.serverUrl}`));
7923
- console.log(import_chalk35.default.bold("\nLocal agent:"));
7924
- console.log(` DID: ${import_chalk35.default.cyan(local.did)}`);
7925
- console.log(` Settlement pubkey: ${import_chalk35.default.cyan(local.settlementPublicKeyB58)}`);
7926
- console.log(` Identity pubkey: ${import_chalk35.default.cyan(local.identityPublicKeyB58)}`);
7927
- console.log(import_chalk35.default.bold("\nAccount:"));
8171
+ console.log(import_chalk36.default.dim(`Server: ${api.serverUrl}`));
8172
+ console.log(import_chalk36.default.bold("\nLocal agent:"));
8173
+ console.log(` DID: ${import_chalk36.default.cyan(local.did)}`);
8174
+ console.log(` Settlement pubkey: ${import_chalk36.default.cyan(local.settlementPublicKeyB58)}`);
8175
+ console.log(` Identity pubkey: ${import_chalk36.default.cyan(local.identityPublicKeyB58)}`);
8176
+ console.log(import_chalk36.default.bold("\nAccount:"));
7928
8177
  if (account) {
7929
- console.log(` Wallet: ${import_chalk35.default.cyan(account.wallet)}`);
8178
+ console.log(` Wallet: ${import_chalk36.default.cyan(account.wallet)}`);
7930
8179
  console.log(` Agents registered: ${account.agentCount}`);
7931
8180
  } else {
7932
- console.log(` ${import_chalk35.default.dim("not logged in (heyarp login)")}`);
8181
+ console.log(` ${import_chalk36.default.dim("not logged in (heyarp login)")}`);
7933
8182
  }
7934
- console.log(import_chalk35.default.bold("\nServer profile:"));
8183
+ console.log(import_chalk36.default.bold("\nServer profile:"));
7935
8184
  console.log(formatJson(agent));
7936
8185
  }
7937
8186
  } catch (err) {
@@ -7943,12 +8192,12 @@ function registerWhoamiCommand(root) {
7943
8192
 
7944
8193
  // src/commands/whois.ts
7945
8194
  var import_sdk30 = require("@heyanon-arp/sdk");
7946
- var import_chalk36 = __toESM(require("chalk"));
8195
+ var import_chalk37 = __toESM(require("chalk"));
7947
8196
  init_api();
7948
8197
  function registerWhoisCommand(root) {
7949
8198
  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) => {
7950
8199
  const api = new ArpApiClient(opts.server);
7951
- progress(opts.json, import_chalk36.default.dim(`Server: ${api.serverUrl}`));
8200
+ progress(opts.json, import_chalk37.default.dim(`Server: ${api.serverUrl}`));
7952
8201
  const profile = await resolveProfile(api, input);
7953
8202
  if (opts.json) {
7954
8203
  jsonOut(profile);
@@ -7971,19 +8220,19 @@ async function resolveProfile(api, input) {
7971
8220
  return api.discoverByName(name);
7972
8221
  }
7973
8222
  function printProfile(p) {
7974
- console.log(`${import_chalk36.default.bold("Name")}: ${import_chalk36.default.cyan(p.name ?? "(unnamed)")}`);
7975
- console.log(`${import_chalk36.default.bold("DID")}: ${import_chalk36.default.cyan(p.did)}`);
7976
- if (p.description) console.log(`${import_chalk36.default.bold("Description")}: ${p.description}`);
7977
- if (p.tags.length > 0) console.log(`${import_chalk36.default.bold("Tags")}: ${p.tags.join(", ")}`);
7978
- console.log(`${import_chalk36.default.bold("Registered")}: ${p.registeredAt}`);
8223
+ console.log(`${import_chalk37.default.bold("Name")}: ${import_chalk37.default.cyan(p.name ?? "(unnamed)")}`);
8224
+ console.log(`${import_chalk37.default.bold("DID")}: ${import_chalk37.default.cyan(p.did)}`);
8225
+ if (p.description) console.log(`${import_chalk37.default.bold("Description")}: ${p.description}`);
8226
+ if (p.tags.length > 0) console.log(`${import_chalk37.default.bold("Tags")}: ${p.tags.join(", ")}`);
8227
+ console.log(`${import_chalk37.default.bold("Registered")}: ${p.registeredAt}`);
7979
8228
  const rep = p.reputation;
7980
- console.log(`${import_chalk36.default.bold("Reputation")}: composite ${rep.scores.composite}/100${rep.computed ? "" : import_chalk36.default.dim(" (cold-start \u2014 no settled cycles yet)")}`);
7981
- console.log(`${import_chalk36.default.bold("Online")}: ${p.liveness.online ? import_chalk36.default.green("yes") : import_chalk36.default.dim("no")}`);
8229
+ console.log(`${import_chalk37.default.bold("Reputation")}: composite ${rep.scores.composite}/100${rep.computed ? "" : import_chalk37.default.dim(" (cold-start \u2014 no settled cycles yet)")}`);
8230
+ console.log(`${import_chalk37.default.bold("Online")}: ${p.liveness.online ? import_chalk37.default.green("yes") : import_chalk37.default.dim("no")}`);
7982
8231
  }
7983
8232
 
7984
8233
  // src/commands/work.ts
7985
8234
  var import_sdk31 = require("@heyanon-arp/sdk");
7986
- var import_chalk37 = __toESM(require("chalk"));
8235
+ var import_chalk38 = __toESM(require("chalk"));
7987
8236
  init_api();
7988
8237
  function registerWorkCommands(root) {
7989
8238
  const cmd = root.command("work").description("Work envelopes inside an ACCEPTED delegation: request / respond");
@@ -8024,11 +8273,11 @@ async function runRequest(recipientDid, delegationId, opts) {
8024
8273
  params
8025
8274
  };
8026
8275
  const body = { type: "work_request", content };
8027
- progress(opts.json, import_chalk37.default.dim(`Server: ${api.serverUrl}`));
8028
- progress(opts.json, import_chalk37.default.dim(`Sender: ${sender.did}`));
8029
- progress(opts.json, import_chalk37.default.dim(`Recipient: ${recipientDid}`));
8030
- progress(opts.json, import_chalk37.default.dim(`Delegation: ${delegationId}`));
8031
- progress(opts.json, import_chalk37.default.dim(`Request id: ${requestId}`));
8276
+ progress(opts.json, import_chalk38.default.dim(`Server: ${api.serverUrl}`));
8277
+ progress(opts.json, import_chalk38.default.dim(`Sender: ${sender.did}`));
8278
+ progress(opts.json, import_chalk38.default.dim(`Recipient: ${recipientDid}`));
8279
+ progress(opts.json, import_chalk38.default.dim(`Delegation: ${delegationId}`));
8280
+ progress(opts.json, import_chalk38.default.dim(`Request id: ${requestId}`));
8032
8281
  const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
8033
8282
  if (opts.json) {
8034
8283
  jsonOut({
@@ -8045,10 +8294,10 @@ async function runRequest(recipientDid, delegationId, opts) {
8045
8294
  });
8046
8295
  } else {
8047
8296
  printIngestResult3(result);
8048
- console.log(import_chalk37.default.dim(`
8297
+ console.log(import_chalk38.default.dim(`
8049
8298
  The payee can reply with:`));
8050
- console.log(import_chalk37.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --output '<json>'`));
8051
- console.log(import_chalk37.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --error CODE:message`));
8299
+ console.log(import_chalk38.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --output '<json>'`));
8300
+ console.log(import_chalk38.default.dim(` heyarp work respond ${result.relationshipId} ${delegationId} ${requestId} --error CODE:message`));
8052
8301
  }
8053
8302
  }
8054
8303
  function registerRespond(parent) {
@@ -8083,13 +8332,13 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
8083
8332
  ...responsePayload
8084
8333
  };
8085
8334
  const body = { type: "work_response", content };
8086
- progress(opts.json, import_chalk37.default.dim(`Server: ${api.serverUrl}`));
8087
- progress(opts.json, import_chalk37.default.dim(`Sender: ${sender.did}`));
8088
- progress(opts.json, import_chalk37.default.dim(`Recipient: ${recipientDid}`));
8089
- progress(opts.json, import_chalk37.default.dim(`Relationship: ${relationshipId}`));
8090
- progress(opts.json, import_chalk37.default.dim(`Delegation: ${delegationId}`));
8091
- progress(opts.json, import_chalk37.default.dim(`Request id: ${requestId}`));
8092
- progress(opts.json, import_chalk37.default.dim(`Outcome: ${responsePayload.output ? "success" : "error"}`));
8335
+ progress(opts.json, import_chalk38.default.dim(`Server: ${api.serverUrl}`));
8336
+ progress(opts.json, import_chalk38.default.dim(`Sender: ${sender.did}`));
8337
+ progress(opts.json, import_chalk38.default.dim(`Recipient: ${recipientDid}`));
8338
+ progress(opts.json, import_chalk38.default.dim(`Relationship: ${relationshipId}`));
8339
+ progress(opts.json, import_chalk38.default.dim(`Delegation: ${delegationId}`));
8340
+ progress(opts.json, import_chalk38.default.dim(`Request id: ${requestId}`));
8341
+ progress(opts.json, import_chalk38.default.dim(`Outcome: ${responsePayload.output ? "success" : "error"}`));
8093
8342
  const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
8094
8343
  if (opts.json) {
8095
8344
  jsonOut({
@@ -8130,7 +8379,7 @@ async function sendWorkEnvelope(args) {
8130
8379
  identitySecretKey: signer.identitySecretKey
8131
8380
  });
8132
8381
  if (args.verbose) {
8133
- console.log(import_chalk37.default.bold("\nEnvelope (pre-send):"));
8382
+ console.log(import_chalk38.default.bold("\nEnvelope (pre-send):"));
8134
8383
  console.log(formatJson(envelope));
8135
8384
  }
8136
8385
  try {
@@ -8170,12 +8419,12 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
8170
8419
  );
8171
8420
  }
8172
8421
  function printIngestResult3(result) {
8173
- console.log(import_chalk37.default.green("\nDelivered."));
8174
- console.log(`${import_chalk37.default.bold("Event id")}: ${import_chalk37.default.cyan(result.eventId)}`);
8175
- console.log(`${import_chalk37.default.bold("Relationship id")}: ${import_chalk37.default.cyan(result.relationshipId)}`);
8176
- console.log(`${import_chalk37.default.bold("Chain index")}: ${import_chalk37.default.cyan(String(result.relationshipEventIndex))}`);
8177
- console.log(`${import_chalk37.default.bold("Server timestamp")}: ${import_chalk37.default.cyan(result.serverTimestamp)}`);
8178
- console.log(`${import_chalk37.default.bold("Server event hash")}: ${import_chalk37.default.cyan(result.serverEventHash)}`);
8422
+ console.log(import_chalk38.default.green("\nDelivered."));
8423
+ console.log(`${import_chalk38.default.bold("Event id")}: ${import_chalk38.default.cyan(result.eventId)}`);
8424
+ console.log(`${import_chalk38.default.bold("Relationship id")}: ${import_chalk38.default.cyan(result.relationshipId)}`);
8425
+ console.log(`${import_chalk38.default.bold("Chain index")}: ${import_chalk38.default.cyan(String(result.relationshipEventIndex))}`);
8426
+ console.log(`${import_chalk38.default.bold("Server timestamp")}: ${import_chalk38.default.cyan(result.serverTimestamp)}`);
8427
+ console.log(`${import_chalk38.default.bold("Server event hash")}: ${import_chalk38.default.cyan(result.serverEventHash)}`);
8179
8428
  }
8180
8429
  function parseJsonObject(cmdName, flagName, raw) {
8181
8430
  let parsed;
@@ -8213,8 +8462,8 @@ function parseParamsInput(cmdName, opts) {
8213
8462
  return parseJsonObject(cmdName, "--params", opts.params ?? "{}");
8214
8463
  }
8215
8464
  function readJsonObjectFile(cmdName, flagName, path) {
8216
- const { existsSync: existsSync7, readFileSync: readFileSync10 } = require("fs");
8217
- if (!existsSync7(path)) {
8465
+ const { existsSync: existsSync8, readFileSync: readFileSync10 } = require("fs");
8466
+ if (!existsSync8(path)) {
8218
8467
  throw new Error(`${cmdName}: ${flagName} file not found at ${path}`);
8219
8468
  }
8220
8469
  let raw;
@@ -8277,7 +8526,7 @@ function parseRequestId(cmdName, raw) {
8277
8526
 
8278
8527
  // src/commands/work-list.ts
8279
8528
  var import_sdk32 = require("@heyanon-arp/sdk");
8280
- var import_chalk38 = __toESM(require("chalk"));
8529
+ var import_chalk39 = __toESM(require("chalk"));
8281
8530
  init_api();
8282
8531
  var ALLOWED_STATES3 = new Set(import_sdk32.WORK_LOG_STATES);
8283
8532
  function registerWorkListCommand(root) {
@@ -8304,9 +8553,9 @@ async function runWorkList(relationshipId, opts) {
8304
8553
  const api = new ArpApiClient(opts.server);
8305
8554
  const sender = resolveSenderAgent("work-list", opts.server, opts.fromDid, opts.from);
8306
8555
  if (!opts.json) {
8307
- console.log(import_chalk38.default.dim(`Server: ${api.serverUrl}`));
8308
- console.log(import_chalk38.default.dim(`Signer: ${sender.did}`));
8309
- console.log(import_chalk38.default.dim(`Relationship: ${relationshipId}`));
8556
+ console.log(import_chalk39.default.dim(`Server: ${api.serverUrl}`));
8557
+ console.log(import_chalk39.default.dim(`Signer: ${sender.did}`));
8558
+ console.log(import_chalk39.default.dim(`Relationship: ${relationshipId}`));
8310
8559
  }
8311
8560
  const query = { limit };
8312
8561
  if (state) query.state = state;
@@ -8319,7 +8568,7 @@ async function runWorkList(relationshipId, opts) {
8319
8568
  return;
8320
8569
  }
8321
8570
  if (rows.length === 0) {
8322
- console.log(import_chalk38.default.dim("\n(no work-logs for this relationship)"));
8571
+ console.log(import_chalk39.default.dim("\n(no work-logs for this relationship)"));
8323
8572
  return;
8324
8573
  }
8325
8574
  console.log("");
@@ -8336,36 +8585,36 @@ async function runWorkList(relationshipId, opts) {
8336
8585
  }));
8337
8586
  }
8338
8587
  const lastId = rows[rows.length - 1].id;
8339
- console.log(import_chalk38.default.dim(`
8588
+ console.log(import_chalk39.default.dim(`
8340
8589
  ${rows.length} work-log row(s). Paginate with --after ${lastId}.`));
8341
8590
  }
8342
8591
  function formatWorkLogLine(w, selfDid, opts = {}) {
8343
8592
  const delegationPart = opts.fullIds ? w.delegationId : idHead3(w.delegationId);
8344
8593
  const requestPart = opts.fullIds ? w.requestId : truncate3(w.requestId, 16);
8345
- const id = import_chalk38.default.bold(`${delegationPart}/${requestPart}`);
8594
+ const id = import_chalk39.default.bold(`${delegationPart}/${requestPart}`);
8346
8595
  const state = colorState2(w.state).padEnd(stateColumnWidth2());
8347
8596
  const peerCallerHead = opts.fullIds ? w.callerDid : didHead5(w.callerDid);
8348
8597
  const peerPayeeHead = opts.fullIds ? w.payeeDid : didHead5(w.payeeDid);
8349
- const direction = w.callerDid === selfDid ? `${import_chalk38.default.bold("me")} \u2192 ${import_chalk38.default.dim(peerPayeeHead)}` : `${import_chalk38.default.dim(peerCallerHead)} \u2192 ${import_chalk38.default.bold("me")}`;
8598
+ const direction = w.callerDid === selfDid ? `${import_chalk39.default.bold("me")} \u2192 ${import_chalk39.default.dim(peerPayeeHead)}` : `${import_chalk39.default.dim(peerCallerHead)} \u2192 ${import_chalk39.default.bold("me")}`;
8350
8599
  const outcome = formatOutcome(w);
8351
8600
  return `${id} ${state} ${direction} ${outcome}`;
8352
8601
  }
8353
8602
  function colorState2(s) {
8354
8603
  switch (s) {
8355
8604
  case import_sdk32.WorkLogStates.REQUESTED:
8356
- return import_chalk38.default.yellow("requested");
8605
+ return import_chalk39.default.yellow("requested");
8357
8606
  case import_sdk32.WorkLogStates.RESPONDED:
8358
- return import_chalk38.default.green("responded");
8607
+ return import_chalk39.default.green("responded");
8359
8608
  }
8360
8609
  }
8361
8610
  function stateColumnWidth2() {
8362
8611
  return 9;
8363
8612
  }
8364
8613
  function formatOutcome(w) {
8365
- if (w.state === import_sdk32.WorkLogStates.REQUESTED) return import_chalk38.default.dim("(in flight)");
8366
- if (w.responseError) return import_chalk38.default.red(`error ${w.responseError.code}: ${truncate3(w.responseError.message, 32)}`);
8367
- if (w.responseOutput) return import_chalk38.default.cyan("ok");
8368
- return import_chalk38.default.dim("(empty response)");
8614
+ if (w.state === import_sdk32.WorkLogStates.REQUESTED) return import_chalk39.default.dim("(in flight)");
8615
+ if (w.responseError) return import_chalk39.default.red(`error ${w.responseError.code}: ${truncate3(w.responseError.message, 32)}`);
8616
+ if (w.responseOutput) return import_chalk39.default.cyan("ok");
8617
+ return import_chalk39.default.dim("(empty response)");
8369
8618
  }
8370
8619
  function idHead3(id) {
8371
8620
  if (id.length <= 12) return id;
@@ -8433,12 +8682,12 @@ function unknownOptionHint(program, err) {
8433
8682
  }
8434
8683
 
8435
8684
  // src/version-gate.ts
8436
- var import_node_fs10 = require("fs");
8437
- var import_node_path7 = require("path");
8685
+ var import_node_fs11 = require("fs");
8686
+ var import_node_path8 = require("path");
8438
8687
  init_paths();
8439
8688
  var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
8440
8689
  var REGISTRY_TIMEOUT_MS = 1500;
8441
- var cacheFile = () => (0, import_node_path7.join)(arpHomeDir(), "update-check.json");
8690
+ var cacheFile = () => (0, import_node_path8.join)(arpHomeDir(), "update-check.json");
8442
8691
  function majorOf(version) {
8443
8692
  return Number.parseInt(version.split(".")[0] ?? "0", 10) || 0;
8444
8693
  }
@@ -8470,7 +8719,7 @@ async function fetchLatest(pkgName) {
8470
8719
  }
8471
8720
  async function resolveLatest(pkgName) {
8472
8721
  try {
8473
- const cached = JSON.parse((0, import_node_fs10.readFileSync)(cacheFile(), "utf8"));
8722
+ const cached = JSON.parse((0, import_node_fs11.readFileSync)(cacheFile(), "utf8"));
8474
8723
  if (typeof cached.latest === "string" && typeof cached.checkedAt === "number" && Date.now() - cached.checkedAt < CHECK_INTERVAL_MS) {
8475
8724
  return cached.latest;
8476
8725
  }
@@ -8480,8 +8729,8 @@ async function resolveLatest(pkgName) {
8480
8729
  if (!fresh) return null;
8481
8730
  try {
8482
8731
  const file = cacheFile();
8483
- (0, import_node_fs10.mkdirSync)((0, import_node_path7.dirname)(file), { recursive: true });
8484
- (0, import_node_fs10.writeFileSync)(file, JSON.stringify({ checkedAt: Date.now(), latest: fresh }));
8732
+ (0, import_node_fs11.mkdirSync)((0, import_node_path8.dirname)(file), { recursive: true });
8733
+ (0, import_node_fs11.writeFileSync)(file, JSON.stringify({ checkedAt: Date.now(), latest: fresh }));
8485
8734
  } catch {
8486
8735
  }
8487
8736
  return fresh;
@@ -8545,6 +8794,7 @@ async function main() {
8545
8794
  registerDidDocCommand(program);
8546
8795
  registerProfileCommand(program);
8547
8796
  registerDoctorCommand(program);
8797
+ registerSelftestCommand(program);
8548
8798
  registerAssetsCommand(program);
8549
8799
  registerEscrowCommands(program);
8550
8800
  registerWhoamiCommand(program);