clawdentity 0.0.12 → 0.0.14
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/bin.js +696 -25
- package/dist/index.js +696 -25
- package/dist/postinstall.js +0 -357
- package/package.json +1 -1
- package/postinstall.mjs +1 -34
- package/skill-bundle/AGENTS.md +1 -1
- package/skill-bundle/openclaw-skill/skill/SKILL.md +5 -4
- package/skill-bundle/openclaw-skill/skill/references/clawdentity-protocol.md +1 -1
package/dist/index.js
CHANGED
|
@@ -6,8 +6,8 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
-
import { createRequire } from "module";
|
|
10
|
-
import { Command as
|
|
9
|
+
import { createRequire as createRequire2 } from "module";
|
|
10
|
+
import { Command as Command11 } from "commander";
|
|
11
11
|
|
|
12
12
|
// ../../packages/protocol/src/agent-registration-proof.ts
|
|
13
13
|
var AGENT_REGISTRATION_PROOF_VERSION = "clawdentity.register.v1";
|
|
@@ -21167,13 +21167,7 @@ function resolveOpenclawConfigPath(openclawDir, homeDir) {
|
|
|
21167
21167
|
return configCandidates[0];
|
|
21168
21168
|
}
|
|
21169
21169
|
function resolveDefaultTransformSource(openclawDir) {
|
|
21170
|
-
return join6(
|
|
21171
|
-
openclawDir,
|
|
21172
|
-
"workspace",
|
|
21173
|
-
"skills",
|
|
21174
|
-
SKILL_DIR_NAME,
|
|
21175
|
-
RELAY_MODULE_FILE_NAME
|
|
21176
|
-
);
|
|
21170
|
+
return join6(openclawDir, "skills", SKILL_DIR_NAME, RELAY_MODULE_FILE_NAME);
|
|
21177
21171
|
}
|
|
21178
21172
|
function resolveTransformTargetPath(openclawDir) {
|
|
21179
21173
|
return join6(openclawDir, "hooks", "transforms", RELAY_MODULE_FILE_NAME);
|
|
@@ -21907,7 +21901,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21907
21901
|
label: "Relay transform",
|
|
21908
21902
|
status: "fail",
|
|
21909
21903
|
message: "relay transform artifacts are missing or empty",
|
|
21910
|
-
remediationHint: "Run:
|
|
21904
|
+
remediationHint: "Run: clawdentity skill install",
|
|
21911
21905
|
details: {
|
|
21912
21906
|
transformTargetPath,
|
|
21913
21907
|
relayTransformRuntimePath,
|
|
@@ -21937,7 +21931,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21937
21931
|
label: "Relay transform",
|
|
21938
21932
|
status: "fail",
|
|
21939
21933
|
message: "missing relay transform artifacts",
|
|
21940
|
-
remediationHint: "Run:
|
|
21934
|
+
remediationHint: "Run: clawdentity skill install",
|
|
21941
21935
|
details: {
|
|
21942
21936
|
transformTargetPath,
|
|
21943
21937
|
relayTransformRuntimePath,
|
|
@@ -22361,7 +22355,7 @@ var createOpenclawCommand = () => {
|
|
|
22361
22355
|
"OpenClaw state directory (default ~/.openclaw)"
|
|
22362
22356
|
).option(
|
|
22363
22357
|
"--transform-source <path>",
|
|
22364
|
-
"Path to relay-to-peer.mjs (default <openclaw-dir>/
|
|
22358
|
+
"Path to relay-to-peer.mjs (default <openclaw-dir>/skills/clawdentity-openclaw-relay/relay-to-peer.mjs)"
|
|
22365
22359
|
).option(
|
|
22366
22360
|
"--openclaw-base-url <url>",
|
|
22367
22361
|
"Base URL for local OpenClaw hook API (default http://127.0.0.1:18789)"
|
|
@@ -22477,6 +22471,7 @@ var PAIRING_QR_DIR_NAME = "pairing";
|
|
|
22477
22471
|
var PEERS_FILE_NAME2 = "peers.json";
|
|
22478
22472
|
var PAIR_START_PATH = "/pair/start";
|
|
22479
22473
|
var PAIR_CONFIRM_PATH = "/pair/confirm";
|
|
22474
|
+
var PAIR_STATUS_PATH = "/pair/status";
|
|
22480
22475
|
var OWNER_PAT_HEADER = "x-claw-owner-pat";
|
|
22481
22476
|
var NONCE_SIZE2 = 24;
|
|
22482
22477
|
var PAIRING_TICKET_PREFIX = "clwpair1_";
|
|
@@ -22484,6 +22479,8 @@ var PAIRING_QR_MAX_AGE_SECONDS = 900;
|
|
|
22484
22479
|
var PAIRING_QR_FILENAME_PATTERN = /-pair-(\d+)\.png$/;
|
|
22485
22480
|
var FILE_MODE4 = 384;
|
|
22486
22481
|
var PEER_ALIAS_PATTERN2 = /^[a-zA-Z0-9._-]+$/;
|
|
22482
|
+
var DEFAULT_STATUS_WAIT_SECONDS = 300;
|
|
22483
|
+
var DEFAULT_STATUS_POLL_INTERVAL_SECONDS = 3;
|
|
22487
22484
|
var isRecord9 = (value) => {
|
|
22488
22485
|
return typeof value === "object" && value !== null;
|
|
22489
22486
|
};
|
|
@@ -22559,6 +22556,52 @@ function parsePairingTicketIssuerOrigin(ticket) {
|
|
|
22559
22556
|
}
|
|
22560
22557
|
return issuerUrl.origin;
|
|
22561
22558
|
}
|
|
22559
|
+
function parseAitAgentDid(ait) {
|
|
22560
|
+
const parts = ait.split(".");
|
|
22561
|
+
if (parts.length < 2) {
|
|
22562
|
+
throw createCliError7(
|
|
22563
|
+
"CLI_PAIR_AGENT_NOT_FOUND",
|
|
22564
|
+
"Agent AIT is invalid. Recreate the agent before pairing."
|
|
22565
|
+
);
|
|
22566
|
+
}
|
|
22567
|
+
let payloadRaw;
|
|
22568
|
+
try {
|
|
22569
|
+
payloadRaw = new TextDecoder().decode(decodeBase64url(parts[1] ?? ""));
|
|
22570
|
+
} catch {
|
|
22571
|
+
throw createCliError7(
|
|
22572
|
+
"CLI_PAIR_AGENT_NOT_FOUND",
|
|
22573
|
+
"Agent AIT is invalid. Recreate the agent before pairing."
|
|
22574
|
+
);
|
|
22575
|
+
}
|
|
22576
|
+
let payload;
|
|
22577
|
+
try {
|
|
22578
|
+
payload = JSON.parse(payloadRaw);
|
|
22579
|
+
} catch {
|
|
22580
|
+
throw createCliError7(
|
|
22581
|
+
"CLI_PAIR_AGENT_NOT_FOUND",
|
|
22582
|
+
"Agent AIT is invalid. Recreate the agent before pairing."
|
|
22583
|
+
);
|
|
22584
|
+
}
|
|
22585
|
+
if (!isRecord9(payload) || typeof payload.sub !== "string") {
|
|
22586
|
+
throw createCliError7(
|
|
22587
|
+
"CLI_PAIR_AGENT_NOT_FOUND",
|
|
22588
|
+
"Agent AIT is invalid. Recreate the agent before pairing."
|
|
22589
|
+
);
|
|
22590
|
+
}
|
|
22591
|
+
const candidate = payload.sub.trim();
|
|
22592
|
+
try {
|
|
22593
|
+
const parsed = parseDid(candidate);
|
|
22594
|
+
if (parsed.kind !== "agent") {
|
|
22595
|
+
throw new Error("invalid kind");
|
|
22596
|
+
}
|
|
22597
|
+
} catch {
|
|
22598
|
+
throw createCliError7(
|
|
22599
|
+
"CLI_PAIR_AGENT_NOT_FOUND",
|
|
22600
|
+
"Agent AIT is invalid. Recreate the agent before pairing."
|
|
22601
|
+
);
|
|
22602
|
+
}
|
|
22603
|
+
return candidate;
|
|
22604
|
+
}
|
|
22562
22605
|
function parsePeerAlias2(value) {
|
|
22563
22606
|
if (value.length === 0 || value.length > 128) {
|
|
22564
22607
|
throw createCliError7(
|
|
@@ -22690,6 +22733,20 @@ function parseTtlSeconds(value) {
|
|
|
22690
22733
|
}
|
|
22691
22734
|
return parsed;
|
|
22692
22735
|
}
|
|
22736
|
+
function parsePositiveIntegerOption(input) {
|
|
22737
|
+
const raw = parseNonEmptyString9(input.value);
|
|
22738
|
+
if (raw.length === 0) {
|
|
22739
|
+
return input.defaultValue;
|
|
22740
|
+
}
|
|
22741
|
+
const parsed = Number.parseInt(raw, 10);
|
|
22742
|
+
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
22743
|
+
throw createCliError7(
|
|
22744
|
+
"CLI_PAIR_STATUS_WAIT_INVALID",
|
|
22745
|
+
`${input.optionName} must be a positive integer`
|
|
22746
|
+
);
|
|
22747
|
+
}
|
|
22748
|
+
return parsed;
|
|
22749
|
+
}
|
|
22693
22750
|
function parseProxyUrl2(candidate) {
|
|
22694
22751
|
try {
|
|
22695
22752
|
const parsed = new URL(candidate);
|
|
@@ -22810,6 +22867,29 @@ function mapConfirmPairError(status, payload) {
|
|
|
22810
22867
|
}
|
|
22811
22868
|
return `Pair confirm failed (${status})`;
|
|
22812
22869
|
}
|
|
22870
|
+
function mapStatusPairError(status, payload) {
|
|
22871
|
+
const code = extractErrorCode(payload);
|
|
22872
|
+
const message2 = extractErrorMessage(payload);
|
|
22873
|
+
if (code === "PROXY_PAIR_TICKET_NOT_FOUND" || status === 404) {
|
|
22874
|
+
return "Pairing ticket not found";
|
|
22875
|
+
}
|
|
22876
|
+
if (code === "PROXY_PAIR_TICKET_EXPIRED" || status === 410) {
|
|
22877
|
+
return "Pairing ticket has expired";
|
|
22878
|
+
}
|
|
22879
|
+
if (code === "PROXY_PAIR_STATUS_FORBIDDEN" || status === 403) {
|
|
22880
|
+
return message2 ? `Pair status request is forbidden (403): ${message2}` : "Pair status request is forbidden (403).";
|
|
22881
|
+
}
|
|
22882
|
+
if (status === 400) {
|
|
22883
|
+
return message2 ? `Pair status request is invalid (400): ${message2}` : "Pair status request is invalid (400).";
|
|
22884
|
+
}
|
|
22885
|
+
if (status >= 500) {
|
|
22886
|
+
return `Proxy pairing service is unavailable (${status}).`;
|
|
22887
|
+
}
|
|
22888
|
+
if (message2) {
|
|
22889
|
+
return `Pair status failed (${status}): ${message2}`;
|
|
22890
|
+
}
|
|
22891
|
+
return `Pair status failed (${status})`;
|
|
22892
|
+
}
|
|
22813
22893
|
function parsePairStartResponse(payload) {
|
|
22814
22894
|
if (!isRecord9(payload)) {
|
|
22815
22895
|
throw createCliError7(
|
|
@@ -22854,6 +22934,44 @@ function parsePairConfirmResponse(payload) {
|
|
|
22854
22934
|
responderAgentDid
|
|
22855
22935
|
};
|
|
22856
22936
|
}
|
|
22937
|
+
function parsePairStatusResponse(payload) {
|
|
22938
|
+
if (!isRecord9(payload)) {
|
|
22939
|
+
throw createCliError7(
|
|
22940
|
+
"CLI_PAIR_STATUS_INVALID_RESPONSE",
|
|
22941
|
+
"Pair status response is invalid"
|
|
22942
|
+
);
|
|
22943
|
+
}
|
|
22944
|
+
const statusRaw = parseNonEmptyString9(payload.status);
|
|
22945
|
+
if (statusRaw !== "pending" && statusRaw !== "confirmed") {
|
|
22946
|
+
throw createCliError7(
|
|
22947
|
+
"CLI_PAIR_STATUS_INVALID_RESPONSE",
|
|
22948
|
+
"Pair status response is invalid"
|
|
22949
|
+
);
|
|
22950
|
+
}
|
|
22951
|
+
const initiatorAgentDid = parseNonEmptyString9(payload.initiatorAgentDid);
|
|
22952
|
+
const responderAgentDid = parseNonEmptyString9(payload.responderAgentDid);
|
|
22953
|
+
const expiresAt = parseNonEmptyString9(payload.expiresAt);
|
|
22954
|
+
const confirmedAt = parseNonEmptyString9(payload.confirmedAt);
|
|
22955
|
+
if (initiatorAgentDid.length === 0 || expiresAt.length === 0) {
|
|
22956
|
+
throw createCliError7(
|
|
22957
|
+
"CLI_PAIR_STATUS_INVALID_RESPONSE",
|
|
22958
|
+
"Pair status response is invalid"
|
|
22959
|
+
);
|
|
22960
|
+
}
|
|
22961
|
+
if (statusRaw === "confirmed" && responderAgentDid.length === 0) {
|
|
22962
|
+
throw createCliError7(
|
|
22963
|
+
"CLI_PAIR_STATUS_INVALID_RESPONSE",
|
|
22964
|
+
"Pair status response is invalid"
|
|
22965
|
+
);
|
|
22966
|
+
}
|
|
22967
|
+
return {
|
|
22968
|
+
status: statusRaw,
|
|
22969
|
+
initiatorAgentDid,
|
|
22970
|
+
responderAgentDid: responderAgentDid.length > 0 ? responderAgentDid : void 0,
|
|
22971
|
+
expiresAt,
|
|
22972
|
+
confirmedAt: confirmedAt.length > 0 ? confirmedAt : void 0
|
|
22973
|
+
};
|
|
22974
|
+
}
|
|
22857
22975
|
async function readAgentProofMaterial(agentName, dependencies) {
|
|
22858
22976
|
const readFileImpl = dependencies.readFileImpl ?? readFile5;
|
|
22859
22977
|
const getConfigDirImpl = dependencies.getConfigDirImpl ?? getConfigDir;
|
|
@@ -23244,6 +23362,147 @@ async function confirmPairing(agentName, options, dependencies = {}) {
|
|
|
23244
23362
|
peerAlias
|
|
23245
23363
|
};
|
|
23246
23364
|
}
|
|
23365
|
+
async function getPairingStatusOnce(agentName, options, dependencies = {}) {
|
|
23366
|
+
const fetchImpl = dependencies.fetchImpl ?? fetch;
|
|
23367
|
+
const resolveConfigImpl = dependencies.resolveConfigImpl ?? resolveConfig;
|
|
23368
|
+
const nowSecondsImpl = dependencies.nowSecondsImpl ?? (() => Math.floor(Date.now() / 1e3));
|
|
23369
|
+
const nonceFactoryImpl = dependencies.nonceFactoryImpl ?? (() => randomBytes4(NONCE_SIZE2).toString("base64url"));
|
|
23370
|
+
const config2 = await resolveConfigImpl();
|
|
23371
|
+
const proxyUrl = await resolveProxyUrl({
|
|
23372
|
+
config: config2,
|
|
23373
|
+
fetchImpl
|
|
23374
|
+
});
|
|
23375
|
+
const ticket = parsePairingTicket(options.ticket);
|
|
23376
|
+
const { ait, secretKey } = await readAgentProofMaterial(
|
|
23377
|
+
agentName,
|
|
23378
|
+
dependencies
|
|
23379
|
+
);
|
|
23380
|
+
const callerAgentDid = parseAitAgentDid(ait);
|
|
23381
|
+
const requestUrl = toProxyRequestUrl(proxyUrl, PAIR_STATUS_PATH);
|
|
23382
|
+
const requestBody = JSON.stringify({ ticket });
|
|
23383
|
+
const bodyBytes = new TextEncoder().encode(requestBody);
|
|
23384
|
+
const timestampSeconds = nowSecondsImpl();
|
|
23385
|
+
const nonce = nonceFactoryImpl();
|
|
23386
|
+
const signedHeaders = await buildSignedHeaders({
|
|
23387
|
+
method: "POST",
|
|
23388
|
+
requestUrl,
|
|
23389
|
+
bodyBytes,
|
|
23390
|
+
secretKey,
|
|
23391
|
+
timestampSeconds,
|
|
23392
|
+
nonce
|
|
23393
|
+
});
|
|
23394
|
+
const response = await executePairRequest({
|
|
23395
|
+
fetchImpl,
|
|
23396
|
+
url: requestUrl,
|
|
23397
|
+
init: {
|
|
23398
|
+
method: "POST",
|
|
23399
|
+
headers: {
|
|
23400
|
+
authorization: `Claw ${ait}`,
|
|
23401
|
+
"content-type": "application/json",
|
|
23402
|
+
...signedHeaders
|
|
23403
|
+
},
|
|
23404
|
+
body: requestBody
|
|
23405
|
+
}
|
|
23406
|
+
});
|
|
23407
|
+
const responseBody = await parseJsonResponse6(response);
|
|
23408
|
+
if (!response.ok) {
|
|
23409
|
+
throw createCliError7(
|
|
23410
|
+
"CLI_PAIR_STATUS_FAILED",
|
|
23411
|
+
mapStatusPairError(response.status, responseBody)
|
|
23412
|
+
);
|
|
23413
|
+
}
|
|
23414
|
+
const parsed = parsePairStatusResponse(responseBody);
|
|
23415
|
+
let peerAlias;
|
|
23416
|
+
if (parsed.status === "confirmed") {
|
|
23417
|
+
const responderAgentDid = parsed.responderAgentDid;
|
|
23418
|
+
if (!responderAgentDid) {
|
|
23419
|
+
throw createCliError7(
|
|
23420
|
+
"CLI_PAIR_STATUS_INVALID_RESPONSE",
|
|
23421
|
+
"Pair status response is invalid"
|
|
23422
|
+
);
|
|
23423
|
+
}
|
|
23424
|
+
const peerDid = callerAgentDid === parsed.initiatorAgentDid ? responderAgentDid : callerAgentDid === responderAgentDid ? parsed.initiatorAgentDid : void 0;
|
|
23425
|
+
if (!peerDid) {
|
|
23426
|
+
throw createCliError7(
|
|
23427
|
+
"CLI_PAIR_STATUS_FORBIDDEN",
|
|
23428
|
+
"Local agent is not a participant in the pairing ticket"
|
|
23429
|
+
);
|
|
23430
|
+
}
|
|
23431
|
+
peerAlias = await persistPairedPeer({
|
|
23432
|
+
ticket,
|
|
23433
|
+
peerDid,
|
|
23434
|
+
dependencies
|
|
23435
|
+
});
|
|
23436
|
+
}
|
|
23437
|
+
return {
|
|
23438
|
+
...parsed,
|
|
23439
|
+
proxyUrl,
|
|
23440
|
+
peerAlias
|
|
23441
|
+
};
|
|
23442
|
+
}
|
|
23443
|
+
async function waitForPairingStatus(input) {
|
|
23444
|
+
const nowSecondsImpl = input.dependencies.nowSecondsImpl ?? (() => Math.floor(Date.now() / 1e3));
|
|
23445
|
+
const sleepImpl = input.dependencies.sleepImpl ?? (async (ms) => {
|
|
23446
|
+
await new Promise((resolve2) => {
|
|
23447
|
+
setTimeout(resolve2, ms);
|
|
23448
|
+
});
|
|
23449
|
+
});
|
|
23450
|
+
const deadlineSeconds = nowSecondsImpl() + input.waitSeconds;
|
|
23451
|
+
while (true) {
|
|
23452
|
+
const status = await getPairingStatusOnce(
|
|
23453
|
+
input.agentName,
|
|
23454
|
+
{ ticket: input.ticket },
|
|
23455
|
+
input.dependencies
|
|
23456
|
+
);
|
|
23457
|
+
if (status.status === "confirmed") {
|
|
23458
|
+
return status;
|
|
23459
|
+
}
|
|
23460
|
+
const nowSeconds = nowSecondsImpl();
|
|
23461
|
+
if (nowSeconds >= deadlineSeconds) {
|
|
23462
|
+
throw createCliError7(
|
|
23463
|
+
"CLI_PAIR_STATUS_WAIT_TIMEOUT",
|
|
23464
|
+
`Pairing is still pending after ${input.waitSeconds} seconds`
|
|
23465
|
+
);
|
|
23466
|
+
}
|
|
23467
|
+
const remainingSeconds = Math.max(0, deadlineSeconds - nowSeconds);
|
|
23468
|
+
const sleepSeconds = Math.min(input.pollIntervalSeconds, remainingSeconds);
|
|
23469
|
+
await sleepImpl(sleepSeconds * 1e3);
|
|
23470
|
+
}
|
|
23471
|
+
}
|
|
23472
|
+
async function getPairingStatus(agentName, options, dependencies = {}) {
|
|
23473
|
+
const ticketRaw = parseNonEmptyString9(options.ticket);
|
|
23474
|
+
if (ticketRaw.length === 0) {
|
|
23475
|
+
throw createCliError7(
|
|
23476
|
+
"CLI_PAIR_STATUS_TICKET_REQUIRED",
|
|
23477
|
+
"Pair status requires --ticket <clwpair1_...>"
|
|
23478
|
+
);
|
|
23479
|
+
}
|
|
23480
|
+
const ticket = parsePairingTicket(ticketRaw);
|
|
23481
|
+
if (options.wait !== true) {
|
|
23482
|
+
return getPairingStatusOnce(
|
|
23483
|
+
agentName,
|
|
23484
|
+
{ ticket },
|
|
23485
|
+
dependencies
|
|
23486
|
+
);
|
|
23487
|
+
}
|
|
23488
|
+
const waitSeconds = parsePositiveIntegerOption({
|
|
23489
|
+
value: options.waitSeconds,
|
|
23490
|
+
optionName: "waitSeconds",
|
|
23491
|
+
defaultValue: DEFAULT_STATUS_WAIT_SECONDS
|
|
23492
|
+
});
|
|
23493
|
+
const pollIntervalSeconds = parsePositiveIntegerOption({
|
|
23494
|
+
value: options.pollIntervalSeconds,
|
|
23495
|
+
optionName: "pollIntervalSeconds",
|
|
23496
|
+
defaultValue: DEFAULT_STATUS_POLL_INTERVAL_SECONDS
|
|
23497
|
+
});
|
|
23498
|
+
return waitForPairingStatus({
|
|
23499
|
+
agentName,
|
|
23500
|
+
ticket,
|
|
23501
|
+
waitSeconds,
|
|
23502
|
+
pollIntervalSeconds,
|
|
23503
|
+
dependencies
|
|
23504
|
+
});
|
|
23505
|
+
}
|
|
23247
23506
|
var createPairCommand = (dependencies = {}) => {
|
|
23248
23507
|
const pairCommand = new Command8("pair").description(
|
|
23249
23508
|
"Manage proxy trust pairing between agents"
|
|
@@ -23251,7 +23510,16 @@ var createPairCommand = (dependencies = {}) => {
|
|
|
23251
23510
|
pairCommand.command("start <agentName>").description("Start pairing and issue one-time pairing ticket").option(
|
|
23252
23511
|
"--owner-pat <token>",
|
|
23253
23512
|
"Owner PAT override (defaults to configured API key)"
|
|
23254
|
-
).option("--ttl-seconds <seconds>", "Pairing ticket expiry in seconds").option("--qr", "Generate a local QR file for sharing").option("--qr-output <path>", "Write QR PNG to a specific file path").
|
|
23513
|
+
).option("--ttl-seconds <seconds>", "Pairing ticket expiry in seconds").option("--qr", "Generate a local QR file for sharing").option("--qr-output <path>", "Write QR PNG to a specific file path").option(
|
|
23514
|
+
"--wait",
|
|
23515
|
+
"Wait for responder confirmation and auto-save peer on initiator"
|
|
23516
|
+
).option(
|
|
23517
|
+
"--wait-seconds <seconds>",
|
|
23518
|
+
"Max seconds to poll for confirmation (default: 300)"
|
|
23519
|
+
).option(
|
|
23520
|
+
"--poll-interval-seconds <seconds>",
|
|
23521
|
+
"Polling interval in seconds while waiting (default: 3)"
|
|
23522
|
+
).action(
|
|
23255
23523
|
withErrorHandling(
|
|
23256
23524
|
"pair start",
|
|
23257
23525
|
async (agentName, options) => {
|
|
@@ -23269,6 +23537,44 @@ var createPairCommand = (dependencies = {}) => {
|
|
|
23269
23537
|
if (result.qrPath) {
|
|
23270
23538
|
writeStdoutLine(`QR File: ${result.qrPath}`);
|
|
23271
23539
|
}
|
|
23540
|
+
if (options.wait === true) {
|
|
23541
|
+
const waitSeconds = parsePositiveIntegerOption({
|
|
23542
|
+
value: options.waitSeconds,
|
|
23543
|
+
optionName: "waitSeconds",
|
|
23544
|
+
defaultValue: DEFAULT_STATUS_WAIT_SECONDS
|
|
23545
|
+
});
|
|
23546
|
+
const pollIntervalSeconds = parsePositiveIntegerOption({
|
|
23547
|
+
value: options.pollIntervalSeconds,
|
|
23548
|
+
optionName: "pollIntervalSeconds",
|
|
23549
|
+
defaultValue: DEFAULT_STATUS_POLL_INTERVAL_SECONDS
|
|
23550
|
+
});
|
|
23551
|
+
writeStdoutLine(
|
|
23552
|
+
`Waiting for confirmation (timeout=${waitSeconds}s, interval=${pollIntervalSeconds}s) ...`
|
|
23553
|
+
);
|
|
23554
|
+
const status = await waitForPairingStatus({
|
|
23555
|
+
agentName,
|
|
23556
|
+
ticket: result.ticket,
|
|
23557
|
+
waitSeconds,
|
|
23558
|
+
pollIntervalSeconds,
|
|
23559
|
+
dependencies
|
|
23560
|
+
});
|
|
23561
|
+
logger9.info("cli.pair_status_confirmed_after_start", {
|
|
23562
|
+
initiatorAgentDid: status.initiatorAgentDid,
|
|
23563
|
+
responderAgentDid: status.responderAgentDid,
|
|
23564
|
+
peerAlias: status.peerAlias
|
|
23565
|
+
});
|
|
23566
|
+
writeStdoutLine("Pairing confirmed");
|
|
23567
|
+
writeStdoutLine(`Status: ${status.status}`);
|
|
23568
|
+
if (status.initiatorAgentDid) {
|
|
23569
|
+
writeStdoutLine(`Initiator Agent DID: ${status.initiatorAgentDid}`);
|
|
23570
|
+
}
|
|
23571
|
+
if (status.responderAgentDid) {
|
|
23572
|
+
writeStdoutLine(`Responder Agent DID: ${status.responderAgentDid}`);
|
|
23573
|
+
}
|
|
23574
|
+
if (status.peerAlias) {
|
|
23575
|
+
writeStdoutLine(`Peer alias saved: ${status.peerAlias}`);
|
|
23576
|
+
}
|
|
23577
|
+
}
|
|
23272
23578
|
}
|
|
23273
23579
|
)
|
|
23274
23580
|
);
|
|
@@ -23293,12 +23599,377 @@ var createPairCommand = (dependencies = {}) => {
|
|
|
23293
23599
|
}
|
|
23294
23600
|
)
|
|
23295
23601
|
);
|
|
23602
|
+
pairCommand.command("status <agentName>").description("Check pairing ticket status and sync local peer on confirm").option("--ticket <ticket>", "One-time pairing ticket (clwpair1_...)").option("--wait", "Poll until ticket is confirmed or timeout is reached").option(
|
|
23603
|
+
"--wait-seconds <seconds>",
|
|
23604
|
+
"Max seconds to poll for confirmation (default: 300)"
|
|
23605
|
+
).option(
|
|
23606
|
+
"--poll-interval-seconds <seconds>",
|
|
23607
|
+
"Polling interval in seconds while waiting (default: 3)"
|
|
23608
|
+
).action(
|
|
23609
|
+
withErrorHandling(
|
|
23610
|
+
"pair status",
|
|
23611
|
+
async (agentName, options) => {
|
|
23612
|
+
const result = await getPairingStatus(agentName, options, dependencies);
|
|
23613
|
+
logger9.info("cli.pair_status", {
|
|
23614
|
+
initiatorAgentDid: result.initiatorAgentDid,
|
|
23615
|
+
responderAgentDid: result.responderAgentDid,
|
|
23616
|
+
status: result.status,
|
|
23617
|
+
proxyUrl: result.proxyUrl,
|
|
23618
|
+
peerAlias: result.peerAlias
|
|
23619
|
+
});
|
|
23620
|
+
writeStdoutLine(`Status: ${result.status}`);
|
|
23621
|
+
writeStdoutLine(`Initiator Agent DID: ${result.initiatorAgentDid}`);
|
|
23622
|
+
if (result.responderAgentDid) {
|
|
23623
|
+
writeStdoutLine(`Responder Agent DID: ${result.responderAgentDid}`);
|
|
23624
|
+
}
|
|
23625
|
+
writeStdoutLine(`Expires At: ${result.expiresAt}`);
|
|
23626
|
+
if (result.confirmedAt) {
|
|
23627
|
+
writeStdoutLine(`Confirmed At: ${result.confirmedAt}`);
|
|
23628
|
+
}
|
|
23629
|
+
if (result.peerAlias) {
|
|
23630
|
+
writeStdoutLine(`Peer alias saved: ${result.peerAlias}`);
|
|
23631
|
+
}
|
|
23632
|
+
}
|
|
23633
|
+
)
|
|
23634
|
+
);
|
|
23296
23635
|
return pairCommand;
|
|
23297
23636
|
};
|
|
23298
23637
|
|
|
23299
|
-
// src/commands/
|
|
23300
|
-
import { readFile as readFile6 } from "fs/promises";
|
|
23638
|
+
// src/commands/skill.ts
|
|
23301
23639
|
import { Command as Command9 } from "commander";
|
|
23640
|
+
|
|
23641
|
+
// src/install-skill-mode.ts
|
|
23642
|
+
import { constants, existsSync as existsSync2 } from "fs";
|
|
23643
|
+
import { access as access3, copyFile as copyFile2, mkdir as mkdir7, readdir as readdir2, readFile as readFile6 } from "fs/promises";
|
|
23644
|
+
import { createRequire } from "module";
|
|
23645
|
+
import { homedir as homedir4 } from "os";
|
|
23646
|
+
import { dirname as dirname6, join as join8, relative } from "path";
|
|
23647
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
23648
|
+
var OPENCLAW_DIR_NAME2 = ".openclaw";
|
|
23649
|
+
var SKILL_PACKAGE_NAME = "@clawdentity/openclaw-skill";
|
|
23650
|
+
var SKILL_DIR_NAME2 = "clawdentity-openclaw-relay";
|
|
23651
|
+
var RELAY_MODULE_FILE_NAME2 = "relay-to-peer.mjs";
|
|
23652
|
+
function isRecord10(value) {
|
|
23653
|
+
return typeof value === "object" && value !== null;
|
|
23654
|
+
}
|
|
23655
|
+
var SkillInstallError = class extends Error {
|
|
23656
|
+
code;
|
|
23657
|
+
details;
|
|
23658
|
+
constructor(input) {
|
|
23659
|
+
super(input.message);
|
|
23660
|
+
this.name = "SkillInstallError";
|
|
23661
|
+
this.code = input.code;
|
|
23662
|
+
this.details = input.details ?? {};
|
|
23663
|
+
}
|
|
23664
|
+
};
|
|
23665
|
+
function getErrorCode3(error48) {
|
|
23666
|
+
if (!isRecord10(error48)) {
|
|
23667
|
+
return void 0;
|
|
23668
|
+
}
|
|
23669
|
+
return typeof error48.code === "string" ? error48.code : void 0;
|
|
23670
|
+
}
|
|
23671
|
+
function resolveHomeDir2(inputHomeDir) {
|
|
23672
|
+
if (typeof inputHomeDir === "string" && inputHomeDir.trim().length > 0) {
|
|
23673
|
+
return inputHomeDir.trim();
|
|
23674
|
+
}
|
|
23675
|
+
return homedir4();
|
|
23676
|
+
}
|
|
23677
|
+
function resolveOpenclawDir2(homeDir, inputOpenclawDir) {
|
|
23678
|
+
if (typeof inputOpenclawDir === "string" && inputOpenclawDir.trim().length > 0) {
|
|
23679
|
+
return inputOpenclawDir.trim();
|
|
23680
|
+
}
|
|
23681
|
+
return join8(homeDir, OPENCLAW_DIR_NAME2);
|
|
23682
|
+
}
|
|
23683
|
+
function resolveSkillPackageRoot(input) {
|
|
23684
|
+
if (typeof input.skillPackageRoot === "string" && input.skillPackageRoot.trim().length > 0) {
|
|
23685
|
+
return input.skillPackageRoot.trim();
|
|
23686
|
+
}
|
|
23687
|
+
const overriddenRoot = input.env.CLAWDENTITY_SKILL_PACKAGE_ROOT;
|
|
23688
|
+
if (typeof overriddenRoot === "string" && overriddenRoot.trim().length > 0) {
|
|
23689
|
+
return overriddenRoot.trim();
|
|
23690
|
+
}
|
|
23691
|
+
const bundledSkillRoot = join8(
|
|
23692
|
+
dirname6(fileURLToPath2(import.meta.url)),
|
|
23693
|
+
"..",
|
|
23694
|
+
"skill-bundle",
|
|
23695
|
+
"openclaw-skill"
|
|
23696
|
+
);
|
|
23697
|
+
if (existsSync2(bundledSkillRoot)) {
|
|
23698
|
+
return bundledSkillRoot;
|
|
23699
|
+
}
|
|
23700
|
+
const require3 = createRequire(import.meta.url);
|
|
23701
|
+
let packageJsonPath;
|
|
23702
|
+
try {
|
|
23703
|
+
packageJsonPath = require3.resolve(`${SKILL_PACKAGE_NAME}/package.json`);
|
|
23704
|
+
return dirname6(packageJsonPath);
|
|
23705
|
+
} catch {
|
|
23706
|
+
const workspaceFallbackRoot = join8(
|
|
23707
|
+
dirname6(fileURLToPath2(import.meta.url)),
|
|
23708
|
+
"..",
|
|
23709
|
+
"..",
|
|
23710
|
+
"openclaw-skill"
|
|
23711
|
+
);
|
|
23712
|
+
if (existsSync2(workspaceFallbackRoot)) {
|
|
23713
|
+
return workspaceFallbackRoot;
|
|
23714
|
+
}
|
|
23715
|
+
throw new SkillInstallError({
|
|
23716
|
+
code: "CLI_SKILL_PACKAGE_NOT_FOUND",
|
|
23717
|
+
message: "Skill artifacts are unavailable. Set CLAWDENTITY_SKILL_PACKAGE_ROOT or provide bundled skill assets before running skill install.",
|
|
23718
|
+
details: {
|
|
23719
|
+
packageName: SKILL_PACKAGE_NAME,
|
|
23720
|
+
bundledSkillRoot,
|
|
23721
|
+
workspaceFallbackRoot
|
|
23722
|
+
}
|
|
23723
|
+
});
|
|
23724
|
+
}
|
|
23725
|
+
}
|
|
23726
|
+
async function assertReadableFile(filePath, details) {
|
|
23727
|
+
try {
|
|
23728
|
+
await access3(filePath, constants.R_OK);
|
|
23729
|
+
} catch (error48) {
|
|
23730
|
+
if (getErrorCode3(error48) === "ENOENT") {
|
|
23731
|
+
throw new SkillInstallError({
|
|
23732
|
+
code: "CLI_SKILL_ARTIFACT_MISSING",
|
|
23733
|
+
message: "Required skill artifact is missing",
|
|
23734
|
+
details: {
|
|
23735
|
+
...details,
|
|
23736
|
+
sourcePath: filePath
|
|
23737
|
+
}
|
|
23738
|
+
});
|
|
23739
|
+
}
|
|
23740
|
+
throw error48;
|
|
23741
|
+
}
|
|
23742
|
+
}
|
|
23743
|
+
async function listFilesRecursively(directoryPath) {
|
|
23744
|
+
const entries = await readdir2(directoryPath, { withFileTypes: true });
|
|
23745
|
+
const files = [];
|
|
23746
|
+
for (const entry of entries.sort(
|
|
23747
|
+
(left, right) => left.name.localeCompare(right.name)
|
|
23748
|
+
)) {
|
|
23749
|
+
const entryPath = join8(directoryPath, entry.name);
|
|
23750
|
+
if (entry.isDirectory()) {
|
|
23751
|
+
files.push(...await listFilesRecursively(entryPath));
|
|
23752
|
+
continue;
|
|
23753
|
+
}
|
|
23754
|
+
if (entry.isFile()) {
|
|
23755
|
+
files.push(entryPath);
|
|
23756
|
+
}
|
|
23757
|
+
}
|
|
23758
|
+
return files;
|
|
23759
|
+
}
|
|
23760
|
+
async function resolveArtifacts(input) {
|
|
23761
|
+
const skillRoot = join8(input.skillPackageRoot, "skill");
|
|
23762
|
+
const skillDocSource = join8(skillRoot, "SKILL.md");
|
|
23763
|
+
const referencesRoot = join8(skillRoot, "references");
|
|
23764
|
+
const relaySource = join8(
|
|
23765
|
+
input.skillPackageRoot,
|
|
23766
|
+
"dist",
|
|
23767
|
+
RELAY_MODULE_FILE_NAME2
|
|
23768
|
+
);
|
|
23769
|
+
await assertReadableFile(skillDocSource, {
|
|
23770
|
+
artifact: "SKILL.md"
|
|
23771
|
+
});
|
|
23772
|
+
await assertReadableFile(relaySource, {
|
|
23773
|
+
artifact: RELAY_MODULE_FILE_NAME2
|
|
23774
|
+
});
|
|
23775
|
+
let referenceFiles;
|
|
23776
|
+
try {
|
|
23777
|
+
referenceFiles = await listFilesRecursively(referencesRoot);
|
|
23778
|
+
} catch (error48) {
|
|
23779
|
+
if (getErrorCode3(error48) === "ENOENT") {
|
|
23780
|
+
throw new SkillInstallError({
|
|
23781
|
+
code: "CLI_SKILL_ARTIFACT_MISSING",
|
|
23782
|
+
message: "Required skill references directory is missing",
|
|
23783
|
+
details: {
|
|
23784
|
+
sourcePath: referencesRoot,
|
|
23785
|
+
artifact: "references"
|
|
23786
|
+
}
|
|
23787
|
+
});
|
|
23788
|
+
}
|
|
23789
|
+
throw error48;
|
|
23790
|
+
}
|
|
23791
|
+
if (referenceFiles.length === 0) {
|
|
23792
|
+
throw new SkillInstallError({
|
|
23793
|
+
code: "CLI_SKILL_REFERENCE_DIR_EMPTY",
|
|
23794
|
+
message: "Required skill references directory is empty",
|
|
23795
|
+
details: {
|
|
23796
|
+
sourcePath: referencesRoot
|
|
23797
|
+
}
|
|
23798
|
+
});
|
|
23799
|
+
}
|
|
23800
|
+
const targetSkillRoot = join8(
|
|
23801
|
+
input.openclawDir,
|
|
23802
|
+
"skills",
|
|
23803
|
+
SKILL_DIR_NAME2
|
|
23804
|
+
);
|
|
23805
|
+
const artifacts = [
|
|
23806
|
+
{
|
|
23807
|
+
sourcePath: skillDocSource,
|
|
23808
|
+
targetPath: join8(targetSkillRoot, "SKILL.md")
|
|
23809
|
+
},
|
|
23810
|
+
{
|
|
23811
|
+
sourcePath: relaySource,
|
|
23812
|
+
targetPath: join8(targetSkillRoot, RELAY_MODULE_FILE_NAME2)
|
|
23813
|
+
},
|
|
23814
|
+
{
|
|
23815
|
+
sourcePath: relaySource,
|
|
23816
|
+
targetPath: join8(
|
|
23817
|
+
input.openclawDir,
|
|
23818
|
+
"hooks",
|
|
23819
|
+
"transforms",
|
|
23820
|
+
RELAY_MODULE_FILE_NAME2
|
|
23821
|
+
)
|
|
23822
|
+
}
|
|
23823
|
+
];
|
|
23824
|
+
for (const referenceFile of referenceFiles) {
|
|
23825
|
+
const relativePath = relative(referencesRoot, referenceFile);
|
|
23826
|
+
artifacts.push({
|
|
23827
|
+
sourcePath: referenceFile,
|
|
23828
|
+
targetPath: join8(targetSkillRoot, "references", relativePath)
|
|
23829
|
+
});
|
|
23830
|
+
}
|
|
23831
|
+
return artifacts.sort(
|
|
23832
|
+
(left, right) => left.targetPath.localeCompare(right.targetPath)
|
|
23833
|
+
);
|
|
23834
|
+
}
|
|
23835
|
+
async function copyArtifact(input) {
|
|
23836
|
+
const sourceContent = await readFile6(input.sourcePath);
|
|
23837
|
+
let existingContent;
|
|
23838
|
+
try {
|
|
23839
|
+
existingContent = await readFile6(input.targetPath);
|
|
23840
|
+
} catch (error48) {
|
|
23841
|
+
if (getErrorCode3(error48) !== "ENOENT") {
|
|
23842
|
+
throw error48;
|
|
23843
|
+
}
|
|
23844
|
+
}
|
|
23845
|
+
if (existingContent !== void 0 && sourceContent.equals(existingContent)) {
|
|
23846
|
+
return "unchanged";
|
|
23847
|
+
}
|
|
23848
|
+
await mkdir7(dirname6(input.targetPath), { recursive: true });
|
|
23849
|
+
await copyFile2(input.sourcePath, input.targetPath);
|
|
23850
|
+
if (existingContent !== void 0) {
|
|
23851
|
+
return "updated";
|
|
23852
|
+
}
|
|
23853
|
+
return "installed";
|
|
23854
|
+
}
|
|
23855
|
+
async function installOpenclawSkillArtifacts(options = {}) {
|
|
23856
|
+
const env = options.env ?? process.env;
|
|
23857
|
+
const homeDir = resolveHomeDir2(options.homeDir);
|
|
23858
|
+
const openclawDir = resolveOpenclawDir2(homeDir, options.openclawDir);
|
|
23859
|
+
const skillPackageRoot = resolveSkillPackageRoot({
|
|
23860
|
+
skillPackageRoot: options.skillPackageRoot,
|
|
23861
|
+
env
|
|
23862
|
+
});
|
|
23863
|
+
const artifacts = await resolveArtifacts({
|
|
23864
|
+
skillPackageRoot,
|
|
23865
|
+
openclawDir
|
|
23866
|
+
});
|
|
23867
|
+
const records = [];
|
|
23868
|
+
for (const artifact of artifacts) {
|
|
23869
|
+
const action = await copyArtifact(artifact);
|
|
23870
|
+
records.push({
|
|
23871
|
+
action,
|
|
23872
|
+
sourcePath: artifact.sourcePath,
|
|
23873
|
+
targetPath: artifact.targetPath
|
|
23874
|
+
});
|
|
23875
|
+
}
|
|
23876
|
+
return {
|
|
23877
|
+
homeDir,
|
|
23878
|
+
openclawDir,
|
|
23879
|
+
skillPackageRoot,
|
|
23880
|
+
targetSkillDirectory: join8(openclawDir, "skills", SKILL_DIR_NAME2),
|
|
23881
|
+
records
|
|
23882
|
+
};
|
|
23883
|
+
}
|
|
23884
|
+
function formatSkillInstallError(error48) {
|
|
23885
|
+
if (error48 instanceof SkillInstallError) {
|
|
23886
|
+
const details = Object.entries(error48.details).map(([key, value]) => `${key}=${value}`).join(" ");
|
|
23887
|
+
if (details.length === 0) {
|
|
23888
|
+
return `${error48.code}: ${error48.message}`;
|
|
23889
|
+
}
|
|
23890
|
+
return `${error48.code}: ${error48.message} (${details})`;
|
|
23891
|
+
}
|
|
23892
|
+
if (error48 instanceof Error) {
|
|
23893
|
+
return error48.message;
|
|
23894
|
+
}
|
|
23895
|
+
return String(error48);
|
|
23896
|
+
}
|
|
23897
|
+
|
|
23898
|
+
// src/commands/skill.ts
|
|
23899
|
+
function collectStringOption(value, previous) {
|
|
23900
|
+
const trimmed = value.trim();
|
|
23901
|
+
if (trimmed.length === 0) {
|
|
23902
|
+
return previous;
|
|
23903
|
+
}
|
|
23904
|
+
return [...previous, trimmed];
|
|
23905
|
+
}
|
|
23906
|
+
function toInstallSummary(records) {
|
|
23907
|
+
const installed = records.filter((record2) => record2.action === "installed");
|
|
23908
|
+
const updated = records.filter((record2) => record2.action === "updated");
|
|
23909
|
+
const unchanged = records.filter((record2) => record2.action === "unchanged");
|
|
23910
|
+
return `installed=${installed.length} updated=${updated.length} unchanged=${unchanged.length}`;
|
|
23911
|
+
}
|
|
23912
|
+
async function runSkillInstall(options) {
|
|
23913
|
+
const requestedDirs = (options.openclawDir ?? []).filter(
|
|
23914
|
+
(dir) => dir.trim().length > 0
|
|
23915
|
+
);
|
|
23916
|
+
const dirs = requestedDirs.length > 0 ? requestedDirs : [void 0];
|
|
23917
|
+
const results = [];
|
|
23918
|
+
for (const openclawDir of dirs) {
|
|
23919
|
+
const result = await installOpenclawSkillArtifacts({
|
|
23920
|
+
openclawDir,
|
|
23921
|
+
skillPackageRoot: options.skillPackageRoot
|
|
23922
|
+
});
|
|
23923
|
+
results.push(result);
|
|
23924
|
+
}
|
|
23925
|
+
return results;
|
|
23926
|
+
}
|
|
23927
|
+
var createSkillCommand = () => {
|
|
23928
|
+
const skillCommand = new Command9("skill").description(
|
|
23929
|
+
"Install and manage Clawdentity skill artifacts"
|
|
23930
|
+
);
|
|
23931
|
+
skillCommand.command("install").description("Install Clawdentity OpenClaw skill artifacts").option(
|
|
23932
|
+
"--openclaw-dir <path>",
|
|
23933
|
+
"OpenClaw state directory target (repeat for multiple profiles)",
|
|
23934
|
+
collectStringOption,
|
|
23935
|
+
[]
|
|
23936
|
+
).option(
|
|
23937
|
+
"--skill-package-root <path>",
|
|
23938
|
+
"Override skill package root (defaults to bundled assets)"
|
|
23939
|
+
).option("--json", "Print machine-readable JSON output").action(
|
|
23940
|
+
withErrorHandling(
|
|
23941
|
+
"skill install",
|
|
23942
|
+
async (options) => {
|
|
23943
|
+
let results;
|
|
23944
|
+
try {
|
|
23945
|
+
results = await runSkillInstall(options);
|
|
23946
|
+
} catch (error48) {
|
|
23947
|
+
throw new Error(formatSkillInstallError(error48));
|
|
23948
|
+
}
|
|
23949
|
+
if (options.json) {
|
|
23950
|
+
writeStdoutLine(JSON.stringify({ installs: results }, null, 2));
|
|
23951
|
+
return;
|
|
23952
|
+
}
|
|
23953
|
+
for (const result of results) {
|
|
23954
|
+
writeStdoutLine(`OpenClaw dir: ${result.openclawDir}`);
|
|
23955
|
+
writeStdoutLine(`Skill source: ${result.skillPackageRoot}`);
|
|
23956
|
+
writeStdoutLine(`Target skill dir: ${result.targetSkillDirectory}`);
|
|
23957
|
+
for (const record2 of result.records) {
|
|
23958
|
+
writeStdoutLine(
|
|
23959
|
+
`${record2.action}: ${record2.targetPath} (source: ${record2.sourcePath})`
|
|
23960
|
+
);
|
|
23961
|
+
}
|
|
23962
|
+
writeStdoutLine(toInstallSummary(result.records));
|
|
23963
|
+
}
|
|
23964
|
+
}
|
|
23965
|
+
)
|
|
23966
|
+
);
|
|
23967
|
+
return skillCommand;
|
|
23968
|
+
};
|
|
23969
|
+
|
|
23970
|
+
// src/commands/verify.ts
|
|
23971
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
23972
|
+
import { Command as Command10 } from "commander";
|
|
23302
23973
|
var logger10 = createLogger({ service: "cli", module: "verify" });
|
|
23303
23974
|
var REGISTRY_KEYS_CACHE_FILE = "registry-keys.json";
|
|
23304
23975
|
var CRL_CLAIMS_CACHE_FILE = "crl-claims.json";
|
|
@@ -23310,7 +23981,7 @@ var VerifyCommandError = class extends Error {
|
|
|
23310
23981
|
this.name = "VerifyCommandError";
|
|
23311
23982
|
}
|
|
23312
23983
|
};
|
|
23313
|
-
var
|
|
23984
|
+
var isRecord11 = (value) => {
|
|
23314
23985
|
return typeof value === "object" && value !== null;
|
|
23315
23986
|
};
|
|
23316
23987
|
var normalizeRegistryUrl2 = (registryUrl) => {
|
|
@@ -23346,7 +24017,7 @@ var resolveToken = async (tokenOrFile) => {
|
|
|
23346
24017
|
throw new VerifyCommandError("invalid token (value is empty)");
|
|
23347
24018
|
}
|
|
23348
24019
|
try {
|
|
23349
|
-
const fileContents = await
|
|
24020
|
+
const fileContents = await readFile7(input, "utf-8");
|
|
23350
24021
|
const token = fileContents.trim();
|
|
23351
24022
|
if (token.length === 0) {
|
|
23352
24023
|
throw new VerifyCommandError(`invalid token (${input} is empty)`);
|
|
@@ -23378,7 +24049,7 @@ var parseResponseJson = async (response) => {
|
|
|
23378
24049
|
}
|
|
23379
24050
|
};
|
|
23380
24051
|
var parseSigningKeys = (payload) => {
|
|
23381
|
-
if (!
|
|
24052
|
+
if (!isRecord11(payload) || !Array.isArray(payload.keys)) {
|
|
23382
24053
|
throw new VerifyCommandError(
|
|
23383
24054
|
"verification keys unavailable (response payload is invalid)"
|
|
23384
24055
|
);
|
|
@@ -23397,7 +24068,7 @@ var parseSigningKeys = (payload) => {
|
|
|
23397
24068
|
};
|
|
23398
24069
|
var parseRegistryKeysCache = (rawCache) => {
|
|
23399
24070
|
const parsed = parseJson(rawCache);
|
|
23400
|
-
if (!
|
|
24071
|
+
if (!isRecord11(parsed)) {
|
|
23401
24072
|
return void 0;
|
|
23402
24073
|
}
|
|
23403
24074
|
const { registryUrl, fetchedAtMs, keys } = parsed;
|
|
@@ -23423,7 +24094,7 @@ var parseRegistryKeysCache = (rawCache) => {
|
|
|
23423
24094
|
};
|
|
23424
24095
|
var parseCrlCache = (rawCache) => {
|
|
23425
24096
|
const parsed = parseJson(rawCache);
|
|
23426
|
-
if (!
|
|
24097
|
+
if (!isRecord11(parsed)) {
|
|
23427
24098
|
return void 0;
|
|
23428
24099
|
}
|
|
23429
24100
|
const { registryUrl, fetchedAtMs, claims } = parsed;
|
|
@@ -23521,7 +24192,7 @@ var fetchCrlClaims = async (input) => {
|
|
|
23521
24192
|
);
|
|
23522
24193
|
}
|
|
23523
24194
|
const payload = await parseResponseJson(response);
|
|
23524
|
-
if (!
|
|
24195
|
+
if (!isRecord11(payload) || typeof payload.crl !== "string") {
|
|
23525
24196
|
throw new VerifyCommandError(
|
|
23526
24197
|
"revocation check unavailable (response payload is invalid)"
|
|
23527
24198
|
);
|
|
@@ -23566,7 +24237,7 @@ var loadCrlClaims = async (input) => {
|
|
|
23566
24237
|
return claims;
|
|
23567
24238
|
};
|
|
23568
24239
|
var toInvalidTokenReason = (error48) => {
|
|
23569
|
-
if (
|
|
24240
|
+
if (isRecord11(error48) && typeof error48.message === "string") {
|
|
23570
24241
|
return `invalid token (${error48.message})`;
|
|
23571
24242
|
}
|
|
23572
24243
|
if (error48 instanceof Error && error48.message.length > 0) {
|
|
@@ -23642,7 +24313,7 @@ var runVerify = async (tokenOrFile) => {
|
|
|
23642
24313
|
printResult(true, `token verified (${claims.sub})`);
|
|
23643
24314
|
};
|
|
23644
24315
|
var createVerifyCommand = () => {
|
|
23645
|
-
return new
|
|
24316
|
+
return new Command10("verify").description("Verify an AIT using registry keys and CRL state").argument(
|
|
23646
24317
|
"<tokenOrFile>",
|
|
23647
24318
|
"Raw AIT token or file path containing the token"
|
|
23648
24319
|
).action(
|
|
@@ -23653,7 +24324,7 @@ var createVerifyCommand = () => {
|
|
|
23653
24324
|
};
|
|
23654
24325
|
|
|
23655
24326
|
// src/index.ts
|
|
23656
|
-
var require2 =
|
|
24327
|
+
var require2 = createRequire2(import.meta.url);
|
|
23657
24328
|
var resolveCliVersion = () => {
|
|
23658
24329
|
const packageJson = require2("../package.json");
|
|
23659
24330
|
if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
|
|
@@ -23663,7 +24334,7 @@ var resolveCliVersion = () => {
|
|
|
23663
24334
|
};
|
|
23664
24335
|
var CLI_VERSION = resolveCliVersion();
|
|
23665
24336
|
var createProgram = () => {
|
|
23666
|
-
return new
|
|
24337
|
+
return new Command11("clawdentity").description("Clawdentity CLI - Agent identity management").version(CLI_VERSION).addCommand(createAdminCommand()).addCommand(createAgentCommand()).addCommand(createApiKeyCommand()).addCommand(createConnectorCommand()).addCommand(createConfigCommand()).addCommand(createInviteCommand()).addCommand(createOpenclawCommand()).addCommand(createPairCommand()).addCommand(createSkillCommand()).addCommand(createVerifyCommand());
|
|
23667
24338
|
};
|
|
23668
24339
|
export {
|
|
23669
24340
|
CLI_VERSION,
|