@heyanon-arp/cli 0.0.25 → 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 +431 -121
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -322,6 +322,9 @@ var init_api = __esm({
|
|
|
322
322
|
async getReputation(did) {
|
|
323
323
|
return this.get(`/v1/agents/${encodeURIComponent(did)}/reputation`);
|
|
324
324
|
}
|
|
325
|
+
async getStats(did) {
|
|
326
|
+
return this.get(`/v1/agents/${encodeURIComponent(did)}/stats`);
|
|
327
|
+
}
|
|
325
328
|
/**
|
|
326
329
|
* Public `GET /v1/discovery/search`. Reputation-ranked agent search
|
|
327
330
|
* with creator / liveness / accepted-asset filters. No auth.
|
|
@@ -733,7 +736,7 @@ var import_commander = require("commander");
|
|
|
733
736
|
// package.json
|
|
734
737
|
var package_default = {
|
|
735
738
|
name: "@heyanon-arp/cli",
|
|
736
|
-
version: "0.0.
|
|
739
|
+
version: "0.0.27",
|
|
737
740
|
description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
|
|
738
741
|
license: "MIT",
|
|
739
742
|
keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
|
|
@@ -4722,8 +4725,8 @@ function formatEscrowConfigStatus(serverUrl, s) {
|
|
|
4722
4725
|
lines.push("");
|
|
4723
4726
|
lines.push(import_chalk14.default.dim(` New locks will snapshot fee_bps=0 \u2014 payee receives 100% on claim.`));
|
|
4724
4727
|
} else {
|
|
4725
|
-
const
|
|
4726
|
-
lines.push(` ${import_chalk14.default.yellow("ENABLED")} \u2014 ${
|
|
4728
|
+
const pct2 = (s.feeBps / 100).toFixed(2);
|
|
4729
|
+
lines.push(` ${import_chalk14.default.yellow("ENABLED")} \u2014 ${pct2}% of payee slice (${s.feeBps} bps)`);
|
|
4727
4730
|
lines.push(` ${import_chalk14.default.dim("fee_recipient:")} ${s.feeRecipient}`);
|
|
4728
4731
|
lines.push("");
|
|
4729
4732
|
lines.push(import_chalk14.default.dim(` New locks will snapshot fee_bps=${s.feeBps} onto themselves.`));
|
|
@@ -7400,9 +7403,258 @@ function bar(score) {
|
|
|
7400
7403
|
return `${"\u2588".repeat(filled)}${"\u2591".repeat(10 - filled)}`;
|
|
7401
7404
|
}
|
|
7402
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
|
+
|
|
7403
7655
|
// src/commands/send-handshake.ts
|
|
7404
7656
|
var import_sdk28 = require("@heyanon-arp/sdk");
|
|
7405
|
-
var
|
|
7657
|
+
var import_chalk32 = __toESM(require("chalk"));
|
|
7406
7658
|
init_api();
|
|
7407
7659
|
function registerSendHandshakeCommand(root) {
|
|
7408
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(
|
|
@@ -7422,10 +7674,10 @@ async function runSendHandshake(recipientDid, opts) {
|
|
|
7422
7674
|
recipientDid = await resolveRecipient(opts.server, "send-handshake", recipientDid, { json: opts.json });
|
|
7423
7675
|
const ttlSeconds = parseTtl3(opts.ttl);
|
|
7424
7676
|
const api = new ArpApiClient(opts.server);
|
|
7425
|
-
progress(opts.json,
|
|
7677
|
+
progress(opts.json, import_chalk32.default.dim(`Server: ${api.serverUrl}`));
|
|
7426
7678
|
const sender = resolveSenderAgent("send-handshake", opts.server, opts.fromDid, opts.from);
|
|
7427
|
-
progress(opts.json,
|
|
7428
|
-
progress(opts.json,
|
|
7679
|
+
progress(opts.json, import_chalk32.default.dim(`Sender: ${sender.did}`));
|
|
7680
|
+
progress(opts.json, import_chalk32.default.dim(`Recipient: ${recipientDid}`));
|
|
7429
7681
|
await guardRecipientReachable(api, recipientDid, { requireOnline: opts.requireOnline });
|
|
7430
7682
|
const content = {};
|
|
7431
7683
|
if (opts.greeting) content.greeting = opts.greeting;
|
|
@@ -7452,7 +7704,7 @@ async function runSendHandshake(recipientDid, opts) {
|
|
|
7452
7704
|
identitySecretKey: signer.identitySecretKey
|
|
7453
7705
|
});
|
|
7454
7706
|
if (opts.verbose) {
|
|
7455
|
-
console.log(
|
|
7707
|
+
console.log(import_chalk32.default.bold("\nEnvelope (pre-send):"));
|
|
7456
7708
|
console.log(formatJson(envelope));
|
|
7457
7709
|
}
|
|
7458
7710
|
const result = await api.ingest(envelope);
|
|
@@ -7472,23 +7724,23 @@ async function runSendHandshake(recipientDid, opts) {
|
|
|
7472
7724
|
});
|
|
7473
7725
|
return;
|
|
7474
7726
|
}
|
|
7475
|
-
console.log(
|
|
7476
|
-
console.log(`${
|
|
7477
|
-
console.log(`${
|
|
7478
|
-
console.log(`${
|
|
7479
|
-
console.log(`${
|
|
7480
|
-
console.log(`${
|
|
7481
|
-
console.log(`${
|
|
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)}`);
|
|
7482
7734
|
if (result.prevServerEventHash) {
|
|
7483
|
-
console.log(`${
|
|
7735
|
+
console.log(`${import_chalk32.default.bold("Prev server event hash")}: ${import_chalk32.default.cyan(result.prevServerEventHash)}`);
|
|
7484
7736
|
} else {
|
|
7485
|
-
console.log(`${
|
|
7737
|
+
console.log(`${import_chalk32.default.bold("Prev server event hash")}: ${import_chalk32.default.dim("(null \u2014 first event of this relationship)")}`);
|
|
7486
7738
|
}
|
|
7487
7739
|
if (opts.verbose) {
|
|
7488
|
-
console.log(
|
|
7740
|
+
console.log(import_chalk32.default.bold("\nFull server response:"));
|
|
7489
7741
|
console.log(formatJson(result));
|
|
7490
7742
|
}
|
|
7491
|
-
console.log(
|
|
7743
|
+
console.log(import_chalk32.default.dim(`
|
|
7492
7744
|
Local sender_sequence advanced to ${nextSequence}.`));
|
|
7493
7745
|
}
|
|
7494
7746
|
function parseTtl3(raw) {
|
|
@@ -7502,7 +7754,7 @@ function parseTtl3(raw) {
|
|
|
7502
7754
|
|
|
7503
7755
|
// src/commands/send-handshake-response.ts
|
|
7504
7756
|
var import_sdk29 = require("@heyanon-arp/sdk");
|
|
7505
|
-
var
|
|
7757
|
+
var import_chalk33 = __toESM(require("chalk"));
|
|
7506
7758
|
init_api();
|
|
7507
7759
|
var ALLOWED_DECISIONS = new Set(import_sdk29.HANDSHAKE_DECISIONS);
|
|
7508
7760
|
function registerSendHandshakeResponseCommand(root) {
|
|
@@ -7543,11 +7795,11 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7543
7795
|
declinePayload = detail ? { reason, reasonDetail: detail } : { reason };
|
|
7544
7796
|
}
|
|
7545
7797
|
const api = new ArpApiClient(opts.server);
|
|
7546
|
-
progress(opts.json,
|
|
7798
|
+
progress(opts.json, import_chalk33.default.dim(`Server: ${api.serverUrl}`));
|
|
7547
7799
|
const sender = resolveSenderAgent("send-handshake-response", opts.server, opts.fromDid, opts.from);
|
|
7548
|
-
progress(opts.json,
|
|
7549
|
-
progress(opts.json,
|
|
7550
|
-
progress(opts.json,
|
|
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}`));
|
|
7551
7803
|
const signer = makeSigner(sender);
|
|
7552
7804
|
if (!opts.force) {
|
|
7553
7805
|
try {
|
|
@@ -7577,13 +7829,13 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7577
7829
|
});
|
|
7578
7830
|
return;
|
|
7579
7831
|
}
|
|
7580
|
-
progress(opts.json,
|
|
7832
|
+
progress(opts.json, import_chalk33.default.yellow(`
|
|
7581
7833
|
[--idempotency] Relationship ${existing.relationshipId} with ${recipientDid} is already 'active'.`));
|
|
7582
7834
|
progress(
|
|
7583
7835
|
opts.json,
|
|
7584
|
-
|
|
7836
|
+
import_chalk33.default.dim(`A previous accept from this signer (event ${previousResponseFromMe.eventId}) landed successfully. Skipping re-send (use --force to override).`)
|
|
7585
7837
|
);
|
|
7586
|
-
progress(opts.json,
|
|
7838
|
+
progress(opts.json, import_chalk33.default.dim(`Last event index: ${existing.lastEventIndex}, last server event hash: ${existing.lastServerEventHash ?? "(none)"}`));
|
|
7587
7839
|
return;
|
|
7588
7840
|
}
|
|
7589
7841
|
throw new Error(
|
|
@@ -7594,7 +7846,7 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7594
7846
|
if (probeErr instanceof Error && /CLOSED|terminated|already 'active' from a previous ACCEPT|original initiator/i.test(probeErr.message)) {
|
|
7595
7847
|
throw probeErr;
|
|
7596
7848
|
}
|
|
7597
|
-
progress(opts.json,
|
|
7849
|
+
progress(opts.json, import_chalk33.default.dim(`(idempotency probe failed; proceeding anyway: ${probeErr.message})`));
|
|
7598
7850
|
}
|
|
7599
7851
|
}
|
|
7600
7852
|
const content = { decision };
|
|
@@ -7624,7 +7876,7 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7624
7876
|
identitySecretKey: signer.identitySecretKey
|
|
7625
7877
|
});
|
|
7626
7878
|
if (opts.verbose) {
|
|
7627
|
-
console.log(
|
|
7879
|
+
console.log(import_chalk33.default.bold("\nEnvelope (pre-send):"));
|
|
7628
7880
|
console.log(formatJson(envelope));
|
|
7629
7881
|
}
|
|
7630
7882
|
const result = await api.ingest(envelope);
|
|
@@ -7645,23 +7897,23 @@ async function runSendHandshakeResponse(recipientDid, opts) {
|
|
|
7645
7897
|
});
|
|
7646
7898
|
return;
|
|
7647
7899
|
}
|
|
7648
|
-
console.log(
|
|
7649
|
-
console.log(`${
|
|
7650
|
-
console.log(`${
|
|
7651
|
-
console.log(`${
|
|
7652
|
-
console.log(`${
|
|
7653
|
-
console.log(`${
|
|
7654
|
-
console.log(`${
|
|
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)}`);
|
|
7655
7907
|
if (result.prevServerEventHash) {
|
|
7656
|
-
console.log(`${
|
|
7908
|
+
console.log(`${import_chalk33.default.bold("Prev server event hash")}: ${import_chalk33.default.cyan(result.prevServerEventHash)}`);
|
|
7657
7909
|
} else {
|
|
7658
|
-
console.log(`${
|
|
7910
|
+
console.log(`${import_chalk33.default.bold("Prev server event hash")}: ${import_chalk33.default.dim("(null \u2014 first event of this relationship)")}`);
|
|
7659
7911
|
}
|
|
7660
7912
|
if (opts.verbose) {
|
|
7661
|
-
console.log(
|
|
7913
|
+
console.log(import_chalk33.default.bold("\nFull server response:"));
|
|
7662
7914
|
console.log(formatJson(result));
|
|
7663
7915
|
}
|
|
7664
|
-
console.log(
|
|
7916
|
+
console.log(import_chalk33.default.dim(`
|
|
7665
7917
|
Local sender_sequence advanced to ${nextSequence}.`));
|
|
7666
7918
|
}
|
|
7667
7919
|
function parseDecision(raw) {
|
|
@@ -7711,8 +7963,64 @@ async function findExistingRelationship(api, signer, senderDid, recipientDid) {
|
|
|
7711
7963
|
return void 0;
|
|
7712
7964
|
}
|
|
7713
7965
|
|
|
7966
|
+
// src/commands/stats.ts
|
|
7967
|
+
var import_chalk34 = __toESM(require("chalk"));
|
|
7968
|
+
init_api();
|
|
7969
|
+
function registerStatsCommand(root) {
|
|
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) => {
|
|
7971
|
+
const did = await resolveRecipient(opts.server, "stats", agent, { json: opts.json });
|
|
7972
|
+
const api = new ArpApiClient(opts.server);
|
|
7973
|
+
const stats = await api.getStats(did);
|
|
7974
|
+
if (opts.json) {
|
|
7975
|
+
jsonOut(stats);
|
|
7976
|
+
return;
|
|
7977
|
+
}
|
|
7978
|
+
const j = false;
|
|
7979
|
+
const { counters: c, scores: s, rates: r, volume: v } = stats;
|
|
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)"}`));
|
|
7982
|
+
progress(j, "");
|
|
7983
|
+
progress(
|
|
7984
|
+
j,
|
|
7985
|
+
` scores composite ${s.composite.toFixed(0)} \xB7 reliability ${s.reliability.toFixed(0)} \xB7 settlement ${s.settlement.toFixed(0)} \xB7 disputeHealth ${s.disputeHealth.toFixed(0)}`
|
|
7986
|
+
);
|
|
7987
|
+
progress(j, ` rates completion ${pct(r.completionRate)} \xB7 dispute ${pct(r.disputeRate)} \xB7 adverse ${pct(r.adverseDisputeRate)}`);
|
|
7988
|
+
progress(
|
|
7989
|
+
j,
|
|
7990
|
+
` cycles on-chain ${c.onchainCycles} \xB7 completed ${c.completedDelegations} (payer ${c.completedAsPayer} / payee ${c.completedAsPayee}) \xB7 failed ${c.failedDelegations}`
|
|
7991
|
+
);
|
|
7992
|
+
progress(j, ` escrows settled ${c.settledEscrows} / refunded ${c.refundedEscrows} \xB7 disputed ${c.disputedEscrows} (adverse ${c.disputesAdverse})`);
|
|
7993
|
+
progress(j, ` network distinct counterparts ${c.distinctCounterparts} \xB7 active relationships ${c.activeRelationships}`);
|
|
7994
|
+
progress(j, "");
|
|
7995
|
+
progress(j, import_chalk34.default.dim(" earned (as payee):"));
|
|
7996
|
+
renderAssets(v.earnedByAsset);
|
|
7997
|
+
progress(j, import_chalk34.default.dim(" paid (as payer):"));
|
|
7998
|
+
renderAssets(v.paidByAsset);
|
|
7999
|
+
if (v.firstSettledAt || v.lastSettledAt) {
|
|
8000
|
+
progress(j, "");
|
|
8001
|
+
progress(j, import_chalk34.default.dim(` settled span: ${v.firstSettledAt ?? "?"} \u2192 ${v.lastSettledAt ?? "?"}`));
|
|
8002
|
+
}
|
|
8003
|
+
progress(j, "");
|
|
8004
|
+
progress(j, import_chalk34.default.dim(" Public, informational \u2014 derived from on-chain settlement; cached briefly."));
|
|
8005
|
+
});
|
|
8006
|
+
}
|
|
8007
|
+
function pct(r) {
|
|
8008
|
+
return r == null ? "n/a" : `${(r * 100).toFixed(0)}%`;
|
|
8009
|
+
}
|
|
8010
|
+
function renderAssets(assets) {
|
|
8011
|
+
if (assets.length === 0) {
|
|
8012
|
+
progress(false, import_chalk34.default.dim(" (none)"));
|
|
8013
|
+
return;
|
|
8014
|
+
}
|
|
8015
|
+
for (const a of assets) {
|
|
8016
|
+
const label = a.symbol ?? `${a.mint.slice(0, 6)}\u2026`;
|
|
8017
|
+
const amount = a.amountDecimal ?? `${a.amountBaseUnits} base-units`;
|
|
8018
|
+
progress(false, ` ${amount} ${label} ${import_chalk34.default.dim(`(${a.lockCount} lock${a.lockCount === 1 ? "" : "s"})`)}`);
|
|
8019
|
+
}
|
|
8020
|
+
}
|
|
8021
|
+
|
|
7714
8022
|
// src/commands/watch.ts
|
|
7715
|
-
var
|
|
8023
|
+
var import_chalk35 = __toESM(require("chalk"));
|
|
7716
8024
|
init_api();
|
|
7717
8025
|
function registerWatchCommand(root) {
|
|
7718
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) => {
|
|
@@ -7723,9 +8031,9 @@ async function runWatch(relationshipId, opts) {
|
|
|
7723
8031
|
const local = resolveSenderAgent("watch", opts.server, opts.fromDid, opts.from);
|
|
7724
8032
|
const api = new ArpApiClient(opts.server);
|
|
7725
8033
|
if (!opts.json) {
|
|
7726
|
-
console.log(
|
|
7727
|
-
console.log(
|
|
7728
|
-
console.log(
|
|
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}`));
|
|
7729
8037
|
}
|
|
7730
8038
|
const controller = new AbortController();
|
|
7731
8039
|
let userAborted = false;
|
|
@@ -7744,7 +8052,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7744
8052
|
}
|
|
7745
8053
|
if (event.type === "heartbeat") continue;
|
|
7746
8054
|
if (event.type === "connected") {
|
|
7747
|
-
console.log(
|
|
8055
|
+
console.log(import_chalk35.default.green(`\u25CF stream open \u2014 watching ${relationshipId}`));
|
|
7748
8056
|
continue;
|
|
7749
8057
|
}
|
|
7750
8058
|
if (event.type === "envelope") {
|
|
@@ -7758,7 +8066,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7758
8066
|
}
|
|
7759
8067
|
continue;
|
|
7760
8068
|
}
|
|
7761
|
-
console.log(
|
|
8069
|
+
console.log(import_chalk35.default.dim(`(unknown event: ${event.type})`));
|
|
7762
8070
|
}
|
|
7763
8071
|
if (!userAborted) {
|
|
7764
8072
|
throw new Error(`watch ${relationshipId}: stream ended unexpectedly (server may have restarted, or the change stream errored). Re-run to reconnect.`);
|
|
@@ -7766,7 +8074,7 @@ async function runWatch(relationshipId, opts) {
|
|
|
7766
8074
|
} catch (err) {
|
|
7767
8075
|
const name = err.name;
|
|
7768
8076
|
if (name === "AbortError" || userAborted) {
|
|
7769
|
-
if (!opts.json) console.log(
|
|
8077
|
+
if (!opts.json) console.log(import_chalk35.default.dim("\nstream closed."));
|
|
7770
8078
|
return;
|
|
7771
8079
|
}
|
|
7772
8080
|
throw err;
|
|
@@ -7780,21 +8088,21 @@ function formatWatchLine(ev, selfDid, opts = {}) {
|
|
|
7780
8088
|
const type = ev.type.padEnd(20);
|
|
7781
8089
|
const direction = directionLabel2(ev, selfDid, opts);
|
|
7782
8090
|
const hash = opts.fullIds ? ev.serverEventHash : hashHead4(ev.serverEventHash);
|
|
7783
|
-
return `${
|
|
8091
|
+
return `${import_chalk35.default.dim(`[${ts}]`)} ${type} ${direction} ${import_chalk35.default.cyan(hash)}`;
|
|
7784
8092
|
}
|
|
7785
8093
|
function directionLabel2(ev, selfDid, opts = {}) {
|
|
7786
8094
|
const senderHead = opts.fullIds ? ev.senderDid : didHead4(ev.senderDid);
|
|
7787
8095
|
const recipientHead = opts.fullIds ? ev.recipientDid : didHead4(ev.recipientDid);
|
|
7788
|
-
if (ev.senderDid === selfDid) return `${
|
|
7789
|
-
if (ev.recipientDid === selfDid) return `${
|
|
7790
|
-
return `${
|
|
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)}`;
|
|
7791
8099
|
}
|
|
7792
8100
|
function didHead4(did) {
|
|
7793
8101
|
if (did.length <= 20) return did;
|
|
7794
8102
|
return `${did.slice(0, 20)}...`;
|
|
7795
8103
|
}
|
|
7796
8104
|
function hashHead4(hash) {
|
|
7797
|
-
if (!hash) return
|
|
8105
|
+
if (!hash) return import_chalk35.default.dim("(none)");
|
|
7798
8106
|
if (hash.length <= 14) return hash;
|
|
7799
8107
|
return `${hash.slice(0, 14)}...`;
|
|
7800
8108
|
}
|
|
@@ -7806,7 +8114,7 @@ function formatClock(iso) {
|
|
|
7806
8114
|
}
|
|
7807
8115
|
|
|
7808
8116
|
// src/commands/whoami.ts
|
|
7809
|
-
var
|
|
8117
|
+
var import_chalk36 = __toESM(require("chalk"));
|
|
7810
8118
|
init_api();
|
|
7811
8119
|
function registerWhoamiCommand(root) {
|
|
7812
8120
|
root.command("whoami").description(
|
|
@@ -7837,12 +8145,12 @@ function registerWhoamiCommand(root) {
|
|
|
7837
8145
|
if (opts.json) {
|
|
7838
8146
|
console.log(formatJson({ ...localJson, account: credential ? { wallet: credential.wallet } : null }));
|
|
7839
8147
|
} else {
|
|
7840
|
-
console.log(
|
|
7841
|
-
console.log(` DID: ${
|
|
7842
|
-
console.log(` Settlement pubkey: ${
|
|
7843
|
-
console.log(` Identity pubkey: ${
|
|
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)}`);
|
|
7844
8152
|
if (local.name) console.log(` Name: ${local.name}`);
|
|
7845
|
-
console.log(` Account: ${credential ?
|
|
8153
|
+
console.log(` Account: ${credential ? import_chalk36.default.cyan(credential.wallet) : import_chalk36.default.dim("not logged in (heyarp login)")}`);
|
|
7846
8154
|
}
|
|
7847
8155
|
return;
|
|
7848
8156
|
}
|
|
@@ -7860,19 +8168,19 @@ function registerWhoamiCommand(root) {
|
|
|
7860
8168
|
if (opts.json) {
|
|
7861
8169
|
console.log(formatJson({ local: localJson, account, server: agent }));
|
|
7862
8170
|
} else {
|
|
7863
|
-
console.log(
|
|
7864
|
-
console.log(
|
|
7865
|
-
console.log(` DID: ${
|
|
7866
|
-
console.log(` Settlement pubkey: ${
|
|
7867
|
-
console.log(` Identity pubkey: ${
|
|
7868
|
-
console.log(
|
|
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:"));
|
|
7869
8177
|
if (account) {
|
|
7870
|
-
console.log(` Wallet: ${
|
|
8178
|
+
console.log(` Wallet: ${import_chalk36.default.cyan(account.wallet)}`);
|
|
7871
8179
|
console.log(` Agents registered: ${account.agentCount}`);
|
|
7872
8180
|
} else {
|
|
7873
|
-
console.log(` ${
|
|
8181
|
+
console.log(` ${import_chalk36.default.dim("not logged in (heyarp login)")}`);
|
|
7874
8182
|
}
|
|
7875
|
-
console.log(
|
|
8183
|
+
console.log(import_chalk36.default.bold("\nServer profile:"));
|
|
7876
8184
|
console.log(formatJson(agent));
|
|
7877
8185
|
}
|
|
7878
8186
|
} catch (err) {
|
|
@@ -7884,12 +8192,12 @@ function registerWhoamiCommand(root) {
|
|
|
7884
8192
|
|
|
7885
8193
|
// src/commands/whois.ts
|
|
7886
8194
|
var import_sdk30 = require("@heyanon-arp/sdk");
|
|
7887
|
-
var
|
|
8195
|
+
var import_chalk37 = __toESM(require("chalk"));
|
|
7888
8196
|
init_api();
|
|
7889
8197
|
function registerWhoisCommand(root) {
|
|
7890
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) => {
|
|
7891
8199
|
const api = new ArpApiClient(opts.server);
|
|
7892
|
-
progress(opts.json,
|
|
8200
|
+
progress(opts.json, import_chalk37.default.dim(`Server: ${api.serverUrl}`));
|
|
7893
8201
|
const profile = await resolveProfile(api, input);
|
|
7894
8202
|
if (opts.json) {
|
|
7895
8203
|
jsonOut(profile);
|
|
@@ -7912,19 +8220,19 @@ async function resolveProfile(api, input) {
|
|
|
7912
8220
|
return api.discoverByName(name);
|
|
7913
8221
|
}
|
|
7914
8222
|
function printProfile(p) {
|
|
7915
|
-
console.log(`${
|
|
7916
|
-
console.log(`${
|
|
7917
|
-
if (p.description) console.log(`${
|
|
7918
|
-
if (p.tags.length > 0) console.log(`${
|
|
7919
|
-
console.log(`${
|
|
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}`);
|
|
7920
8228
|
const rep = p.reputation;
|
|
7921
|
-
console.log(`${
|
|
7922
|
-
console.log(`${
|
|
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")}`);
|
|
7923
8231
|
}
|
|
7924
8232
|
|
|
7925
8233
|
// src/commands/work.ts
|
|
7926
8234
|
var import_sdk31 = require("@heyanon-arp/sdk");
|
|
7927
|
-
var
|
|
8235
|
+
var import_chalk38 = __toESM(require("chalk"));
|
|
7928
8236
|
init_api();
|
|
7929
8237
|
function registerWorkCommands(root) {
|
|
7930
8238
|
const cmd = root.command("work").description("Work envelopes inside an ACCEPTED delegation: request / respond");
|
|
@@ -7965,11 +8273,11 @@ async function runRequest(recipientDid, delegationId, opts) {
|
|
|
7965
8273
|
params
|
|
7966
8274
|
};
|
|
7967
8275
|
const body = { type: "work_request", content };
|
|
7968
|
-
progress(opts.json,
|
|
7969
|
-
progress(opts.json,
|
|
7970
|
-
progress(opts.json,
|
|
7971
|
-
progress(opts.json,
|
|
7972
|
-
progress(opts.json,
|
|
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}`));
|
|
7973
8281
|
const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
7974
8282
|
if (opts.json) {
|
|
7975
8283
|
jsonOut({
|
|
@@ -7986,10 +8294,10 @@ async function runRequest(recipientDid, delegationId, opts) {
|
|
|
7986
8294
|
});
|
|
7987
8295
|
} else {
|
|
7988
8296
|
printIngestResult3(result);
|
|
7989
|
-
console.log(
|
|
8297
|
+
console.log(import_chalk38.default.dim(`
|
|
7990
8298
|
The payee can reply with:`));
|
|
7991
|
-
console.log(
|
|
7992
|
-
console.log(
|
|
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`));
|
|
7993
8301
|
}
|
|
7994
8302
|
}
|
|
7995
8303
|
function registerRespond(parent) {
|
|
@@ -8024,13 +8332,13 @@ async function runRespond(relationshipId, delegationId, requestId, opts) {
|
|
|
8024
8332
|
...responsePayload
|
|
8025
8333
|
};
|
|
8026
8334
|
const body = { type: "work_response", content };
|
|
8027
|
-
progress(opts.json,
|
|
8028
|
-
progress(opts.json,
|
|
8029
|
-
progress(opts.json,
|
|
8030
|
-
progress(opts.json,
|
|
8031
|
-
progress(opts.json,
|
|
8032
|
-
progress(opts.json,
|
|
8033
|
-
progress(opts.json,
|
|
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"}`));
|
|
8034
8342
|
const result = await sendWorkEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
8035
8343
|
if (opts.json) {
|
|
8036
8344
|
jsonOut({
|
|
@@ -8071,7 +8379,7 @@ async function sendWorkEnvelope(args) {
|
|
|
8071
8379
|
identitySecretKey: signer.identitySecretKey
|
|
8072
8380
|
});
|
|
8073
8381
|
if (args.verbose) {
|
|
8074
|
-
console.log(
|
|
8382
|
+
console.log(import_chalk38.default.bold("\nEnvelope (pre-send):"));
|
|
8075
8383
|
console.log(formatJson(envelope));
|
|
8076
8384
|
}
|
|
8077
8385
|
try {
|
|
@@ -8111,12 +8419,12 @@ async function resolveResponseRecipient(cmdName, api, signer, args) {
|
|
|
8111
8419
|
);
|
|
8112
8420
|
}
|
|
8113
8421
|
function printIngestResult3(result) {
|
|
8114
|
-
console.log(
|
|
8115
|
-
console.log(`${
|
|
8116
|
-
console.log(`${
|
|
8117
|
-
console.log(`${
|
|
8118
|
-
console.log(`${
|
|
8119
|
-
console.log(`${
|
|
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)}`);
|
|
8120
8428
|
}
|
|
8121
8429
|
function parseJsonObject(cmdName, flagName, raw) {
|
|
8122
8430
|
let parsed;
|
|
@@ -8154,8 +8462,8 @@ function parseParamsInput(cmdName, opts) {
|
|
|
8154
8462
|
return parseJsonObject(cmdName, "--params", opts.params ?? "{}");
|
|
8155
8463
|
}
|
|
8156
8464
|
function readJsonObjectFile(cmdName, flagName, path) {
|
|
8157
|
-
const { existsSync:
|
|
8158
|
-
if (!
|
|
8465
|
+
const { existsSync: existsSync8, readFileSync: readFileSync10 } = require("fs");
|
|
8466
|
+
if (!existsSync8(path)) {
|
|
8159
8467
|
throw new Error(`${cmdName}: ${flagName} file not found at ${path}`);
|
|
8160
8468
|
}
|
|
8161
8469
|
let raw;
|
|
@@ -8218,7 +8526,7 @@ function parseRequestId(cmdName, raw) {
|
|
|
8218
8526
|
|
|
8219
8527
|
// src/commands/work-list.ts
|
|
8220
8528
|
var import_sdk32 = require("@heyanon-arp/sdk");
|
|
8221
|
-
var
|
|
8529
|
+
var import_chalk39 = __toESM(require("chalk"));
|
|
8222
8530
|
init_api();
|
|
8223
8531
|
var ALLOWED_STATES3 = new Set(import_sdk32.WORK_LOG_STATES);
|
|
8224
8532
|
function registerWorkListCommand(root) {
|
|
@@ -8245,9 +8553,9 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8245
8553
|
const api = new ArpApiClient(opts.server);
|
|
8246
8554
|
const sender = resolveSenderAgent("work-list", opts.server, opts.fromDid, opts.from);
|
|
8247
8555
|
if (!opts.json) {
|
|
8248
|
-
console.log(
|
|
8249
|
-
console.log(
|
|
8250
|
-
console.log(
|
|
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}`));
|
|
8251
8559
|
}
|
|
8252
8560
|
const query = { limit };
|
|
8253
8561
|
if (state) query.state = state;
|
|
@@ -8260,7 +8568,7 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8260
8568
|
return;
|
|
8261
8569
|
}
|
|
8262
8570
|
if (rows.length === 0) {
|
|
8263
|
-
console.log(
|
|
8571
|
+
console.log(import_chalk39.default.dim("\n(no work-logs for this relationship)"));
|
|
8264
8572
|
return;
|
|
8265
8573
|
}
|
|
8266
8574
|
console.log("");
|
|
@@ -8277,36 +8585,36 @@ async function runWorkList(relationshipId, opts) {
|
|
|
8277
8585
|
}));
|
|
8278
8586
|
}
|
|
8279
8587
|
const lastId = rows[rows.length - 1].id;
|
|
8280
|
-
console.log(
|
|
8588
|
+
console.log(import_chalk39.default.dim(`
|
|
8281
8589
|
${rows.length} work-log row(s). Paginate with --after ${lastId}.`));
|
|
8282
8590
|
}
|
|
8283
8591
|
function formatWorkLogLine(w, selfDid, opts = {}) {
|
|
8284
8592
|
const delegationPart = opts.fullIds ? w.delegationId : idHead3(w.delegationId);
|
|
8285
8593
|
const requestPart = opts.fullIds ? w.requestId : truncate3(w.requestId, 16);
|
|
8286
|
-
const id =
|
|
8594
|
+
const id = import_chalk39.default.bold(`${delegationPart}/${requestPart}`);
|
|
8287
8595
|
const state = colorState2(w.state).padEnd(stateColumnWidth2());
|
|
8288
8596
|
const peerCallerHead = opts.fullIds ? w.callerDid : didHead5(w.callerDid);
|
|
8289
8597
|
const peerPayeeHead = opts.fullIds ? w.payeeDid : didHead5(w.payeeDid);
|
|
8290
|
-
const direction = w.callerDid === selfDid ? `${
|
|
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")}`;
|
|
8291
8599
|
const outcome = formatOutcome(w);
|
|
8292
8600
|
return `${id} ${state} ${direction} ${outcome}`;
|
|
8293
8601
|
}
|
|
8294
8602
|
function colorState2(s) {
|
|
8295
8603
|
switch (s) {
|
|
8296
8604
|
case import_sdk32.WorkLogStates.REQUESTED:
|
|
8297
|
-
return
|
|
8605
|
+
return import_chalk39.default.yellow("requested");
|
|
8298
8606
|
case import_sdk32.WorkLogStates.RESPONDED:
|
|
8299
|
-
return
|
|
8607
|
+
return import_chalk39.default.green("responded");
|
|
8300
8608
|
}
|
|
8301
8609
|
}
|
|
8302
8610
|
function stateColumnWidth2() {
|
|
8303
8611
|
return 9;
|
|
8304
8612
|
}
|
|
8305
8613
|
function formatOutcome(w) {
|
|
8306
|
-
if (w.state === import_sdk32.WorkLogStates.REQUESTED) return
|
|
8307
|
-
if (w.responseError) return
|
|
8308
|
-
if (w.responseOutput) return
|
|
8309
|
-
return
|
|
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)");
|
|
8310
8618
|
}
|
|
8311
8619
|
function idHead3(id) {
|
|
8312
8620
|
if (id.length <= 12) return id;
|
|
@@ -8374,12 +8682,12 @@ function unknownOptionHint(program, err) {
|
|
|
8374
8682
|
}
|
|
8375
8683
|
|
|
8376
8684
|
// src/version-gate.ts
|
|
8377
|
-
var
|
|
8378
|
-
var
|
|
8685
|
+
var import_node_fs11 = require("fs");
|
|
8686
|
+
var import_node_path8 = require("path");
|
|
8379
8687
|
init_paths();
|
|
8380
8688
|
var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
8381
8689
|
var REGISTRY_TIMEOUT_MS = 1500;
|
|
8382
|
-
var cacheFile = () => (0,
|
|
8690
|
+
var cacheFile = () => (0, import_node_path8.join)(arpHomeDir(), "update-check.json");
|
|
8383
8691
|
function majorOf(version) {
|
|
8384
8692
|
return Number.parseInt(version.split(".")[0] ?? "0", 10) || 0;
|
|
8385
8693
|
}
|
|
@@ -8411,7 +8719,7 @@ async function fetchLatest(pkgName) {
|
|
|
8411
8719
|
}
|
|
8412
8720
|
async function resolveLatest(pkgName) {
|
|
8413
8721
|
try {
|
|
8414
|
-
const cached = JSON.parse((0,
|
|
8722
|
+
const cached = JSON.parse((0, import_node_fs11.readFileSync)(cacheFile(), "utf8"));
|
|
8415
8723
|
if (typeof cached.latest === "string" && typeof cached.checkedAt === "number" && Date.now() - cached.checkedAt < CHECK_INTERVAL_MS) {
|
|
8416
8724
|
return cached.latest;
|
|
8417
8725
|
}
|
|
@@ -8421,8 +8729,8 @@ async function resolveLatest(pkgName) {
|
|
|
8421
8729
|
if (!fresh) return null;
|
|
8422
8730
|
try {
|
|
8423
8731
|
const file = cacheFile();
|
|
8424
|
-
(0,
|
|
8425
|
-
(0,
|
|
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 }));
|
|
8426
8734
|
} catch {
|
|
8427
8735
|
}
|
|
8428
8736
|
return fresh;
|
|
@@ -8486,6 +8794,7 @@ async function main() {
|
|
|
8486
8794
|
registerDidDocCommand(program);
|
|
8487
8795
|
registerProfileCommand(program);
|
|
8488
8796
|
registerDoctorCommand(program);
|
|
8797
|
+
registerSelftestCommand(program);
|
|
8489
8798
|
registerAssetsCommand(program);
|
|
8490
8799
|
registerEscrowCommands(program);
|
|
8491
8800
|
registerWhoamiCommand(program);
|
|
@@ -8508,6 +8817,7 @@ async function main() {
|
|
|
8508
8817
|
registerReceiptCommands(program);
|
|
8509
8818
|
registerReceiptsCommand(program);
|
|
8510
8819
|
registerReputationCommand(program);
|
|
8820
|
+
registerStatsCommand(program);
|
|
8511
8821
|
registerWalletCommands(program);
|
|
8512
8822
|
(0, import_shield3.installMiddleware)(program);
|
|
8513
8823
|
try {
|