clawdentity 0.0.5 → 0.0.6
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
CHANGED
|
@@ -20617,7 +20617,7 @@ async function persistRedeemConfig(registryUrl, apiKeyToken, dependencies = {})
|
|
|
20617
20617
|
}
|
|
20618
20618
|
var createInviteCommand = (dependencies = {}) => {
|
|
20619
20619
|
const inviteCommand = new Command6("invite").description(
|
|
20620
|
-
"Manage registry onboarding invites
|
|
20620
|
+
"Manage registry onboarding invites"
|
|
20621
20621
|
);
|
|
20622
20622
|
inviteCommand.command("create").description("Create a registry invite code (admin only)").option("--expires-at <timestamp>", "Optional invite expiry (ISO-8601)").option("--registry-url <url>", "Override registry URL").action(
|
|
20623
20623
|
withErrorHandling(
|
|
@@ -20660,6 +20660,7 @@ var createInviteCommand = (dependencies = {}) => {
|
|
|
20660
20660
|
dependencies
|
|
20661
20661
|
);
|
|
20662
20662
|
writeStdoutLine("API key saved to local config");
|
|
20663
|
+
writeStdoutLine("Onboarding auth complete");
|
|
20663
20664
|
}
|
|
20664
20665
|
)
|
|
20665
20666
|
);
|
|
@@ -20704,6 +20705,9 @@ var INVITE_CODE_PREFIX = "clawd1_";
|
|
|
20704
20705
|
var PEER_ALIAS_PATTERN = /^[a-zA-Z0-9._-]+$/;
|
|
20705
20706
|
var FILE_MODE3 = 384;
|
|
20706
20707
|
var OPENCLAW_HOOK_TOKEN_BYTES = 32;
|
|
20708
|
+
var OPENCLAW_SETUP_COMMAND_HINT = "Run: clawdentity openclaw setup <agentName> --peer-alias <alias> --peer-did <did> --peer-proxy-url <proxy-url>";
|
|
20709
|
+
var OPENCLAW_SETUP_RESTART_COMMAND_HINT = `${OPENCLAW_SETUP_COMMAND_HINT} and restart OpenClaw`;
|
|
20710
|
+
var OPENCLAW_SETUP_WITH_BASE_URL_HINT = `${OPENCLAW_SETUP_COMMAND_HINT} --openclaw-base-url <url>`;
|
|
20707
20711
|
var textEncoder2 = new TextEncoder();
|
|
20708
20712
|
var textDecoder = new TextDecoder();
|
|
20709
20713
|
function isRecord7(value) {
|
|
@@ -21006,10 +21010,6 @@ async function ensureLocalAgentCredentials(homeDir, agentName) {
|
|
|
21006
21010
|
}
|
|
21007
21011
|
}
|
|
21008
21012
|
}
|
|
21009
|
-
function encodeInvitePayload(payload) {
|
|
21010
|
-
const encoded = encodeBase64url(textEncoder2.encode(JSON.stringify(payload)));
|
|
21011
|
-
return `${INVITE_CODE_PREFIX}${encoded}`;
|
|
21012
|
-
}
|
|
21013
21013
|
function decodeInvitePayload(code) {
|
|
21014
21014
|
const rawCode = parseNonEmptyString7(code, "invite code");
|
|
21015
21015
|
if (!rawCode.startsWith(INVITE_CODE_PREFIX)) {
|
|
@@ -21512,7 +21512,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21512
21512
|
label: "Selected agent marker",
|
|
21513
21513
|
status: "fail",
|
|
21514
21514
|
message: missing ? `missing ${selectedAgentPath}` : "selected agent marker is invalid",
|
|
21515
|
-
remediationHint:
|
|
21515
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT
|
|
21516
21516
|
})
|
|
21517
21517
|
);
|
|
21518
21518
|
}
|
|
@@ -21523,7 +21523,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21523
21523
|
label: "Local agent credentials",
|
|
21524
21524
|
status: "fail",
|
|
21525
21525
|
message: "cannot validate credentials without selected agent marker",
|
|
21526
|
-
remediationHint:
|
|
21526
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT
|
|
21527
21527
|
})
|
|
21528
21528
|
);
|
|
21529
21529
|
} else {
|
|
@@ -21565,7 +21565,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21565
21565
|
label: "Peers map",
|
|
21566
21566
|
status: "fail",
|
|
21567
21567
|
message: `peer alias is missing: ${peerAlias}`,
|
|
21568
|
-
remediationHint:
|
|
21568
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
|
|
21569
21569
|
details: { peersPath, peerAlias }
|
|
21570
21570
|
})
|
|
21571
21571
|
);
|
|
@@ -21587,7 +21587,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21587
21587
|
label: "Peers map",
|
|
21588
21588
|
status: "fail",
|
|
21589
21589
|
message: "no peers are configured",
|
|
21590
|
-
remediationHint:
|
|
21590
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
|
|
21591
21591
|
details: { peersPath }
|
|
21592
21592
|
})
|
|
21593
21593
|
);
|
|
@@ -21690,7 +21690,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21690
21690
|
label: "OpenClaw hook mapping",
|
|
21691
21691
|
status: "fail",
|
|
21692
21692
|
message: `missing send-to-peer mapping in ${openclawConfigPath}`,
|
|
21693
|
-
remediationHint:
|
|
21693
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
|
|
21694
21694
|
details: { openclawConfigPath }
|
|
21695
21695
|
})
|
|
21696
21696
|
);
|
|
@@ -21712,7 +21712,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21712
21712
|
label: "OpenClaw hook auth",
|
|
21713
21713
|
status: "fail",
|
|
21714
21714
|
message: `hooks.enabled is not true in ${openclawConfigPath}`,
|
|
21715
|
-
remediationHint:
|
|
21715
|
+
remediationHint: OPENCLAW_SETUP_RESTART_COMMAND_HINT,
|
|
21716
21716
|
details: { openclawConfigPath }
|
|
21717
21717
|
})
|
|
21718
21718
|
);
|
|
@@ -21723,7 +21723,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21723
21723
|
label: "OpenClaw hook auth",
|
|
21724
21724
|
status: "fail",
|
|
21725
21725
|
message: `hooks.token is missing in ${openclawConfigPath}`,
|
|
21726
|
-
remediationHint:
|
|
21726
|
+
remediationHint: OPENCLAW_SETUP_RESTART_COMMAND_HINT,
|
|
21727
21727
|
details: { openclawConfigPath }
|
|
21728
21728
|
})
|
|
21729
21729
|
);
|
|
@@ -21780,7 +21780,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21780
21780
|
label: "OpenClaw base URL",
|
|
21781
21781
|
status: "fail",
|
|
21782
21782
|
message: `unable to resolve OpenClaw base URL from ${relayRuntimeConfigPath}`,
|
|
21783
|
-
remediationHint:
|
|
21783
|
+
remediationHint: OPENCLAW_SETUP_WITH_BASE_URL_HINT
|
|
21784
21784
|
})
|
|
21785
21785
|
);
|
|
21786
21786
|
}
|
|
@@ -21796,13 +21796,13 @@ function parseRelayProbeFailure(input) {
|
|
|
21796
21796
|
if (input.status === 404) {
|
|
21797
21797
|
return {
|
|
21798
21798
|
message: "OpenClaw send-to-peer hook is unavailable",
|
|
21799
|
-
remediationHint:
|
|
21799
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT
|
|
21800
21800
|
};
|
|
21801
21801
|
}
|
|
21802
21802
|
if (input.status === 405) {
|
|
21803
21803
|
return {
|
|
21804
21804
|
message: "OpenClaw send-to-peer hook is not enabled for POST requests",
|
|
21805
|
-
remediationHint:
|
|
21805
|
+
remediationHint: `${OPENCLAW_SETUP_COMMAND_HINT}, then restart OpenClaw`
|
|
21806
21806
|
};
|
|
21807
21807
|
}
|
|
21808
21808
|
if (input.status === 500) {
|
|
@@ -21929,29 +21929,38 @@ async function runOpenclawRelayTest(options) {
|
|
|
21929
21929
|
preflight
|
|
21930
21930
|
};
|
|
21931
21931
|
}
|
|
21932
|
-
function
|
|
21933
|
-
const
|
|
21934
|
-
const
|
|
21935
|
-
const
|
|
21936
|
-
const
|
|
21937
|
-
const
|
|
21938
|
-
|
|
21939
|
-
|
|
21940
|
-
|
|
21941
|
-
|
|
21942
|
-
|
|
21943
|
-
|
|
21944
|
-
|
|
21945
|
-
|
|
21946
|
-
|
|
21947
|
-
|
|
21948
|
-
|
|
21949
|
-
|
|
21950
|
-
|
|
21932
|
+
function resolveOpenclawSetupPeerInput(options) {
|
|
21933
|
+
const inviteCode = options.inviteCode?.trim();
|
|
21934
|
+
const invite = inviteCode !== void 0 && inviteCode.length > 0 ? decodeInvitePayload(inviteCode) : void 0;
|
|
21935
|
+
const peerAliasCandidate = options.peerAlias ?? invite?.alias;
|
|
21936
|
+
const peerDidCandidate = options.peerDid ?? invite?.did;
|
|
21937
|
+
const peerProxyUrlCandidate = options.peerProxyUrl ?? invite?.proxyUrl;
|
|
21938
|
+
const peerNameCandidate = options.peerName ?? invite?.name;
|
|
21939
|
+
const missingFields = [];
|
|
21940
|
+
if (peerAliasCandidate === void 0 || peerAliasCandidate.trim().length === 0) {
|
|
21941
|
+
missingFields.push("peerAlias");
|
|
21942
|
+
}
|
|
21943
|
+
if (peerDidCandidate === void 0 || peerDidCandidate.trim().length === 0) {
|
|
21944
|
+
missingFields.push("peerDid");
|
|
21945
|
+
}
|
|
21946
|
+
if (peerProxyUrlCandidate === void 0 || peerProxyUrlCandidate.trim().length === 0) {
|
|
21947
|
+
missingFields.push("peerProxyUrl");
|
|
21948
|
+
}
|
|
21949
|
+
if (missingFields.length > 0) {
|
|
21950
|
+
throw createCliError5(
|
|
21951
|
+
"CLI_OPENCLAW_PEER_INPUT_REQUIRED",
|
|
21952
|
+
"Peer routing details are required. Provide --peer-alias, --peer-did, and --peer-proxy-url.",
|
|
21953
|
+
{ missingFields }
|
|
21954
|
+
);
|
|
21955
|
+
}
|
|
21956
|
+
return {
|
|
21957
|
+
peerAlias: parsePeerAlias(peerAliasCandidate),
|
|
21958
|
+
peerDid: parseAgentDid2(peerDidCandidate, "peer DID"),
|
|
21959
|
+
peerProxyUrl: parseProxyUrl(peerProxyUrlCandidate),
|
|
21960
|
+
peerName: parseOptionalName(peerNameCandidate)
|
|
21951
21961
|
};
|
|
21952
|
-
return result;
|
|
21953
21962
|
}
|
|
21954
|
-
async function
|
|
21963
|
+
async function setupOpenclawRelay(agentName, options) {
|
|
21955
21964
|
const normalizedAgentName = assertValidAgentName(agentName);
|
|
21956
21965
|
const homeDir = resolveHomeDir(options.homeDir);
|
|
21957
21966
|
const openclawDir = resolveOpenclawDir(options.openclawDir, homeDir);
|
|
@@ -21966,15 +21975,7 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
21966
21975
|
optionValue: options.openclawBaseUrl,
|
|
21967
21976
|
relayRuntimeConfigPath
|
|
21968
21977
|
});
|
|
21969
|
-
const
|
|
21970
|
-
const peerAliasCandidate = options.peerAlias ?? invite.alias;
|
|
21971
|
-
if (!peerAliasCandidate) {
|
|
21972
|
-
throw createCliError5(
|
|
21973
|
-
"CLI_OPENCLAW_PEER_ALIAS_REQUIRED",
|
|
21974
|
-
"Peer alias is required. Include alias in invite code or pass --peer-alias."
|
|
21975
|
-
);
|
|
21976
|
-
}
|
|
21977
|
-
const peerAlias = parsePeerAlias(peerAliasCandidate);
|
|
21978
|
+
const peerInput = resolveOpenclawSetupPeerInput(options);
|
|
21978
21979
|
await ensureLocalAgentCredentials(homeDir, normalizedAgentName);
|
|
21979
21980
|
await mkdir5(dirname4(transformTargetPath), { recursive: true });
|
|
21980
21981
|
try {
|
|
@@ -21995,7 +21996,11 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
21995
21996
|
);
|
|
21996
21997
|
const peersPath = resolvePeersPath(homeDir);
|
|
21997
21998
|
const peers = await loadPeersConfig(peersPath);
|
|
21998
|
-
peers.peers[peerAlias] =
|
|
21999
|
+
peers.peers[peerInput.peerAlias] = peerInput.peerName === void 0 ? { did: peerInput.peerDid, proxyUrl: peerInput.peerProxyUrl } : {
|
|
22000
|
+
did: peerInput.peerDid,
|
|
22001
|
+
proxyUrl: peerInput.peerProxyUrl,
|
|
22002
|
+
name: peerInput.peerName
|
|
22003
|
+
};
|
|
21999
22004
|
await savePeersConfig(peersPath, peers);
|
|
22000
22005
|
const relayTransformPeersPath = resolveTransformPeersPath(openclawDir);
|
|
22001
22006
|
await writeSecureFile3(
|
|
@@ -22050,8 +22055,9 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
22050
22055
|
);
|
|
22051
22056
|
logger8.info("cli.openclaw_setup_completed", {
|
|
22052
22057
|
agentName: normalizedAgentName,
|
|
22053
|
-
peerAlias,
|
|
22054
|
-
peerDid:
|
|
22058
|
+
peerAlias: peerInput.peerAlias,
|
|
22059
|
+
peerDid: peerInput.peerDid,
|
|
22060
|
+
peerProxyUrl: peerInput.peerProxyUrl,
|
|
22055
22061
|
openclawConfigPath,
|
|
22056
22062
|
transformTargetPath,
|
|
22057
22063
|
relayTransformRuntimePath,
|
|
@@ -22061,9 +22067,9 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
22061
22067
|
relayRuntimeConfigPath
|
|
22062
22068
|
});
|
|
22063
22069
|
return {
|
|
22064
|
-
peerAlias,
|
|
22065
|
-
peerDid:
|
|
22066
|
-
peerProxyUrl:
|
|
22070
|
+
peerAlias: peerInput.peerAlias,
|
|
22071
|
+
peerDid: peerInput.peerDid,
|
|
22072
|
+
peerProxyUrl: peerInput.peerProxyUrl,
|
|
22067
22073
|
openclawConfigPath,
|
|
22068
22074
|
transformTargetPath,
|
|
22069
22075
|
relayTransformRuntimePath,
|
|
@@ -22075,29 +22081,12 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
22075
22081
|
}
|
|
22076
22082
|
var createOpenclawCommand = () => {
|
|
22077
22083
|
const openclawCommand = new Command7("openclaw").description(
|
|
22078
|
-
"Manage OpenClaw
|
|
22079
|
-
);
|
|
22080
|
-
openclawCommand.command("invite").description("Create an invite code for peer relay onboarding").requiredOption("--did <did>", "Peer agent DID (did:claw:agent:...)").requiredOption(
|
|
22081
|
-
"--proxy-url <url>",
|
|
22082
|
-
"Public proxy URL ending in /hooks/agent"
|
|
22083
|
-
).option("--peer-alias <alias>", "Suggested peer alias for the receiver").option("--name <displayName>", "Human-friendly peer display name").action(
|
|
22084
|
-
withErrorHandling(
|
|
22085
|
-
"openclaw invite",
|
|
22086
|
-
async (options) => {
|
|
22087
|
-
const invite = createOpenclawInviteCode(options);
|
|
22088
|
-
writeStdoutLine(`Invite code: ${invite.code}`);
|
|
22089
|
-
writeStdoutLine(`Agent DID: ${invite.did}`);
|
|
22090
|
-
writeStdoutLine(`Proxy URL: ${invite.proxyUrl}`);
|
|
22091
|
-
if (invite.peerAlias) {
|
|
22092
|
-
writeStdoutLine(`Suggested Alias: ${invite.peerAlias}`);
|
|
22093
|
-
}
|
|
22094
|
-
}
|
|
22095
|
-
)
|
|
22084
|
+
"Manage OpenClaw relay setup"
|
|
22096
22085
|
);
|
|
22097
|
-
openclawCommand.command("setup <agentName>").description("Apply OpenClaw relay setup using
|
|
22098
|
-
"--
|
|
22099
|
-
"
|
|
22100
|
-
).option("--peer-
|
|
22086
|
+
openclawCommand.command("setup <agentName>").description("Apply OpenClaw relay setup using peer routing details").requiredOption("--peer-alias <alias>", "Peer alias for local routing").requiredOption("--peer-did <did>", "Peer agent DID (did:claw:agent:...)").requiredOption(
|
|
22087
|
+
"--peer-proxy-url <url>",
|
|
22088
|
+
"Peer proxy URL ending in /hooks/agent"
|
|
22089
|
+
).option("--peer-name <displayName>", "Human-friendly peer display name").option(
|
|
22101
22090
|
"--openclaw-dir <path>",
|
|
22102
22091
|
"OpenClaw state directory (default ~/.openclaw)"
|
|
22103
22092
|
).option(
|
|
@@ -22110,7 +22099,7 @@ var createOpenclawCommand = () => {
|
|
|
22110
22099
|
withErrorHandling(
|
|
22111
22100
|
"openclaw setup",
|
|
22112
22101
|
async (agentName, options) => {
|
|
22113
|
-
const result = await
|
|
22102
|
+
const result = await setupOpenclawRelay(agentName, options);
|
|
22114
22103
|
writeStdoutLine(`Peer alias configured: ${result.peerAlias}`);
|
|
22115
22104
|
writeStdoutLine(`Peer DID: ${result.peerDid}`);
|
|
22116
22105
|
writeStdoutLine(`Peer proxy URL: ${result.peerProxyUrl}`);
|
package/dist/index.js
CHANGED
|
@@ -20617,7 +20617,7 @@ async function persistRedeemConfig(registryUrl, apiKeyToken, dependencies = {})
|
|
|
20617
20617
|
}
|
|
20618
20618
|
var createInviteCommand = (dependencies = {}) => {
|
|
20619
20619
|
const inviteCommand = new Command6("invite").description(
|
|
20620
|
-
"Manage registry onboarding invites
|
|
20620
|
+
"Manage registry onboarding invites"
|
|
20621
20621
|
);
|
|
20622
20622
|
inviteCommand.command("create").description("Create a registry invite code (admin only)").option("--expires-at <timestamp>", "Optional invite expiry (ISO-8601)").option("--registry-url <url>", "Override registry URL").action(
|
|
20623
20623
|
withErrorHandling(
|
|
@@ -20660,6 +20660,7 @@ var createInviteCommand = (dependencies = {}) => {
|
|
|
20660
20660
|
dependencies
|
|
20661
20661
|
);
|
|
20662
20662
|
writeStdoutLine("API key saved to local config");
|
|
20663
|
+
writeStdoutLine("Onboarding auth complete");
|
|
20663
20664
|
}
|
|
20664
20665
|
)
|
|
20665
20666
|
);
|
|
@@ -20704,6 +20705,9 @@ var INVITE_CODE_PREFIX = "clawd1_";
|
|
|
20704
20705
|
var PEER_ALIAS_PATTERN = /^[a-zA-Z0-9._-]+$/;
|
|
20705
20706
|
var FILE_MODE3 = 384;
|
|
20706
20707
|
var OPENCLAW_HOOK_TOKEN_BYTES = 32;
|
|
20708
|
+
var OPENCLAW_SETUP_COMMAND_HINT = "Run: clawdentity openclaw setup <agentName> --peer-alias <alias> --peer-did <did> --peer-proxy-url <proxy-url>";
|
|
20709
|
+
var OPENCLAW_SETUP_RESTART_COMMAND_HINT = `${OPENCLAW_SETUP_COMMAND_HINT} and restart OpenClaw`;
|
|
20710
|
+
var OPENCLAW_SETUP_WITH_BASE_URL_HINT = `${OPENCLAW_SETUP_COMMAND_HINT} --openclaw-base-url <url>`;
|
|
20707
20711
|
var textEncoder2 = new TextEncoder();
|
|
20708
20712
|
var textDecoder = new TextDecoder();
|
|
20709
20713
|
function isRecord7(value) {
|
|
@@ -21006,10 +21010,6 @@ async function ensureLocalAgentCredentials(homeDir, agentName) {
|
|
|
21006
21010
|
}
|
|
21007
21011
|
}
|
|
21008
21012
|
}
|
|
21009
|
-
function encodeInvitePayload(payload) {
|
|
21010
|
-
const encoded = encodeBase64url(textEncoder2.encode(JSON.stringify(payload)));
|
|
21011
|
-
return `${INVITE_CODE_PREFIX}${encoded}`;
|
|
21012
|
-
}
|
|
21013
21013
|
function decodeInvitePayload(code) {
|
|
21014
21014
|
const rawCode = parseNonEmptyString7(code, "invite code");
|
|
21015
21015
|
if (!rawCode.startsWith(INVITE_CODE_PREFIX)) {
|
|
@@ -21512,7 +21512,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21512
21512
|
label: "Selected agent marker",
|
|
21513
21513
|
status: "fail",
|
|
21514
21514
|
message: missing ? `missing ${selectedAgentPath}` : "selected agent marker is invalid",
|
|
21515
|
-
remediationHint:
|
|
21515
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT
|
|
21516
21516
|
})
|
|
21517
21517
|
);
|
|
21518
21518
|
}
|
|
@@ -21523,7 +21523,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21523
21523
|
label: "Local agent credentials",
|
|
21524
21524
|
status: "fail",
|
|
21525
21525
|
message: "cannot validate credentials without selected agent marker",
|
|
21526
|
-
remediationHint:
|
|
21526
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT
|
|
21527
21527
|
})
|
|
21528
21528
|
);
|
|
21529
21529
|
} else {
|
|
@@ -21565,7 +21565,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21565
21565
|
label: "Peers map",
|
|
21566
21566
|
status: "fail",
|
|
21567
21567
|
message: `peer alias is missing: ${peerAlias}`,
|
|
21568
|
-
remediationHint:
|
|
21568
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
|
|
21569
21569
|
details: { peersPath, peerAlias }
|
|
21570
21570
|
})
|
|
21571
21571
|
);
|
|
@@ -21587,7 +21587,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21587
21587
|
label: "Peers map",
|
|
21588
21588
|
status: "fail",
|
|
21589
21589
|
message: "no peers are configured",
|
|
21590
|
-
remediationHint:
|
|
21590
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
|
|
21591
21591
|
details: { peersPath }
|
|
21592
21592
|
})
|
|
21593
21593
|
);
|
|
@@ -21690,7 +21690,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21690
21690
|
label: "OpenClaw hook mapping",
|
|
21691
21691
|
status: "fail",
|
|
21692
21692
|
message: `missing send-to-peer mapping in ${openclawConfigPath}`,
|
|
21693
|
-
remediationHint:
|
|
21693
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
|
|
21694
21694
|
details: { openclawConfigPath }
|
|
21695
21695
|
})
|
|
21696
21696
|
);
|
|
@@ -21712,7 +21712,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21712
21712
|
label: "OpenClaw hook auth",
|
|
21713
21713
|
status: "fail",
|
|
21714
21714
|
message: `hooks.enabled is not true in ${openclawConfigPath}`,
|
|
21715
|
-
remediationHint:
|
|
21715
|
+
remediationHint: OPENCLAW_SETUP_RESTART_COMMAND_HINT,
|
|
21716
21716
|
details: { openclawConfigPath }
|
|
21717
21717
|
})
|
|
21718
21718
|
);
|
|
@@ -21723,7 +21723,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21723
21723
|
label: "OpenClaw hook auth",
|
|
21724
21724
|
status: "fail",
|
|
21725
21725
|
message: `hooks.token is missing in ${openclawConfigPath}`,
|
|
21726
|
-
remediationHint:
|
|
21726
|
+
remediationHint: OPENCLAW_SETUP_RESTART_COMMAND_HINT,
|
|
21727
21727
|
details: { openclawConfigPath }
|
|
21728
21728
|
})
|
|
21729
21729
|
);
|
|
@@ -21780,7 +21780,7 @@ async function runOpenclawDoctor(options = {}) {
|
|
|
21780
21780
|
label: "OpenClaw base URL",
|
|
21781
21781
|
status: "fail",
|
|
21782
21782
|
message: `unable to resolve OpenClaw base URL from ${relayRuntimeConfigPath}`,
|
|
21783
|
-
remediationHint:
|
|
21783
|
+
remediationHint: OPENCLAW_SETUP_WITH_BASE_URL_HINT
|
|
21784
21784
|
})
|
|
21785
21785
|
);
|
|
21786
21786
|
}
|
|
@@ -21796,13 +21796,13 @@ function parseRelayProbeFailure(input) {
|
|
|
21796
21796
|
if (input.status === 404) {
|
|
21797
21797
|
return {
|
|
21798
21798
|
message: "OpenClaw send-to-peer hook is unavailable",
|
|
21799
|
-
remediationHint:
|
|
21799
|
+
remediationHint: OPENCLAW_SETUP_COMMAND_HINT
|
|
21800
21800
|
};
|
|
21801
21801
|
}
|
|
21802
21802
|
if (input.status === 405) {
|
|
21803
21803
|
return {
|
|
21804
21804
|
message: "OpenClaw send-to-peer hook is not enabled for POST requests",
|
|
21805
|
-
remediationHint:
|
|
21805
|
+
remediationHint: `${OPENCLAW_SETUP_COMMAND_HINT}, then restart OpenClaw`
|
|
21806
21806
|
};
|
|
21807
21807
|
}
|
|
21808
21808
|
if (input.status === 500) {
|
|
@@ -21929,29 +21929,38 @@ async function runOpenclawRelayTest(options) {
|
|
|
21929
21929
|
preflight
|
|
21930
21930
|
};
|
|
21931
21931
|
}
|
|
21932
|
-
function
|
|
21933
|
-
const
|
|
21934
|
-
const
|
|
21935
|
-
const
|
|
21936
|
-
const
|
|
21937
|
-
const
|
|
21938
|
-
|
|
21939
|
-
|
|
21940
|
-
|
|
21941
|
-
|
|
21942
|
-
|
|
21943
|
-
|
|
21944
|
-
|
|
21945
|
-
|
|
21946
|
-
|
|
21947
|
-
|
|
21948
|
-
|
|
21949
|
-
|
|
21950
|
-
|
|
21932
|
+
function resolveOpenclawSetupPeerInput(options) {
|
|
21933
|
+
const inviteCode = options.inviteCode?.trim();
|
|
21934
|
+
const invite = inviteCode !== void 0 && inviteCode.length > 0 ? decodeInvitePayload(inviteCode) : void 0;
|
|
21935
|
+
const peerAliasCandidate = options.peerAlias ?? invite?.alias;
|
|
21936
|
+
const peerDidCandidate = options.peerDid ?? invite?.did;
|
|
21937
|
+
const peerProxyUrlCandidate = options.peerProxyUrl ?? invite?.proxyUrl;
|
|
21938
|
+
const peerNameCandidate = options.peerName ?? invite?.name;
|
|
21939
|
+
const missingFields = [];
|
|
21940
|
+
if (peerAliasCandidate === void 0 || peerAliasCandidate.trim().length === 0) {
|
|
21941
|
+
missingFields.push("peerAlias");
|
|
21942
|
+
}
|
|
21943
|
+
if (peerDidCandidate === void 0 || peerDidCandidate.trim().length === 0) {
|
|
21944
|
+
missingFields.push("peerDid");
|
|
21945
|
+
}
|
|
21946
|
+
if (peerProxyUrlCandidate === void 0 || peerProxyUrlCandidate.trim().length === 0) {
|
|
21947
|
+
missingFields.push("peerProxyUrl");
|
|
21948
|
+
}
|
|
21949
|
+
if (missingFields.length > 0) {
|
|
21950
|
+
throw createCliError5(
|
|
21951
|
+
"CLI_OPENCLAW_PEER_INPUT_REQUIRED",
|
|
21952
|
+
"Peer routing details are required. Provide --peer-alias, --peer-did, and --peer-proxy-url.",
|
|
21953
|
+
{ missingFields }
|
|
21954
|
+
);
|
|
21955
|
+
}
|
|
21956
|
+
return {
|
|
21957
|
+
peerAlias: parsePeerAlias(peerAliasCandidate),
|
|
21958
|
+
peerDid: parseAgentDid2(peerDidCandidate, "peer DID"),
|
|
21959
|
+
peerProxyUrl: parseProxyUrl(peerProxyUrlCandidate),
|
|
21960
|
+
peerName: parseOptionalName(peerNameCandidate)
|
|
21951
21961
|
};
|
|
21952
|
-
return result;
|
|
21953
21962
|
}
|
|
21954
|
-
async function
|
|
21963
|
+
async function setupOpenclawRelay(agentName, options) {
|
|
21955
21964
|
const normalizedAgentName = assertValidAgentName(agentName);
|
|
21956
21965
|
const homeDir = resolveHomeDir(options.homeDir);
|
|
21957
21966
|
const openclawDir = resolveOpenclawDir(options.openclawDir, homeDir);
|
|
@@ -21966,15 +21975,7 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
21966
21975
|
optionValue: options.openclawBaseUrl,
|
|
21967
21976
|
relayRuntimeConfigPath
|
|
21968
21977
|
});
|
|
21969
|
-
const
|
|
21970
|
-
const peerAliasCandidate = options.peerAlias ?? invite.alias;
|
|
21971
|
-
if (!peerAliasCandidate) {
|
|
21972
|
-
throw createCliError5(
|
|
21973
|
-
"CLI_OPENCLAW_PEER_ALIAS_REQUIRED",
|
|
21974
|
-
"Peer alias is required. Include alias in invite code or pass --peer-alias."
|
|
21975
|
-
);
|
|
21976
|
-
}
|
|
21977
|
-
const peerAlias = parsePeerAlias(peerAliasCandidate);
|
|
21978
|
+
const peerInput = resolveOpenclawSetupPeerInput(options);
|
|
21978
21979
|
await ensureLocalAgentCredentials(homeDir, normalizedAgentName);
|
|
21979
21980
|
await mkdir5(dirname4(transformTargetPath), { recursive: true });
|
|
21980
21981
|
try {
|
|
@@ -21995,7 +21996,11 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
21995
21996
|
);
|
|
21996
21997
|
const peersPath = resolvePeersPath(homeDir);
|
|
21997
21998
|
const peers = await loadPeersConfig(peersPath);
|
|
21998
|
-
peers.peers[peerAlias] =
|
|
21999
|
+
peers.peers[peerInput.peerAlias] = peerInput.peerName === void 0 ? { did: peerInput.peerDid, proxyUrl: peerInput.peerProxyUrl } : {
|
|
22000
|
+
did: peerInput.peerDid,
|
|
22001
|
+
proxyUrl: peerInput.peerProxyUrl,
|
|
22002
|
+
name: peerInput.peerName
|
|
22003
|
+
};
|
|
21999
22004
|
await savePeersConfig(peersPath, peers);
|
|
22000
22005
|
const relayTransformPeersPath = resolveTransformPeersPath(openclawDir);
|
|
22001
22006
|
await writeSecureFile3(
|
|
@@ -22050,8 +22055,9 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
22050
22055
|
);
|
|
22051
22056
|
logger8.info("cli.openclaw_setup_completed", {
|
|
22052
22057
|
agentName: normalizedAgentName,
|
|
22053
|
-
peerAlias,
|
|
22054
|
-
peerDid:
|
|
22058
|
+
peerAlias: peerInput.peerAlias,
|
|
22059
|
+
peerDid: peerInput.peerDid,
|
|
22060
|
+
peerProxyUrl: peerInput.peerProxyUrl,
|
|
22055
22061
|
openclawConfigPath,
|
|
22056
22062
|
transformTargetPath,
|
|
22057
22063
|
relayTransformRuntimePath,
|
|
@@ -22061,9 +22067,9 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
22061
22067
|
relayRuntimeConfigPath
|
|
22062
22068
|
});
|
|
22063
22069
|
return {
|
|
22064
|
-
peerAlias,
|
|
22065
|
-
peerDid:
|
|
22066
|
-
peerProxyUrl:
|
|
22070
|
+
peerAlias: peerInput.peerAlias,
|
|
22071
|
+
peerDid: peerInput.peerDid,
|
|
22072
|
+
peerProxyUrl: peerInput.peerProxyUrl,
|
|
22067
22073
|
openclawConfigPath,
|
|
22068
22074
|
transformTargetPath,
|
|
22069
22075
|
relayTransformRuntimePath,
|
|
@@ -22075,29 +22081,12 @@ async function setupOpenclawRelayFromInvite(agentName, options) {
|
|
|
22075
22081
|
}
|
|
22076
22082
|
var createOpenclawCommand = () => {
|
|
22077
22083
|
const openclawCommand = new Command7("openclaw").description(
|
|
22078
|
-
"Manage OpenClaw
|
|
22079
|
-
);
|
|
22080
|
-
openclawCommand.command("invite").description("Create an invite code for peer relay onboarding").requiredOption("--did <did>", "Peer agent DID (did:claw:agent:...)").requiredOption(
|
|
22081
|
-
"--proxy-url <url>",
|
|
22082
|
-
"Public proxy URL ending in /hooks/agent"
|
|
22083
|
-
).option("--peer-alias <alias>", "Suggested peer alias for the receiver").option("--name <displayName>", "Human-friendly peer display name").action(
|
|
22084
|
-
withErrorHandling(
|
|
22085
|
-
"openclaw invite",
|
|
22086
|
-
async (options) => {
|
|
22087
|
-
const invite = createOpenclawInviteCode(options);
|
|
22088
|
-
writeStdoutLine(`Invite code: ${invite.code}`);
|
|
22089
|
-
writeStdoutLine(`Agent DID: ${invite.did}`);
|
|
22090
|
-
writeStdoutLine(`Proxy URL: ${invite.proxyUrl}`);
|
|
22091
|
-
if (invite.peerAlias) {
|
|
22092
|
-
writeStdoutLine(`Suggested Alias: ${invite.peerAlias}`);
|
|
22093
|
-
}
|
|
22094
|
-
}
|
|
22095
|
-
)
|
|
22084
|
+
"Manage OpenClaw relay setup"
|
|
22096
22085
|
);
|
|
22097
|
-
openclawCommand.command("setup <agentName>").description("Apply OpenClaw relay setup using
|
|
22098
|
-
"--
|
|
22099
|
-
"
|
|
22100
|
-
).option("--peer-
|
|
22086
|
+
openclawCommand.command("setup <agentName>").description("Apply OpenClaw relay setup using peer routing details").requiredOption("--peer-alias <alias>", "Peer alias for local routing").requiredOption("--peer-did <did>", "Peer agent DID (did:claw:agent:...)").requiredOption(
|
|
22087
|
+
"--peer-proxy-url <url>",
|
|
22088
|
+
"Peer proxy URL ending in /hooks/agent"
|
|
22089
|
+
).option("--peer-name <displayName>", "Human-friendly peer display name").option(
|
|
22101
22090
|
"--openclaw-dir <path>",
|
|
22102
22091
|
"OpenClaw state directory (default ~/.openclaw)"
|
|
22103
22092
|
).option(
|
|
@@ -22110,7 +22099,7 @@ var createOpenclawCommand = () => {
|
|
|
22110
22099
|
withErrorHandling(
|
|
22111
22100
|
"openclaw setup",
|
|
22112
22101
|
async (agentName, options) => {
|
|
22113
|
-
const result = await
|
|
22102
|
+
const result = await setupOpenclawRelay(agentName, options);
|
|
22114
22103
|
writeStdoutLine(`Peer alias configured: ${result.peerAlias}`);
|
|
22115
22104
|
writeStdoutLine(`Peer DID: ${result.peerDid}`);
|
|
22116
22105
|
writeStdoutLine(`Peer proxy URL: ${result.peerProxyUrl}`);
|
package/dist/postinstall.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawdentity",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -21,17 +21,6 @@
|
|
|
21
21
|
"postinstall.mjs",
|
|
22
22
|
"skill-bundle"
|
|
23
23
|
],
|
|
24
|
-
"scripts": {
|
|
25
|
-
"build": "pnpm -F @clawdentity/openclaw-skill build && pnpm run sync:skill-bundle && pnpm run verify:skill-bundle && tsup",
|
|
26
|
-
"format": "biome format .",
|
|
27
|
-
"lint": "biome lint .",
|
|
28
|
-
"prepack": "pnpm run build",
|
|
29
|
-
"postinstall": "node ./postinstall.mjs",
|
|
30
|
-
"sync:skill-bundle": "node ./scripts/sync-skill-bundle.mjs",
|
|
31
|
-
"verify:skill-bundle": "node ./scripts/verify-skill-bundle.mjs",
|
|
32
|
-
"test": "vitest run",
|
|
33
|
-
"typecheck": "tsc --noEmit"
|
|
34
|
-
},
|
|
35
24
|
"dependencies": {
|
|
36
25
|
"commander": "^13.1.0",
|
|
37
26
|
"jsqr": "^1.4.0",
|
|
@@ -40,11 +29,21 @@
|
|
|
40
29
|
"ws": "^8.19.0"
|
|
41
30
|
},
|
|
42
31
|
"devDependencies": {
|
|
43
|
-
"@clawdentity/connector": "workspace:*",
|
|
44
|
-
"@clawdentity/protocol": "workspace:*",
|
|
45
|
-
"@clawdentity/sdk": "workspace:*",
|
|
46
32
|
"@types/node": "^22.18.11",
|
|
47
33
|
"@types/pngjs": "^6.0.5",
|
|
48
|
-
"@types/qrcode": "^1.5.6"
|
|
34
|
+
"@types/qrcode": "^1.5.6",
|
|
35
|
+
"@clawdentity/protocol": "0.0.0",
|
|
36
|
+
"@clawdentity/connector": "0.0.0",
|
|
37
|
+
"@clawdentity/sdk": "0.0.0"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "pnpm -F @clawdentity/openclaw-skill build && pnpm run sync:skill-bundle && pnpm run verify:skill-bundle && tsup",
|
|
41
|
+
"format": "biome format .",
|
|
42
|
+
"lint": "biome lint .",
|
|
43
|
+
"postinstall": "node ./postinstall.mjs",
|
|
44
|
+
"sync:skill-bundle": "node ./scripts/sync-skill-bundle.mjs",
|
|
45
|
+
"verify:skill-bundle": "node ./scripts/verify-skill-bundle.mjs",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"typecheck": "tsc --noEmit"
|
|
49
48
|
}
|
|
50
|
-
}
|
|
49
|
+
}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clawdentity_openclaw_relay
|
|
3
|
-
description: This skill should be used when the user asks to
|
|
4
|
-
version: 0.
|
|
3
|
+
description: This skill should be used when the user asks to install or configure Clawdentity relay for OpenClaw agents and prepare them for pairing and message delivery.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Clawdentity OpenClaw Relay Skill
|
|
8
8
|
|
|
9
|
-
This skill
|
|
9
|
+
This skill prepares a local OpenClaw agent in a strict sequence:
|
|
10
|
+
1. finish registry onboarding and generate/store API key
|
|
11
|
+
2. create local agent identity
|
|
12
|
+
3. configure relay runtime
|
|
13
|
+
4. become ready to start or accept pairing
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Use this skill when any of the following are requested:
|
|
14
|
-
- Install relay support for OpenClaw peer communication.
|
|
15
|
-
- Complete first-time setup from an invite code.
|
|
16
|
-
- Repair broken relay setup after config drift.
|
|
17
|
-
- Verify invite-code onboarding and peer mapping.
|
|
15
|
+
Relay invite codes are not part of this flow.
|
|
18
16
|
|
|
19
17
|
## Filesystem Truth (must be used exactly)
|
|
20
18
|
|
|
@@ -23,7 +21,7 @@ Use this skill when any of the following are requested:
|
|
|
23
21
|
- OpenClaw config: `<resolved-openclaw-state>/openclaw.json` (legacy names may exist: `clawdbot.json`, `moldbot.json`, `moltbot.json`)
|
|
24
22
|
- OpenClaw config env overrides: `OPENCLAW_CONFIG_PATH`, legacy `CLAWDBOT_CONFIG_PATH`
|
|
25
23
|
- OpenClaw state env overrides: `OPENCLAW_STATE_DIR`, legacy `CLAWDBOT_STATE_DIR`
|
|
26
|
-
- OpenClaw home override
|
|
24
|
+
- OpenClaw home override: `OPENCLAW_HOME`
|
|
27
25
|
- Transform target path: `~/.openclaw/hooks/transforms/relay-to-peer.mjs`
|
|
28
26
|
- Transform runtime snapshot: `~/.openclaw/hooks/transforms/clawdentity-relay.json`
|
|
29
27
|
- Transform peers snapshot: `~/.openclaw/hooks/transforms/clawdentity-peers.json`
|
|
@@ -42,166 +40,123 @@ Use this skill when any of the following are requested:
|
|
|
42
40
|
- Relay runtime config: `~/.clawdentity/openclaw-relay.json`
|
|
43
41
|
- Connector assignment map: `~/.clawdentity/openclaw-connectors.json`
|
|
44
42
|
|
|
45
|
-
##
|
|
43
|
+
## Inputs
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
- Registry onboarding invite code
|
|
49
|
-
-
|
|
45
|
+
Required for onboarding:
|
|
46
|
+
- Registry onboarding invite code: `clw_inv_...` (or existing local API key)
|
|
47
|
+
- Local agent name
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
Required for relay setup (after onboarding + agent create):
|
|
50
|
+
- Peer alias
|
|
51
|
+
- Peer DID
|
|
52
|
+
- Peer proxy URL (`.../hooks/agent`)
|
|
53
|
+
- Optional peer display name
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
Required for pairing phase (after setup):
|
|
56
|
+
- Initiator proxy URL
|
|
57
|
+
- Responder proxy URL
|
|
54
58
|
|
|
55
59
|
## Tool Execution Contract (Agent)
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- Start connector runtime for relay handoff:
|
|
85
|
-
- `clawdentity connector start <agent-name>`
|
|
86
|
-
- Optional persistent connector autostart:
|
|
87
|
-
- `clawdentity connector service install <agent-name>`
|
|
88
|
-
- Validate health and delivery:
|
|
89
|
-
- `clawdentity openclaw doctor`
|
|
90
|
-
- `clawdentity openclaw relay test --peer <alias>`
|
|
91
|
-
|
|
92
|
-
Pairing bootstrap uses CLI commands in the current release:
|
|
93
|
-
|
|
94
|
-
- Owner/initiator starts pairing on initiator proxy:
|
|
95
|
-
- `clawdentity pair start <initiator-agent-name> --proxy-url <initiator-proxy-url> --qr`
|
|
96
|
-
- Optionally pass explicit owner PAT: `--owner-pat <token>`
|
|
97
|
-
- Responder confirms on responder proxy:
|
|
98
|
-
- `clawdentity pair confirm <responder-agent-name> --qr-file <ticket-qr-file> --proxy-url <responder-proxy-url>`
|
|
99
|
-
- optional global proxy URL env fallback: `CLAWDENTITY_PROXY_URL=<proxy-url>`
|
|
100
|
-
|
|
101
|
-
Successful confirm establishes mutual trust for the two agent DIDs. After confirm, both directions are allowed for trusted delivery.
|
|
102
|
-
|
|
103
|
-
1. Confirm prerequisites with the human.
|
|
104
|
-
- Confirm `clawdentity` CLI is installed and runnable.
|
|
61
|
+
- Execute side effects directly with tools/CLI.
|
|
62
|
+
- Do not ask humans to run commands that the agent can run.
|
|
63
|
+
- Ask humans only for missing secrets or missing peer/proxy inputs.
|
|
64
|
+
- Keep status output concrete: created agent DID, generated API key status, written files.
|
|
65
|
+
|
|
66
|
+
## Command Utilization (required)
|
|
67
|
+
|
|
68
|
+
- `clawdentity config init`
|
|
69
|
+
- `clawdentity config init --registry-url <registry-url>`
|
|
70
|
+
- `clawdentity config set registryUrl <registry-url>`
|
|
71
|
+
- `clawdentity invite redeem <registry-invite-code>`
|
|
72
|
+
- `clawdentity invite redeem <registry-invite-code> --registry-url <registry-url>`
|
|
73
|
+
- `clawdentity config set apiKey <api-key>` (fallback only when invite is unavailable)
|
|
74
|
+
- `clawdentity agent create <agent-name> --framework openclaw`
|
|
75
|
+
- `clawdentity agent inspect <agent-name>`
|
|
76
|
+
- `clawdentity openclaw setup <agent-name> --peer-alias <alias> --peer-did <did> --peer-proxy-url <url>`
|
|
77
|
+
- `clawdentity connector start <agent-name>`
|
|
78
|
+
- `clawdentity connector service install <agent-name>` (optional)
|
|
79
|
+
- `clawdentity openclaw doctor`
|
|
80
|
+
- `clawdentity openclaw relay test --peer <alias>`
|
|
81
|
+
- `clawdentity pair start <agent-name> --proxy-url <initiator-proxy-url> --qr`
|
|
82
|
+
- `clawdentity pair confirm <agent-name> --qr-file <path> --proxy-url <responder-proxy-url>`
|
|
83
|
+
|
|
84
|
+
## Journey (strict order)
|
|
85
|
+
|
|
86
|
+
1. Validate prerequisites.
|
|
87
|
+
- Confirm CLI is installed.
|
|
105
88
|
- Confirm local agent name.
|
|
106
|
-
- Confirm API key
|
|
107
|
-
- Confirm OpenClaw
|
|
108
|
-
- Do not
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
2. Confirm skill artifact exists in workspace skills directory.
|
|
116
|
-
- Ensure `~/.openclaw/workspace/skills/clawdentity-openclaw-relay/relay-to-peer.mjs` exists.
|
|
117
|
-
- If missing, install/update skill package contents before setup.
|
|
118
|
-
|
|
119
|
-
3. Initialize local Clawdentity config.
|
|
89
|
+
- Confirm either existing API key or `clw_inv_...`.
|
|
90
|
+
- Confirm OpenClaw path/base URL only if non-default.
|
|
91
|
+
- Do not ask for pairing inputs before onboarding is complete.
|
|
92
|
+
|
|
93
|
+
2. Ensure skill artifact exists.
|
|
94
|
+
- Ensure `relay-to-peer.mjs` exists in workspace skill path.
|
|
95
|
+
- If missing, install/update skill package contents first.
|
|
96
|
+
|
|
97
|
+
3. Initialize local CLI config.
|
|
120
98
|
- Run `clawdentity config init`.
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
4.
|
|
124
|
-
- If API key already exists, continue.
|
|
125
|
-
- Else
|
|
126
|
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
5.
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
6.
|
|
137
|
-
-
|
|
138
|
-
`clawdentity openclaw setup <agent-name> --
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
7. Verify setup outputs.
|
|
148
|
-
- Confirm setup reports:
|
|
149
|
-
- peer alias
|
|
150
|
-
- peer DID
|
|
151
|
-
- updated OpenClaw config path
|
|
152
|
-
- installed transform path
|
|
153
|
-
- OpenClaw base URL
|
|
154
|
-
- relay runtime config path
|
|
155
|
-
- Confirm `~/.clawdentity/openclaw-agent-name` is set to the local agent name.
|
|
156
|
-
|
|
157
|
-
8. Start connector runtime for local relay handoff.
|
|
99
|
+
- If needed, run with `--registry-url`.
|
|
100
|
+
|
|
101
|
+
4. Finish onboarding and generate API key.
|
|
102
|
+
- If API key already exists locally, continue.
|
|
103
|
+
- Else run `clawdentity invite redeem <clw_inv_...>`.
|
|
104
|
+
- Confirm output shows:
|
|
105
|
+
- `Invite redeemed`
|
|
106
|
+
- API key token printed once
|
|
107
|
+
- `API key saved to local config`
|
|
108
|
+
- Stop and fix if this step fails. Do not proceed to pairing.
|
|
109
|
+
|
|
110
|
+
5. Create local OpenClaw agent identity.
|
|
111
|
+
- Run `clawdentity agent create <agent-name> --framework openclaw`.
|
|
112
|
+
- Run `clawdentity agent inspect <agent-name>`.
|
|
113
|
+
|
|
114
|
+
6. Configure relay setup.
|
|
115
|
+
- Run:
|
|
116
|
+
`clawdentity openclaw setup <agent-name> --peer-alias <alias> --peer-did <did> --peer-proxy-url <url>`
|
|
117
|
+
- Add optional:
|
|
118
|
+
- `--peer-name <displayName>`
|
|
119
|
+
- `--openclaw-dir <path>`
|
|
120
|
+
- `--openclaw-base-url <url>`
|
|
121
|
+
- Verify output contains peer alias, peer DID, peer proxy URL, OpenClaw config path, and relay runtime path.
|
|
122
|
+
|
|
123
|
+
7. Start connector runtime.
|
|
158
124
|
- Run `clawdentity connector start <agent-name>`.
|
|
159
|
-
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-
|
|
168
|
-
|
|
169
|
-
- Confirm pairing success before
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
- Missing peer relay invite code (`clawd1_...`).
|
|
182
|
-
- Missing registry onboarding invite code (`clw_inv_...`) when API key is absent.
|
|
183
|
-
- Missing Clawdentity API key only when registry onboarding invite code is unavailable.
|
|
184
|
-
- Missing initiator/responder proxy URLs for pairing commands.
|
|
185
|
-
- Unclear OpenClaw state directory.
|
|
186
|
-
- Non-default OpenClaw base URL.
|
|
187
|
-
- Local connector runtime or peer network route is unknown or unreachable from agent runtime.
|
|
125
|
+
- Optional persistent mode: `clawdentity connector service install <agent-name>`.
|
|
126
|
+
|
|
127
|
+
8. Validate readiness.
|
|
128
|
+
- Run `clawdentity openclaw doctor`.
|
|
129
|
+
- Run `clawdentity openclaw relay test --peer <alias>`.
|
|
130
|
+
- At this point the agent is ready to start pairing or accept pairing.
|
|
131
|
+
|
|
132
|
+
9. Pairing phase (separate from onboarding).
|
|
133
|
+
- Initiator: `clawdentity pair start <agent-name> --proxy-url <initiator-proxy-url> --qr`
|
|
134
|
+
- Responder: `clawdentity pair confirm <agent-name> --qr-file <path> --proxy-url <responder-proxy-url>`
|
|
135
|
+
- Confirm pairing success before first real peer message.
|
|
136
|
+
|
|
137
|
+
## Required Question Policy
|
|
138
|
+
|
|
139
|
+
Ask only when missing:
|
|
140
|
+
- local agent name
|
|
141
|
+
- onboarding invite (`clw_inv_...`) when API key is absent
|
|
142
|
+
- peer alias/DID/proxy URL for setup
|
|
143
|
+
- initiator/responder proxy URLs for pairing
|
|
144
|
+
- non-default OpenClaw path/base URL
|
|
145
|
+
|
|
146
|
+
Do not ask for relay invite codes.
|
|
188
147
|
|
|
189
148
|
## Failure Handling
|
|
190
149
|
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
- Re-run `clawdentity openclaw doctor`.
|
|
197
|
-
- Re-run `clawdentity openclaw relay test --peer <alias>`.
|
|
198
|
-
- Re-run the same user-style flow from step 6 onward only after health checks pass.
|
|
150
|
+
- Report exact missing file/value.
|
|
151
|
+
- Fix only failing input/config.
|
|
152
|
+
- Keep connector running while testing relay delivery.
|
|
153
|
+
- If `405 Method Not Allowed` appears on hook path, rerun setup and restart OpenClaw.
|
|
154
|
+
- Re-run `openclaw doctor`, then `openclaw relay test`.
|
|
199
155
|
|
|
200
156
|
## Bundled Resources
|
|
201
157
|
|
|
202
|
-
### References
|
|
203
158
|
| File | Purpose |
|
|
204
159
|
|------|---------|
|
|
205
|
-
| `references/clawdentity-protocol.md` |
|
|
160
|
+
| `references/clawdentity-protocol.md` | Peer-map schema, pairing contract, connector handoff envelope, runtime failure mapping |
|
|
206
161
|
|
|
207
162
|
Directive: read the reference file before troubleshooting relay contract or connector handoff failures.
|
|
@@ -26,27 +26,19 @@ Define the exact runtime contract used by `relay-to-peer.mjs`.
|
|
|
26
26
|
- `~/.clawdentity/openclaw-relay.json`
|
|
27
27
|
- `~/.clawdentity/openclaw-connectors.json`
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## Setup Input Contract
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
`clawdentity openclaw setup` is configured with explicit peer routing fields:
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"did": "did:claw:agent:01H...",
|
|
38
|
-
"proxyUrl": "https://beta-proxy.example.com/hooks/agent",
|
|
39
|
-
"alias": "beta",
|
|
40
|
-
"name": "Beta Agent"
|
|
41
|
-
}
|
|
42
|
-
```
|
|
33
|
+
- `--peer-alias <alias>`
|
|
34
|
+
- `--peer-did <did:claw:agent:...>`
|
|
35
|
+
- `--peer-proxy-url <http(s)://.../hooks/agent>`
|
|
36
|
+
- optional `--peer-name <display-name>`
|
|
43
37
|
|
|
44
38
|
Rules:
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
- `proxyUrl` must be absolute `http` or `https`.
|
|
49
|
-
- `alias` is optional but preferred for zero-question setup.
|
|
39
|
+
- peer alias uses `[a-zA-Z0-9._-]`
|
|
40
|
+
- peer DID must be a valid agent DID
|
|
41
|
+
- peer proxy URL must be absolute `http` or `https`
|
|
50
42
|
|
|
51
43
|
## Peer Map Schema
|
|
52
44
|
|