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