@heyanon-arp/cli 0.0.10 → 0.0.12
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 +288 -89
- package/dist/cli.js.map +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -246,10 +246,11 @@ function parseSseRecord(record) {
|
|
|
246
246
|
}
|
|
247
247
|
return id !== void 0 ? { type, data, id } : { type, data };
|
|
248
248
|
}
|
|
249
|
-
var import_sdk, DEFAULT_SERVER_URL, ApiError, ArpApiClient;
|
|
249
|
+
var import_sdk, import_shield, DEFAULT_SERVER_URL, ApiError, ArpApiClient;
|
|
250
250
|
var init_api = __esm({
|
|
251
251
|
"src/api.ts"() {
|
|
252
252
|
import_sdk = require("@heyanon-arp/sdk");
|
|
253
|
+
import_shield = require("@heyanon-arp/shield");
|
|
253
254
|
init_config();
|
|
254
255
|
DEFAULT_SERVER_URL = "https://api.heyanon.ai/arp";
|
|
255
256
|
ApiError = class extends Error {
|
|
@@ -382,7 +383,14 @@ var init_api = __esm({
|
|
|
382
383
|
const record = buffer.slice(0, recordEnd);
|
|
383
384
|
buffer = buffer.slice(recordEnd + 2);
|
|
384
385
|
const event = parseSseRecord(record);
|
|
385
|
-
if (event !== null)
|
|
386
|
+
if (event !== null) {
|
|
387
|
+
if (event.type === "envelope" && event.data !== null && typeof event.data === "object") {
|
|
388
|
+
const guarded = await (0, import_shield.guardInboundEvent)(event.data, { selfDid: did });
|
|
389
|
+
yield { ...event, data: guarded.event };
|
|
390
|
+
} else {
|
|
391
|
+
yield event;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
386
394
|
recordEnd = buffer.indexOf("\n\n");
|
|
387
395
|
}
|
|
388
396
|
}
|
|
@@ -441,13 +449,14 @@ var init_api = __esm({
|
|
|
441
449
|
* walks FORWARD from a watermark (polling-worker pattern).
|
|
442
450
|
*/
|
|
443
451
|
async listInbox(did, signer, query) {
|
|
444
|
-
|
|
452
|
+
const events = await this.signedRequest(
|
|
445
453
|
"GET",
|
|
446
454
|
`/v1/agents/${encodeURIComponent(did)}/inbox`,
|
|
447
455
|
null,
|
|
448
456
|
signer,
|
|
449
457
|
query
|
|
450
458
|
);
|
|
459
|
+
return (0, import_shield.guardInboundBatch)(events, { selfDid: did });
|
|
451
460
|
}
|
|
452
461
|
/**
|
|
453
462
|
* Signed `GET /v1/agents/:did/events/:eventId`. Direct envelope
|
|
@@ -461,7 +470,8 @@ var init_api = __esm({
|
|
|
461
470
|
* not-a-member-of-pair.
|
|
462
471
|
*/
|
|
463
472
|
async getEvent(did, eventId, signer) {
|
|
464
|
-
|
|
473
|
+
const event = await this.signedRequest("GET", `/v1/agents/${encodeURIComponent(did)}/events/${encodeURIComponent(eventId)}`, null, signer);
|
|
474
|
+
return (await (0, import_shield.guardInboundEvent)(event, { selfDid: did })).event;
|
|
465
475
|
}
|
|
466
476
|
/**
|
|
467
477
|
* Signed `GET /v1/relationships/:id/events`. Returns the canonical
|
|
@@ -469,13 +479,14 @@ var init_api = __esm({
|
|
|
469
479
|
* one of the relationship pair.
|
|
470
480
|
*/
|
|
471
481
|
async listEvents(relationshipId, signer, query) {
|
|
472
|
-
|
|
482
|
+
const events = await this.signedRequest(
|
|
473
483
|
"GET",
|
|
474
484
|
`/v1/relationships/${encodeURIComponent(relationshipId)}/events`,
|
|
475
485
|
null,
|
|
476
486
|
signer,
|
|
477
487
|
query
|
|
478
488
|
);
|
|
489
|
+
return (0, import_shield.guardInboundBatch)(events, { selfDid: signer.did });
|
|
479
490
|
}
|
|
480
491
|
/**
|
|
481
492
|
* Signed `GET /v1/relationships/:id/delegations`. One row per
|
|
@@ -485,7 +496,7 @@ var init_api = __esm({
|
|
|
485
496
|
* entity feed.
|
|
486
497
|
*/
|
|
487
498
|
async listDelegations(relationshipId, signer, query, signal) {
|
|
488
|
-
|
|
499
|
+
const rows = await this.signedRequest(
|
|
489
500
|
"GET",
|
|
490
501
|
`/v1/relationships/${encodeURIComponent(relationshipId)}/delegations`,
|
|
491
502
|
null,
|
|
@@ -493,6 +504,7 @@ var init_api = __esm({
|
|
|
493
504
|
query,
|
|
494
505
|
signal
|
|
495
506
|
);
|
|
507
|
+
return (0, import_shield.guardInboundFieldsBatch)(rows, ["scopeSummary", "title", "brief", "acceptanceCriteria"], { selfDid: signer.did });
|
|
496
508
|
}
|
|
497
509
|
/**
|
|
498
510
|
* Signed `GET /v1/relationships/:id/work`. One row per
|
|
@@ -502,13 +514,14 @@ var init_api = __esm({
|
|
|
502
514
|
* work-logs operating under a single delegation umbrella.
|
|
503
515
|
*/
|
|
504
516
|
async listWorkLogs(relationshipId, signer, query) {
|
|
505
|
-
|
|
517
|
+
const rows = await this.signedRequest(
|
|
506
518
|
"GET",
|
|
507
519
|
`/v1/relationships/${encodeURIComponent(relationshipId)}/work`,
|
|
508
520
|
null,
|
|
509
521
|
signer,
|
|
510
522
|
query
|
|
511
523
|
);
|
|
524
|
+
return (0, import_shield.guardInboundFieldsBatch)(rows, ["responseOutput", "requestParams"], { selfDid: signer.did });
|
|
512
525
|
}
|
|
513
526
|
/**
|
|
514
527
|
* Signed `GET /v1/relationships/:id/receipts`. One row per
|
|
@@ -759,45 +772,6 @@ var init_format = __esm({
|
|
|
759
772
|
}
|
|
760
773
|
});
|
|
761
774
|
|
|
762
|
-
// src/id-format.ts
|
|
763
|
-
function describeNonUuidShape(raw) {
|
|
764
|
-
if (raw === "") return "empty string";
|
|
765
|
-
if (raw.startsWith("del_") && UUID_RE.test(raw.slice(4))) {
|
|
766
|
-
return "looks like a delegation id with the canonical `del_` prefix. If this field expects a delegation_id, drop the `del_` prefix and pass the 36-char body. If this field expects a DIFFERENT id type (relationship_id / request_id), the `del_`-prefixed value belongs to the WRONG entity \u2014 look up the right row and copy its id";
|
|
767
|
-
}
|
|
768
|
-
if (raw.startsWith("evt_")) {
|
|
769
|
-
return "looks like an event id (evt_<uuid>) \u2014 this command expects a delegation/relationship/request id (UUID), which is a DIFFERENT column. Look up the row that emitted this event (`heyarp events <rel> --json`) and copy the appropriate id field";
|
|
770
|
-
}
|
|
771
|
-
if (raw.startsWith("did:arp:")) {
|
|
772
|
-
return "looks like a DID (agent identifier) \u2014 this command expects a delegation/relationship/request id (UUID), not a DID";
|
|
773
|
-
}
|
|
774
|
-
if (SHA256_PREFIX_RE.test(raw)) {
|
|
775
|
-
return "looks like a sha256:<hash> \u2014 this command expects a UUID, not a hash. sha256: ids show up in receipt_event_hash, request_hash, response_hash";
|
|
776
|
-
}
|
|
777
|
-
if (OBJECT_ID_24_HEX_RE.test(raw)) {
|
|
778
|
-
return "looks like a Mongo ObjectId (24-hex row id surfaced by some server read endpoints) rather than the expected UUID. Mongo ObjectIds and delegation ids are DIFFERENT formats";
|
|
779
|
-
}
|
|
780
|
-
if (UUID_NO_DASHES_RE.test(raw)) {
|
|
781
|
-
return "looks like a UUID with no dashes \u2014 canonical UUIDs need the 8-4-4-4-12 dash pattern (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)";
|
|
782
|
-
}
|
|
783
|
-
return void 0;
|
|
784
|
-
}
|
|
785
|
-
function requireUuid(cmdName, raw, label) {
|
|
786
|
-
if (UUID_RE.test(raw)) return;
|
|
787
|
-
const hint = describeNonUuidShape(raw);
|
|
788
|
-
const base = `${cmdName}: ${label} must be a UUID (got '${raw}')`;
|
|
789
|
-
throw new Error(hint ? `${base} \u2014 ${hint}` : base);
|
|
790
|
-
}
|
|
791
|
-
var UUID_RE, OBJECT_ID_24_HEX_RE, SHA256_PREFIX_RE, UUID_NO_DASHES_RE;
|
|
792
|
-
var init_id_format = __esm({
|
|
793
|
-
"src/id-format.ts"() {
|
|
794
|
-
UUID_RE = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
|
|
795
|
-
OBJECT_ID_24_HEX_RE = /^[0-9a-f]{24}$/;
|
|
796
|
-
SHA256_PREFIX_RE = /^sha256:[0-9a-f]{64}$/;
|
|
797
|
-
UUID_NO_DASHES_RE = /^[a-fA-F0-9]{32}$/;
|
|
798
|
-
}
|
|
799
|
-
});
|
|
800
|
-
|
|
801
775
|
// src/state.ts
|
|
802
776
|
function stateFilePath() {
|
|
803
777
|
return (0, import_node_path3.join)(arpHomeDir(), "agents.json");
|
|
@@ -936,7 +910,7 @@ var init_state = __esm({
|
|
|
936
910
|
|
|
937
911
|
// src/commands/lifecycle.ts
|
|
938
912
|
function registerLifecycleCommands(root) {
|
|
939
|
-
root.command("update").description("Update an agent profile (name / description / tags). At least one flag is required.").argument("<did>").option("--server <url>", "Override ARP server base URL").option("--name <s>", "New display name").option("--description <s>", "New description").option("--tag <s>", "Capability tag \u2014 REPLACES the existing list. Repeatable: --tag translation --tag fr",
|
|
913
|
+
root.command("update").description("Update an agent profile (name / description / tags). At least one flag is required.").argument("<did>").option("--server <url>", "Override ARP server base URL").option("--name <s>", "New display name").option("--description <s>", "New description").option("--tag <s>", "Capability tag \u2014 REPLACES the existing list. Repeatable: --tag translation --tag fr", accumulate, []).option("--clear-tags", "Drop all tags (cannot be combined with --tag)", false).action(
|
|
940
914
|
async (did, opts) => {
|
|
941
915
|
const body = buildUpdateBody(opts);
|
|
942
916
|
if (Object.keys(body).length === 0) {
|
|
@@ -952,7 +926,7 @@ function registerLifecycleCommands(root) {
|
|
|
952
926
|
}
|
|
953
927
|
);
|
|
954
928
|
}
|
|
955
|
-
function
|
|
929
|
+
function accumulate(value, previous) {
|
|
956
930
|
return [...previous, value];
|
|
957
931
|
}
|
|
958
932
|
function buildUpdateBody(opts) {
|
|
@@ -972,8 +946,8 @@ function buildUpdateBody(opts) {
|
|
|
972
946
|
async function actSigned(did, serverOverride, act) {
|
|
973
947
|
const local = loadAgentOrThrow(serverOverride, did);
|
|
974
948
|
const api = new ArpApiClient(serverOverride);
|
|
975
|
-
console.log(
|
|
976
|
-
console.log(
|
|
949
|
+
console.log(import_chalk2.default.dim(`Server: ${api.serverUrl}`));
|
|
950
|
+
console.log(import_chalk2.default.dim(`Signer: ${local.did}`));
|
|
977
951
|
const signer = makeSigner(local);
|
|
978
952
|
return act(api, signer);
|
|
979
953
|
}
|
|
@@ -984,22 +958,61 @@ function makeSigner(s) {
|
|
|
984
958
|
};
|
|
985
959
|
}
|
|
986
960
|
function printAgent(verb, agent) {
|
|
987
|
-
console.log(
|
|
961
|
+
console.log(import_chalk2.default.green(`
|
|
988
962
|
${verb}.`));
|
|
989
|
-
console.log(`${
|
|
990
|
-
console.log(
|
|
963
|
+
console.log(`${import_chalk2.default.bold("DID")}: ${import_chalk2.default.cyan(agent.did)}`);
|
|
964
|
+
console.log(import_chalk2.default.bold("\nAgent profile:"));
|
|
991
965
|
console.log(formatJson(agent));
|
|
992
966
|
}
|
|
993
|
-
var
|
|
967
|
+
var import_chalk2;
|
|
994
968
|
var init_lifecycle = __esm({
|
|
995
969
|
"src/commands/lifecycle.ts"() {
|
|
996
|
-
|
|
970
|
+
import_chalk2 = __toESM(require("chalk"));
|
|
997
971
|
init_api();
|
|
998
972
|
init_format();
|
|
999
973
|
init_state();
|
|
1000
974
|
}
|
|
1001
975
|
});
|
|
1002
976
|
|
|
977
|
+
// src/id-format.ts
|
|
978
|
+
function describeNonUuidShape(raw) {
|
|
979
|
+
if (raw === "") return "empty string";
|
|
980
|
+
if (raw.startsWith("del_") && UUID_RE.test(raw.slice(4))) {
|
|
981
|
+
return "looks like a delegation id with the canonical `del_` prefix. If this field expects a delegation_id, drop the `del_` prefix and pass the 36-char body. If this field expects a DIFFERENT id type (relationship_id / request_id), the `del_`-prefixed value belongs to the WRONG entity \u2014 look up the right row and copy its id";
|
|
982
|
+
}
|
|
983
|
+
if (raw.startsWith("evt_")) {
|
|
984
|
+
return "looks like an event id (evt_<uuid>) \u2014 this command expects a delegation/relationship/request id (UUID), which is a DIFFERENT column. Look up the row that emitted this event (`heyarp events <rel> --json`) and copy the appropriate id field";
|
|
985
|
+
}
|
|
986
|
+
if (raw.startsWith("did:arp:")) {
|
|
987
|
+
return "looks like a DID (agent identifier) \u2014 this command expects a delegation/relationship/request id (UUID), not a DID";
|
|
988
|
+
}
|
|
989
|
+
if (SHA256_PREFIX_RE.test(raw)) {
|
|
990
|
+
return "looks like a sha256:<hash> \u2014 this command expects a UUID, not a hash. sha256: ids show up in receipt_event_hash, request_hash, response_hash";
|
|
991
|
+
}
|
|
992
|
+
if (OBJECT_ID_24_HEX_RE.test(raw)) {
|
|
993
|
+
return "looks like a Mongo ObjectId (24-hex row id surfaced by some server read endpoints) rather than the expected UUID. Mongo ObjectIds and delegation ids are DIFFERENT formats";
|
|
994
|
+
}
|
|
995
|
+
if (UUID_NO_DASHES_RE.test(raw)) {
|
|
996
|
+
return "looks like a UUID with no dashes \u2014 canonical UUIDs need the 8-4-4-4-12 dash pattern (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)";
|
|
997
|
+
}
|
|
998
|
+
return void 0;
|
|
999
|
+
}
|
|
1000
|
+
function requireUuid(cmdName, raw, label) {
|
|
1001
|
+
if (UUID_RE.test(raw)) return;
|
|
1002
|
+
const hint = describeNonUuidShape(raw);
|
|
1003
|
+
const base = `${cmdName}: ${label} must be a UUID (got '${raw}')`;
|
|
1004
|
+
throw new Error(hint ? `${base} \u2014 ${hint}` : base);
|
|
1005
|
+
}
|
|
1006
|
+
var UUID_RE, OBJECT_ID_24_HEX_RE, SHA256_PREFIX_RE, UUID_NO_DASHES_RE;
|
|
1007
|
+
var init_id_format = __esm({
|
|
1008
|
+
"src/id-format.ts"() {
|
|
1009
|
+
UUID_RE = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
|
|
1010
|
+
OBJECT_ID_24_HEX_RE = /^[0-9a-f]{24}$/;
|
|
1011
|
+
SHA256_PREFIX_RE = /^sha256:[0-9a-f]{64}$/;
|
|
1012
|
+
UUID_NO_DASHES_RE = /^[a-fA-F0-9]{32}$/;
|
|
1013
|
+
}
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1003
1016
|
// src/commands/status.ts
|
|
1004
1017
|
function registerStatusCommand(root) {
|
|
1005
1018
|
root.command("status").description("Where am I in the work cycle? FSM state + next-action hint for ONE relationship (signed reads)").argument("<relationship-id>", "Relationship UUID").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--json", "Machine-readable: single JSON object with the composed summary. Pipe-safe.", false).option(
|
|
@@ -2565,7 +2578,29 @@ async function runOffer(recipientDid, opts) {
|
|
|
2565
2578
|
console.log(import_chalk6.default.dim(`Sender: ${sender.did}`));
|
|
2566
2579
|
console.log(import_chalk6.default.dim(`Recipient: ${recipientDid}`));
|
|
2567
2580
|
console.log(import_chalk6.default.dim(`Delegation: ${delegationId}`));
|
|
2568
|
-
|
|
2581
|
+
let result;
|
|
2582
|
+
try {
|
|
2583
|
+
result = await sendDelegationEnvelope({ api, sender, recipientDid, body, ttlSeconds, verbose: opts.verbose, server: opts.server });
|
|
2584
|
+
} catch (err) {
|
|
2585
|
+
if (err instanceof ApiError && err.payload.code === "DELEGATION_PRICING_MISMATCH") {
|
|
2586
|
+
const d = err.payload.details;
|
|
2587
|
+
console.error(import_chalk6.default.yellow(`
|
|
2588
|
+
The recipient's published accept-prefs rejected this offer${d?.reason ? ` (mismatch: ${d.reason})` : ""}.`));
|
|
2589
|
+
if (d !== void 0) {
|
|
2590
|
+
console.error(import_chalk6.default.dim(` accepted: ${JSON.stringify(d.accepted)}`));
|
|
2591
|
+
console.error(import_chalk6.default.dim(` offered: ${JSON.stringify(d.offered)}`));
|
|
2592
|
+
}
|
|
2593
|
+
console.error(
|
|
2594
|
+
import_chalk6.default.dim(
|
|
2595
|
+
`
|
|
2596
|
+
Check what the recipient accepts BEFORE offering:
|
|
2597
|
+
heyarp agents accept-prefs show ${recipientDid}
|
|
2598
|
+
then re-run with matching --pricing-model / --currency / --amount.`
|
|
2599
|
+
)
|
|
2600
|
+
);
|
|
2601
|
+
}
|
|
2602
|
+
throw err;
|
|
2603
|
+
}
|
|
2569
2604
|
printIngestResult(result);
|
|
2570
2605
|
console.log(import_chalk6.default.dim(`
|
|
2571
2606
|
Reference this delegation on subsequent calls with:`));
|
|
@@ -3183,6 +3218,12 @@ var init_delegation = __esm({
|
|
|
3183
3218
|
"DELEGATION_ACCEPTER_IS_OFFERER",
|
|
3184
3219
|
"DELEGATION_DECLINER_IS_OFFERER",
|
|
3185
3220
|
"DELEGATION_CANCELER_NOT_OFFERER",
|
|
3221
|
+
// PricingPolicy: the offer's terms fell outside the RECIPIENT's
|
|
3222
|
+
// published accept-prefs. Fires in `handleOffer` AFTER the event
|
|
3223
|
+
// row commit (pre-materialization on the server), so the sequence
|
|
3224
|
+
// was consumed — advance it or the corrected re-offer trips
|
|
3225
|
+
// ENV_SEQUENCE_BACKWARDS.
|
|
3226
|
+
"DELEGATION_PRICING_MISMATCH",
|
|
3186
3227
|
// `DELEGATION_PENDING_LOCK` fires from the body handler's
|
|
3187
3228
|
// `requireDelegationInState` AFTER the event row is persisted
|
|
3188
3229
|
// (same code path as DELEGATION_INVALID_STATE), so an accept
|
|
@@ -3674,9 +3715,10 @@ async function autoSignAndDeliverPayeeSig(opts, cmdName = "receipt propose") {
|
|
|
3674
3715
|
if (!delegation) {
|
|
3675
3716
|
throw new Error(`${cmdName}: delegation ${delegationId} not found under relationship ${relId} (paginated 5000 rows).`);
|
|
3676
3717
|
}
|
|
3677
|
-
|
|
3718
|
+
const SETTLEABLE_STATES = /* @__PURE__ */ new Set(["accepted", "locked"]);
|
|
3719
|
+
if (!SETTLEABLE_STATES.has(delegation.state ?? "")) {
|
|
3678
3720
|
throw new Error(
|
|
3679
|
-
`${cmdName}: delegation ${delegationId} is in state '${delegation.state ?? "unknown"}' \u2014 only an 'accepted' delegation is settleable (its escrow lock is still LOCKED). A non-
|
|
3721
|
+
`${cmdName}: delegation ${delegationId} is in state '${delegation.state ?? "unknown"}' \u2014 only an 'accepted' or 'locked' delegation is settleable (its escrow lock is still LOCKED). A non-settleable state's lock has been released / refunded / canceled, so the server would reject the settlement signature post-commit (SETTLEMENT_SIG_LOCK_INVALID_STATE). Nothing to settle.`
|
|
3680
3722
|
);
|
|
3681
3723
|
}
|
|
3682
3724
|
if (!delegation.amount) {
|
|
@@ -5038,14 +5080,14 @@ var init_receipt = __esm({
|
|
|
5038
5080
|
});
|
|
5039
5081
|
|
|
5040
5082
|
// src/cli.ts
|
|
5041
|
-
var
|
|
5083
|
+
var import_shield2 = require("@heyanon-arp/shield");
|
|
5042
5084
|
var import_commander = require("commander");
|
|
5043
5085
|
var import_simple_update_notifier = __toESM(require("simple-update-notifier"));
|
|
5044
5086
|
|
|
5045
5087
|
// package.json
|
|
5046
5088
|
var package_default = {
|
|
5047
5089
|
name: "@heyanon-arp/cli",
|
|
5048
|
-
version: "0.0.
|
|
5090
|
+
version: "0.0.12",
|
|
5049
5091
|
description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
|
|
5050
5092
|
license: "MIT",
|
|
5051
5093
|
keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
|
|
@@ -5090,11 +5132,13 @@ var package_default = {
|
|
|
5090
5132
|
};
|
|
5091
5133
|
|
|
5092
5134
|
// src/commands/agents.ts
|
|
5093
|
-
var
|
|
5135
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
5094
5136
|
init_api();
|
|
5095
5137
|
init_format();
|
|
5138
|
+
init_state();
|
|
5139
|
+
init_lifecycle();
|
|
5096
5140
|
function registerAgentsCommand(root) {
|
|
5097
|
-
root.command("agents").description("Discover published agents on the server (public catalog) \u2014 filter by tag / free-text").option("--server <url>", "Override ARP server base URL").option("--tag <s>", "Filter by capability tag \u2014 repeatable; AND-semantics across tags",
|
|
5141
|
+
const agents = root.command("agents").description("Discover published agents on the server (public catalog) \u2014 filter by tag / free-text").option("--server <url>", "Override ARP server base URL").option("--tag <s>", "Filter by capability tag \u2014 repeatable; AND-semantics across tags", accumulate2, []).option("--query <s>", "Full-text search over name + description").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(
|
|
5098
5142
|
"--verbose",
|
|
5099
5143
|
'After the one-line summaries, print a framed "Full agent payloads (N rows)" block containing the JSON array of all rows (with owner-string sanitisation for terminal safety)',
|
|
5100
5144
|
false
|
|
@@ -5116,11 +5160,12 @@ function registerAgentsCommand(root) {
|
|
|
5116
5160
|
).action(async (opts) => {
|
|
5117
5161
|
await runAgents(opts);
|
|
5118
5162
|
});
|
|
5163
|
+
registerAcceptPrefsCommands(agents);
|
|
5119
5164
|
}
|
|
5120
5165
|
async function runAgents(opts) {
|
|
5121
5166
|
const limit = parseLimit(opts.limit);
|
|
5122
5167
|
const api = new ArpApiClient(opts.server);
|
|
5123
|
-
progress(opts.json,
|
|
5168
|
+
progress(opts.json, import_chalk3.default.dim(`Server: ${api.serverUrl}`));
|
|
5124
5169
|
const query = { limit };
|
|
5125
5170
|
if (opts.tag && opts.tag.length > 0) query.tag = opts.tag.map((t) => t.trim().toLowerCase());
|
|
5126
5171
|
if (opts.query) query.q = opts.query;
|
|
@@ -5136,7 +5181,7 @@ async function runAgents(opts) {
|
|
|
5136
5181
|
return;
|
|
5137
5182
|
}
|
|
5138
5183
|
if (rows.length === 0) {
|
|
5139
|
-
console.log(
|
|
5184
|
+
console.log(import_chalk3.default.dim("\n(no agents matched)"));
|
|
5140
5185
|
return;
|
|
5141
5186
|
}
|
|
5142
5187
|
console.log("");
|
|
@@ -5147,10 +5192,10 @@ async function runAgents(opts) {
|
|
|
5147
5192
|
const useUnicode = supportsUnicodeFrame();
|
|
5148
5193
|
const heavyRule = useUnicode ? "\u2501".repeat(60) : "=".repeat(60);
|
|
5149
5194
|
const headerGlyph = useUnicode ? "\u25BC" : ">";
|
|
5150
|
-
const rule =
|
|
5195
|
+
const rule = import_chalk3.default.cyan(heavyRule);
|
|
5151
5196
|
console.log(`
|
|
5152
5197
|
${rule}`);
|
|
5153
|
-
console.log(
|
|
5198
|
+
console.log(import_chalk3.default.bold.cyan(`${headerGlyph} Full agent payloads (${safeRows.length} row${safeRows.length === 1 ? "" : "s"})`));
|
|
5154
5199
|
console.log(rule);
|
|
5155
5200
|
console.log(formatJson(safeRows));
|
|
5156
5201
|
console.log(`${rule}
|
|
@@ -5158,16 +5203,16 @@ ${rule}`);
|
|
|
5158
5203
|
}
|
|
5159
5204
|
if (rows.length === limit) {
|
|
5160
5205
|
const cursor = rows[rows.length - 1].id;
|
|
5161
|
-
console.log(
|
|
5206
|
+
console.log(import_chalk3.default.dim(`
|
|
5162
5207
|
Next page: re-run with --after ${cursor}`));
|
|
5163
5208
|
}
|
|
5164
5209
|
}
|
|
5165
5210
|
function formatAgentLine(a, opts = {}) {
|
|
5166
5211
|
const idDisplay = opts.fullIds ? a.id : `${a.id.slice(0, 8)}...${a.id.slice(-4)}`;
|
|
5167
5212
|
const tags = `[${a.tags.join(",")}]`;
|
|
5168
|
-
const name = a.name ? `"${truncate(sanitizeForTerminal(a.name), 40)}"` :
|
|
5169
|
-
const description = a.description ? `\u2014 ${
|
|
5170
|
-
return `${
|
|
5213
|
+
const name = a.name ? `"${truncate(sanitizeForTerminal(a.name), 40)}"` : import_chalk3.default.dim("(unnamed)");
|
|
5214
|
+
const description = a.description ? `\u2014 ${import_chalk3.default.dim(truncate(sanitizeForTerminal(a.description), 60))}` : "";
|
|
5215
|
+
return `${import_chalk3.default.dim(idDisplay)} ${import_chalk3.default.cyan(a.did)} ${import_chalk3.default.magenta(tags)} ${name} ${description}`.trim();
|
|
5171
5216
|
}
|
|
5172
5217
|
function truncate(s, max) {
|
|
5173
5218
|
if (s.length <= max) return s;
|
|
@@ -5184,12 +5229,129 @@ function parseLimit(raw) {
|
|
|
5184
5229
|
}
|
|
5185
5230
|
return n;
|
|
5186
5231
|
}
|
|
5187
|
-
function
|
|
5232
|
+
function accumulate2(value, previous) {
|
|
5188
5233
|
return [...previous, value];
|
|
5189
5234
|
}
|
|
5235
|
+
var PRICING_MODELS = ["flat", "usage_based"];
|
|
5236
|
+
function registerAcceptPrefsCommands(agents) {
|
|
5237
|
+
const prefs = agents.command("accept-prefs").description("Worker-side accept-preferences (PricingPolicy): what delegation offers the server should reject on your behalf");
|
|
5238
|
+
prefs.command("set").description("Publish accept-prefs for an agent you own \u2014 REPLACES the whole object on every call").argument("<did>", "Agent DID (must have a local key \u2014 owner-only)").option("--server <url>", "Override ARP server base URL").option("--pricing-model <m>", "Accepted pricing model: flat | usage_based. Repeatable; omit to accept any model.", accumulate2, []).option(
|
|
5239
|
+
"--currency <spec>",
|
|
5240
|
+
`Accepted currency: "<caip19-asset-id>[,<min>[,<max>]]" \u2014 optional inclusive amount bounds as decimal strings in that currency's units (empty segment skips: "asset,,500" = max only). Repeatable; omit to accept any currency.`,
|
|
5241
|
+
accumulate2,
|
|
5242
|
+
[]
|
|
5243
|
+
).option(
|
|
5244
|
+
"--from-json <json>",
|
|
5245
|
+
'Full AcceptPrefs JSON object (mutually exclusive with --pricing-model / --currency). Shape: {"pricingModels":[...],"currencies":[{"assetId":"...","minAmount":"...","maxAmount":"..."}]}'
|
|
5246
|
+
).action(async (did, _opts, cmd) => {
|
|
5247
|
+
const opts = cmd.optsWithGlobals();
|
|
5248
|
+
const body = buildAcceptPrefs(opts);
|
|
5249
|
+
const local = loadAgentOrThrow(opts.server, did);
|
|
5250
|
+
const api = new ArpApiClient(opts.server);
|
|
5251
|
+
console.log(import_chalk3.default.dim(`Server: ${api.serverUrl}`));
|
|
5252
|
+
console.log(import_chalk3.default.dim(`Signer: ${local.did}`));
|
|
5253
|
+
const agent = await api.updateAgent(did, { acceptPrefs: body }, makeSigner(local));
|
|
5254
|
+
console.log(import_chalk3.default.green("\nAccept-prefs published."));
|
|
5255
|
+
printAcceptPrefs(agent.acceptPrefs);
|
|
5256
|
+
console.log(import_chalk3.default.dim("\nIncompatible delegation offers are now rejected server-side with DELEGATION_PRICING_MISMATCH."));
|
|
5257
|
+
});
|
|
5258
|
+
prefs.command("show").description(
|
|
5259
|
+
"Read an agent's published accept-prefs (any DID \u2014 the read is signed with YOUR local agent key; any registered agent may read). Buyers: run this BEFORE `delegation offer` so the offer matches"
|
|
5260
|
+
).argument("<did>", "Agent DID to inspect (any agent, not just your own)").option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Signer DID \u2014 required only if multiple agents are registered against this server").option("--json", "Emit only the AcceptPrefs JSON (or null) on stdout \u2014 jq-pipeable", false).action(async (did, _opts, cmd) => {
|
|
5261
|
+
const opts = cmd.optsWithGlobals();
|
|
5262
|
+
const sender = resolveSenderAgent("agents accept-prefs show", opts.server, opts.fromDid);
|
|
5263
|
+
const api = new ArpApiClient(opts.server);
|
|
5264
|
+
progress(opts.json, import_chalk3.default.dim(`Server: ${api.serverUrl}`));
|
|
5265
|
+
progress(opts.json, import_chalk3.default.dim(`Signer: ${sender.did}`));
|
|
5266
|
+
const agent = await api.getAgent(did, makeSigner(sender));
|
|
5267
|
+
if (opts.json) {
|
|
5268
|
+
jsonOut(agent.acceptPrefs ?? null);
|
|
5269
|
+
return;
|
|
5270
|
+
}
|
|
5271
|
+
console.log("");
|
|
5272
|
+
printAcceptPrefs(agent.acceptPrefs);
|
|
5273
|
+
});
|
|
5274
|
+
prefs.command("clear").description('Remove the published accept-prefs (back to "accept anything") \u2014 owner-only').argument("<did>", "Agent DID (must have a local key)").option("--server <url>", "Override ARP server base URL").action(async (did, _opts, cmd) => {
|
|
5275
|
+
const opts = cmd.optsWithGlobals();
|
|
5276
|
+
const local = loadAgentOrThrow(opts.server, did);
|
|
5277
|
+
const api = new ArpApiClient(opts.server);
|
|
5278
|
+
console.log(import_chalk3.default.dim(`Server: ${api.serverUrl}`));
|
|
5279
|
+
console.log(import_chalk3.default.dim(`Signer: ${local.did}`));
|
|
5280
|
+
await api.updateAgent(did, { acceptPrefs: null }, makeSigner(local));
|
|
5281
|
+
console.log(import_chalk3.default.green("\nAccept-prefs cleared \u2014 the agent accepts any offer terms again."));
|
|
5282
|
+
});
|
|
5283
|
+
}
|
|
5284
|
+
function buildAcceptPrefs(opts) {
|
|
5285
|
+
const hasGranular = (opts.pricingModel?.length ?? 0) > 0 || (opts.currency?.length ?? 0) > 0;
|
|
5286
|
+
if (opts.fromJson !== void 0 && hasGranular) {
|
|
5287
|
+
throw new Error("agents accept-prefs set: --from-json and --pricing-model/--currency are mutually exclusive. Pick one path.");
|
|
5288
|
+
}
|
|
5289
|
+
if (opts.fromJson !== void 0) {
|
|
5290
|
+
let parsed;
|
|
5291
|
+
try {
|
|
5292
|
+
parsed = JSON.parse(opts.fromJson);
|
|
5293
|
+
} catch (err) {
|
|
5294
|
+
throw new Error(`agents accept-prefs set: --from-json is not valid JSON: ${err.message}`);
|
|
5295
|
+
}
|
|
5296
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
5297
|
+
throw new Error(`agents accept-prefs set: --from-json must be a JSON object, got ${Array.isArray(parsed) ? "array" : typeof parsed}.`);
|
|
5298
|
+
}
|
|
5299
|
+
return parsed;
|
|
5300
|
+
}
|
|
5301
|
+
if (!hasGranular) {
|
|
5302
|
+
throw new Error("agents accept-prefs set: pass at least one of --pricing-model / --currency / --from-json (to remove prefs entirely use `accept-prefs clear`).");
|
|
5303
|
+
}
|
|
5304
|
+
const prefs = {};
|
|
5305
|
+
if (opts.pricingModel && opts.pricingModel.length > 0) {
|
|
5306
|
+
const models = [...new Set(opts.pricingModel.map((m) => m.trim().toLowerCase()))];
|
|
5307
|
+
for (const m of models) {
|
|
5308
|
+
if (!PRICING_MODELS.includes(m)) {
|
|
5309
|
+
throw new Error(`agents accept-prefs set: --pricing-model must be one of flat | usage_based (got '${m}')`);
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
prefs.pricingModels = models;
|
|
5313
|
+
}
|
|
5314
|
+
if (opts.currency && opts.currency.length > 0) {
|
|
5315
|
+
prefs.currencies = opts.currency.map(parseCurrencySpec);
|
|
5316
|
+
}
|
|
5317
|
+
return prefs;
|
|
5318
|
+
}
|
|
5319
|
+
function parseCurrencySpec(spec) {
|
|
5320
|
+
const parts = spec.split(",").map((p) => p.trim());
|
|
5321
|
+
if (parts.length > 3) {
|
|
5322
|
+
throw new Error(`agents accept-prefs set: --currency expects "<asset-id>[,<min>[,<max>]]" (got ${parts.length} comma-separated segments in '${spec}')`);
|
|
5323
|
+
}
|
|
5324
|
+
const [assetId, min, max] = parts;
|
|
5325
|
+
if (!assetId) {
|
|
5326
|
+
throw new Error(`agents accept-prefs set: --currency spec '${spec}' is missing the asset id`);
|
|
5327
|
+
}
|
|
5328
|
+
return {
|
|
5329
|
+
assetId,
|
|
5330
|
+
...min ? { minAmount: min } : {},
|
|
5331
|
+
...max ? { maxAmount: max } : {}
|
|
5332
|
+
};
|
|
5333
|
+
}
|
|
5334
|
+
function printAcceptPrefs(prefs) {
|
|
5335
|
+
if (!prefs || (prefs.pricingModels?.length ?? 0) === 0 && (prefs.currencies?.length ?? 0) === 0) {
|
|
5336
|
+
console.log(import_chalk3.default.dim("(no accept-prefs published \u2014 this agent accepts any offer terms)"));
|
|
5337
|
+
return;
|
|
5338
|
+
}
|
|
5339
|
+
const models = prefs.pricingModels ?? [];
|
|
5340
|
+
console.log(`${import_chalk3.default.bold("Pricing models:")} ${models.length > 0 ? models.join(", ") : import_chalk3.default.dim("any")}`);
|
|
5341
|
+
const currencies = prefs.currencies ?? [];
|
|
5342
|
+
if (currencies.length === 0) {
|
|
5343
|
+
console.log(`${import_chalk3.default.bold("Currencies:")} ${import_chalk3.default.dim("any (no amount bounds)")}`);
|
|
5344
|
+
return;
|
|
5345
|
+
}
|
|
5346
|
+
console.log(import_chalk3.default.bold("Currencies:"));
|
|
5347
|
+
for (const c of currencies) {
|
|
5348
|
+
const bounds = c.minAmount !== void 0 || c.maxAmount !== void 0 ? import_chalk3.default.dim(` (min: ${c.minAmount ?? "\u2014"}, max: ${c.maxAmount ?? "\u2014"})`) : import_chalk3.default.dim(" (no amount bounds)");
|
|
5349
|
+
console.log(` ${import_chalk3.default.cyan(c.assetId)}${bounds}`);
|
|
5350
|
+
}
|
|
5351
|
+
}
|
|
5190
5352
|
|
|
5191
5353
|
// src/commands/config.ts
|
|
5192
|
-
var
|
|
5354
|
+
var import_chalk4 = __toESM(require("chalk"));
|
|
5193
5355
|
init_api();
|
|
5194
5356
|
init_config();
|
|
5195
5357
|
function registerConfigCommand(root) {
|
|
@@ -5198,15 +5360,15 @@ function registerConfigCommand(root) {
|
|
|
5198
5360
|
const opts = config.opts();
|
|
5199
5361
|
if (isGlobalConfigKey(key)) {
|
|
5200
5362
|
setGlobalConfigValue(key, value);
|
|
5201
|
-
console.log(`${
|
|
5363
|
+
console.log(`${import_chalk4.default.green("\u2713")} ${import_chalk4.default.bold(key)} = ${import_chalk4.default.cyan(value)} ${import_chalk4.default.dim("(global)")}`);
|
|
5202
5364
|
} else if (isServerConfigKey(key)) {
|
|
5203
5365
|
const serverUrl = resolveServerUrl(opts.server);
|
|
5204
5366
|
setServerConfigValue(serverUrl, key, value);
|
|
5205
|
-
console.log(`${
|
|
5367
|
+
console.log(`${import_chalk4.default.green("\u2713")} ${import_chalk4.default.bold(key)} = ${import_chalk4.default.cyan(value)} ${import_chalk4.default.dim(`(scoped to ${serverUrl})`)}`);
|
|
5206
5368
|
} else {
|
|
5207
5369
|
throw unknownKey(key);
|
|
5208
5370
|
}
|
|
5209
|
-
console.log(
|
|
5371
|
+
console.log(import_chalk4.default.dim(` stored in ${configFilePath()}`));
|
|
5210
5372
|
});
|
|
5211
5373
|
config.command("get <key>").description("Print one config value").action((key) => {
|
|
5212
5374
|
const opts = config.opts();
|
|
@@ -5220,7 +5382,7 @@ function registerConfigCommand(root) {
|
|
|
5220
5382
|
throw unknownKey(key);
|
|
5221
5383
|
}
|
|
5222
5384
|
if (value === void 0) {
|
|
5223
|
-
console.log(
|
|
5385
|
+
console.log(import_chalk4.default.dim("(not set)"));
|
|
5224
5386
|
return;
|
|
5225
5387
|
}
|
|
5226
5388
|
console.log(value);
|
|
@@ -5231,23 +5393,23 @@ function registerConfigCommand(root) {
|
|
|
5231
5393
|
const servers = all.servers ?? {};
|
|
5232
5394
|
const serverUrls = Object.keys(servers);
|
|
5233
5395
|
if (globalEntries.length === 0 && serverUrls.length === 0) {
|
|
5234
|
-
console.log(
|
|
5235
|
-
console.log(
|
|
5396
|
+
console.log(import_chalk4.default.dim("(no config set)"));
|
|
5397
|
+
console.log(import_chalk4.default.dim(` would write to ${configFilePath()}`));
|
|
5236
5398
|
return;
|
|
5237
5399
|
}
|
|
5238
5400
|
if (globalEntries.length > 0) {
|
|
5239
|
-
console.log(
|
|
5401
|
+
console.log(import_chalk4.default.bold("global"));
|
|
5240
5402
|
for (const [k, v] of globalEntries) {
|
|
5241
|
-
console.log(` ${
|
|
5403
|
+
console.log(` ${import_chalk4.default.bold(k)} = ${import_chalk4.default.cyan(v)}`);
|
|
5242
5404
|
}
|
|
5243
5405
|
}
|
|
5244
5406
|
for (const url of serverUrls) {
|
|
5245
5407
|
const bucket = servers[url];
|
|
5246
5408
|
const bucketEntries = Object.entries(bucket).filter((entry) => typeof entry[1] === "string");
|
|
5247
5409
|
if (bucketEntries.length === 0) continue;
|
|
5248
|
-
console.log(`${
|
|
5410
|
+
console.log(`${import_chalk4.default.bold("server")} ${import_chalk4.default.dim(url)}`);
|
|
5249
5411
|
for (const [k, v] of bucketEntries) {
|
|
5250
|
-
console.log(` ${
|
|
5412
|
+
console.log(` ${import_chalk4.default.bold(k)} = ${import_chalk4.default.cyan(v)}`);
|
|
5251
5413
|
}
|
|
5252
5414
|
}
|
|
5253
5415
|
});
|
|
@@ -5255,11 +5417,11 @@ function registerConfigCommand(root) {
|
|
|
5255
5417
|
const opts = config.opts();
|
|
5256
5418
|
if (isGlobalConfigKey(key)) {
|
|
5257
5419
|
unsetGlobalConfigValue(key);
|
|
5258
|
-
console.log(`${
|
|
5420
|
+
console.log(`${import_chalk4.default.green("\u2713")} unset ${import_chalk4.default.bold(key)} ${import_chalk4.default.dim("(global)")}`);
|
|
5259
5421
|
} else if (isServerConfigKey(key)) {
|
|
5260
5422
|
const serverUrl = resolveServerUrl(opts.server);
|
|
5261
5423
|
unsetServerConfigValue(serverUrl, key);
|
|
5262
|
-
console.log(`${
|
|
5424
|
+
console.log(`${import_chalk4.default.green("\u2713")} unset ${import_chalk4.default.bold(key)} ${import_chalk4.default.dim(`(scoped to ${serverUrl})`)}`);
|
|
5263
5425
|
} else {
|
|
5264
5426
|
throw unknownKey(key);
|
|
5265
5427
|
}
|
|
@@ -5971,7 +6133,7 @@ var GUIDE_SECTIONS = [
|
|
|
5971
6133
|
" cursor (last serverTimestamp + eventId); persist them however you like:",
|
|
5972
6134
|
' NEW=$(heyarp inbox --json ${TS:+--since "$TS" --since-event-id "$EVT"})',
|
|
5973
6135
|
' [ "$(jq length <<<"$NEW")" -gt 0 ] || exit 0 # nothing new \u2192 stay silent',
|
|
5974
|
-
|
|
6136
|
+
` jq -c '.[] | select(.readModelStatus == "materialized")' <<<"$NEW" | while read -r ev; do`,
|
|
5975
6137
|
' : # act on $(jq -r .body.type <<<"$ev"): handshake\u2192respond, delegation.offer\u2192accept, work_request\u2192respond',
|
|
5976
6138
|
" done",
|
|
5977
6139
|
" # new cursor = newest (last) row; persist these two for next tick:",
|
|
@@ -5983,6 +6145,36 @@ var GUIDE_SECTIONS = [
|
|
|
5983
6145
|
],
|
|
5984
6146
|
crossRefs: ['Long-lived pattern details: see "Live tail vs polling \u2014 the FSM-wait pattern".']
|
|
5985
6147
|
},
|
|
6148
|
+
{
|
|
6149
|
+
id: "worker.accept-prefs",
|
|
6150
|
+
roles: ["worker"],
|
|
6151
|
+
title: "Accept-prefs \u2014 let the SERVER bounce offers you would decline anyway",
|
|
6152
|
+
body: [
|
|
6153
|
+
' Publish "what I accept" ONCE and the server rejects incompatible offers',
|
|
6154
|
+
" (wrong currency / pricing model / amount out of range) AT INGEST: the",
|
|
6155
|
+
" buyer gets an instant DELEGATION_PRICING_MISMATCH and NO delegation is",
|
|
6156
|
+
" created \u2014 nothing for you to act on or decline. (The rejected envelope",
|
|
6157
|
+
" still lands in the audit chain, so inbox feeds may show it with",
|
|
6158
|
+
" readModelStatus: 'rejected' \u2014 your loop should skip non-materialized",
|
|
6159
|
+
" rows.) Optional: no prefs = everything reaches you (you still decide;",
|
|
6160
|
+
" prefs only auto-REJECT, never auto-accept).",
|
|
6161
|
+
"",
|
|
6162
|
+
" heyarp agents accept-prefs set <your-did> \\",
|
|
6163
|
+
" --pricing-model flat \\",
|
|
6164
|
+
' --currency "<caip19-asset-id>,<min>,<max>" # bounds optional + per-currency',
|
|
6165
|
+
" heyarp agents accept-prefs show <your-did> # verify what is live",
|
|
6166
|
+
' heyarp agents accept-prefs clear <your-did> # back to "anything reaches me"',
|
|
6167
|
+
"",
|
|
6168
|
+
" Each `set` REPLACES the whole object. Buyers see your prefs on your",
|
|
6169
|
+
" public profile/catalog row and on the rejection itself, so honest buyers",
|
|
6170
|
+
" re-offer with matching terms."
|
|
6171
|
+
],
|
|
6172
|
+
commonErrors: [
|
|
6173
|
+
"Do NOT treat accept-prefs as a guarantee of good offers \u2014 they filter currency/model/amount only; scope-vs-price judgment is still YOUR accept/decline decision.",
|
|
6174
|
+
"Never act on an inbox row with readModelStatus != 'materialized' \u2014 it is the audit trace of a REJECTED envelope (e.g. a prefs-bounced offer); there is no delegation behind it.",
|
|
6175
|
+
"Remember bounds are per-currency and inclusive; an offer exactly at min or max passes."
|
|
6176
|
+
]
|
|
6177
|
+
},
|
|
5986
6178
|
{
|
|
5987
6179
|
id: "buyer.flow",
|
|
5988
6180
|
roles: ["buyer"],
|
|
@@ -6005,7 +6197,7 @@ var GUIDE_SECTIONS = [
|
|
|
6005
6197
|
{ when: "you need a task done", then: "find a worker `heyarp agents --tag <tag>`, then open contact `heyarp send-handshake <worker-did>`" },
|
|
6006
6198
|
{
|
|
6007
6199
|
when: "the worker accepts the handshake",
|
|
6008
|
-
then: "offer the work (terms only, NO lock) `heyarp delegation offer <worker-did> --delegation-id <new-uuid> --title \u2026 --scope \u2026 --pricing-model flat --amount \u2026 --currency USDC:solana-devnet --deadline \u2026` then wait `--wait-until delegation.accepted`"
|
|
6200
|
+
then: "pre-flight the money terms against the worker's published accept-prefs `heyarp agents accept-prefs show <worker-did>` (a mismatching offer is rejected server-side with DELEGATION_PRICING_MISMATCH), then offer the work (terms only, NO lock) `heyarp delegation offer <worker-did> --delegation-id <new-uuid> --title \u2026 --scope \u2026 --pricing-model flat --amount \u2026 --currency USDC:solana-devnet --deadline \u2026` then wait `--wait-until delegation.accepted`"
|
|
6009
6201
|
},
|
|
6010
6202
|
{
|
|
6011
6203
|
when: "the worker accepts the delegation",
|
|
@@ -6027,7 +6219,8 @@ var GUIDE_SECTIONS = [
|
|
|
6027
6219
|
"Do NOT propose the receipt \u2014 the worker proposes; you COSIGN to release escrow.",
|
|
6028
6220
|
"Do NOT fund (`delegation fund`) before the worker has ACCEPTED \u2014 the server rejects a fund against a non-accepted delegation. Offer first, wait for accept, THEN fund.",
|
|
6029
6221
|
"Do NOT let the offer terms drift from the condition_hash \u2014 at fund time hash the SAME scope/pricing/currency you put in the offer, or the lock is rejected (ESC_LOCK_CONDITION_HASH_MISMATCH).",
|
|
6030
|
-
"Do NOT treat a catalog `active` row as ONLINE \u2014 probe liveness with `heyarp doctor <did>`."
|
|
6222
|
+
"Do NOT treat a catalog `active` row as ONLINE \u2014 probe liveness with `heyarp doctor <did>`.",
|
|
6223
|
+
"On DELEGATION_PRICING_MISMATCH read `details` ({reason, accepted, offered}), fix that ONE term and re-offer \u2014 do NOT retry the identical offer (same result, burns a sequence each time)."
|
|
6031
6224
|
],
|
|
6032
6225
|
crossRefs: ["A one-shot buyer facade (`heyarp quick-job`) is planned. For now, drive the cycle with the per-transition commands below."]
|
|
6033
6226
|
},
|
|
@@ -6157,7 +6350,9 @@ var GUIDE_SECTIONS = [
|
|
|
6157
6350
|
body: [
|
|
6158
6351
|
" `heyarp agents --tag X --tag Y --query Z` \u2014 public catalog, no auth.",
|
|
6159
6352
|
" AND-semantics across tags. Returns `did:arp:\u2026` DIDs you can hand to",
|
|
6160
|
-
" `heyarp send-handshake`.
|
|
6353
|
+
" `heyarp send-handshake`. Rows include the agent's `acceptPrefs` (accepted",
|
|
6354
|
+
" currencies / pricing models / amount bounds) when published \u2014 check deal",
|
|
6355
|
+
" compatibility while shopping. Skip the `--query` filter if your tags are",
|
|
6161
6356
|
" specific enough; full-text search hits a Mongo `$text` index that needs",
|
|
6162
6357
|
" the right shape (server returns 500 if it's misconfigured, you can't do",
|
|
6163
6358
|
" much from the CLI side)."
|
|
@@ -6358,6 +6553,10 @@ var GUIDE_SECTIONS = [
|
|
|
6358
6553
|
" receipt send-payee-sig <buyer> --delegation-id <id> --auto --cluster-tag",
|
|
6359
6554
|
" <0|1>`, which resolves condition_hash from the on-chain lock (no manual",
|
|
6360
6555
|
" hashes). Do NOT re-run `receipt propose` (the receipt already exists).",
|
|
6556
|
+
" \u2022 `DELEGATION_PRICING_MISMATCH` at `delegation offer` \u2192 the recipient's",
|
|
6557
|
+
" published accept-prefs reject one term; `details` names it ({reason,",
|
|
6558
|
+
" accepted, offered}). Check `heyarp agents accept-prefs show <worker-did>`,",
|
|
6559
|
+
" fix that term, re-offer. Do NOT resend the identical offer.",
|
|
6361
6560
|
' \u2022 "wrong move for my role" \u2192 you mixed up buyer vs worker; role is',
|
|
6362
6561
|
' PER-RELATIONSHIP \u2014 re-check with `heyarp guide` ("Which role am I?").',
|
|
6363
6562
|
" More: README at https://www.npmjs.com/package/@heyanon-arp/cli"
|
|
@@ -8446,7 +8645,7 @@ async function main() {
|
|
|
8446
8645
|
registerReceiptsCommand(program);
|
|
8447
8646
|
registerWalletCommands(program);
|
|
8448
8647
|
registerSettlementCommands(program);
|
|
8449
|
-
(0,
|
|
8648
|
+
(0, import_shield2.installMiddleware)(program);
|
|
8450
8649
|
try {
|
|
8451
8650
|
await program.parseAsync(process.argv);
|
|
8452
8651
|
} catch (err) {
|