clawdentity 0.0.11 → 0.0.13
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 +953 -364
- package/dist/index.js +953 -364
- package/dist/postinstall.js +0 -357
- package/package.json +16 -17
- package/postinstall.mjs +1 -34
- package/skill-bundle/AGENTS.md +1 -1
- package/skill-bundle/openclaw-skill/skill/SKILL.md +9 -11
- package/skill-bundle/openclaw-skill/skill/references/clawdentity-protocol.md +1 -1
package/dist/postinstall.js
CHANGED
|
@@ -1,358 +1 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/install-skill-mode.ts
|
|
4
|
-
import { constants, existsSync } from "fs";
|
|
5
|
-
import { access, copyFile, mkdir, readdir, readFile } from "fs/promises";
|
|
6
|
-
import { createRequire } from "module";
|
|
7
|
-
import { homedir } from "os";
|
|
8
|
-
import { dirname, join, relative } from "path";
|
|
9
|
-
import { fileURLToPath } from "url";
|
|
10
|
-
|
|
11
|
-
// src/io.ts
|
|
12
|
-
var withTrailingNewline = (value) => value.endsWith("\n") ? value : `${value}
|
|
13
|
-
`;
|
|
14
|
-
var writeStdoutLine = (value) => {
|
|
15
|
-
process.stdout.write(withTrailingNewline(value));
|
|
16
|
-
};
|
|
17
|
-
var writeStderrLine = (value) => {
|
|
18
|
-
process.stderr.write(withTrailingNewline(value));
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
// src/install-skill-mode.ts
|
|
22
|
-
var OPENCLAW_DIR_NAME = ".openclaw";
|
|
23
|
-
var SKILL_PACKAGE_NAME = "@clawdentity/openclaw-skill";
|
|
24
|
-
var SKILL_DIR_NAME = "clawdentity-openclaw-relay";
|
|
25
|
-
var RELAY_MODULE_FILE_NAME = "relay-to-peer.mjs";
|
|
26
|
-
function isRecord(value) {
|
|
27
|
-
return typeof value === "object" && value !== null;
|
|
28
|
-
}
|
|
29
|
-
var SkillInstallError = class extends Error {
|
|
30
|
-
code;
|
|
31
|
-
details;
|
|
32
|
-
constructor(input) {
|
|
33
|
-
super(input.message);
|
|
34
|
-
this.name = "SkillInstallError";
|
|
35
|
-
this.code = input.code;
|
|
36
|
-
this.details = input.details ?? {};
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
function getErrorCode(error) {
|
|
40
|
-
if (!isRecord(error)) {
|
|
41
|
-
return void 0;
|
|
42
|
-
}
|
|
43
|
-
return typeof error.code === "string" ? error.code : void 0;
|
|
44
|
-
}
|
|
45
|
-
function parseBooleanFlag(value) {
|
|
46
|
-
if (value === void 0) {
|
|
47
|
-
return void 0;
|
|
48
|
-
}
|
|
49
|
-
const normalized = value.trim().toLowerCase();
|
|
50
|
-
if (normalized === "" || normalized === "1" || normalized === "true" || normalized === "yes") {
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
if (normalized === "0" || normalized === "false" || normalized === "no") {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
return void 0;
|
|
57
|
-
}
|
|
58
|
-
function hasSkillFlagInNpmArgv(rawArgv) {
|
|
59
|
-
if (!rawArgv || rawArgv.trim().length === 0) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
let parsed;
|
|
63
|
-
try {
|
|
64
|
-
parsed = JSON.parse(rawArgv);
|
|
65
|
-
} catch {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
if (!isRecord(parsed)) {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
const original = parsed.original;
|
|
72
|
-
if (!Array.isArray(original)) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
return original.some((entry) => entry === "--skill");
|
|
76
|
-
}
|
|
77
|
-
function isSkillInstallRequested(env = process.env) {
|
|
78
|
-
const envFlag = parseBooleanFlag(env.npm_config_skill);
|
|
79
|
-
if (envFlag !== void 0) {
|
|
80
|
-
return envFlag;
|
|
81
|
-
}
|
|
82
|
-
return hasSkillFlagInNpmArgv(env.npm_config_argv);
|
|
83
|
-
}
|
|
84
|
-
function resolveHomeDir(inputHomeDir) {
|
|
85
|
-
if (typeof inputHomeDir === "string" && inputHomeDir.trim().length > 0) {
|
|
86
|
-
return inputHomeDir.trim();
|
|
87
|
-
}
|
|
88
|
-
return homedir();
|
|
89
|
-
}
|
|
90
|
-
function resolveOpenclawDir(homeDir, inputOpenclawDir) {
|
|
91
|
-
if (typeof inputOpenclawDir === "string" && inputOpenclawDir.trim().length > 0) {
|
|
92
|
-
return inputOpenclawDir.trim();
|
|
93
|
-
}
|
|
94
|
-
return join(homeDir, OPENCLAW_DIR_NAME);
|
|
95
|
-
}
|
|
96
|
-
function resolveSkillPackageRoot(input) {
|
|
97
|
-
if (typeof input.skillPackageRoot === "string" && input.skillPackageRoot.trim().length > 0) {
|
|
98
|
-
return input.skillPackageRoot.trim();
|
|
99
|
-
}
|
|
100
|
-
const overriddenRoot = input.env.CLAWDENTITY_SKILL_PACKAGE_ROOT;
|
|
101
|
-
if (typeof overriddenRoot === "string" && overriddenRoot.trim().length > 0) {
|
|
102
|
-
return overriddenRoot.trim();
|
|
103
|
-
}
|
|
104
|
-
const bundledSkillRoot = join(
|
|
105
|
-
dirname(fileURLToPath(import.meta.url)),
|
|
106
|
-
"..",
|
|
107
|
-
"skill-bundle",
|
|
108
|
-
"openclaw-skill"
|
|
109
|
-
);
|
|
110
|
-
if (existsSync(bundledSkillRoot)) {
|
|
111
|
-
return bundledSkillRoot;
|
|
112
|
-
}
|
|
113
|
-
const require2 = createRequire(import.meta.url);
|
|
114
|
-
let packageJsonPath;
|
|
115
|
-
try {
|
|
116
|
-
packageJsonPath = require2.resolve(`${SKILL_PACKAGE_NAME}/package.json`);
|
|
117
|
-
return dirname(packageJsonPath);
|
|
118
|
-
} catch {
|
|
119
|
-
const workspaceFallbackRoot = join(
|
|
120
|
-
dirname(fileURLToPath(import.meta.url)),
|
|
121
|
-
"..",
|
|
122
|
-
"..",
|
|
123
|
-
"openclaw-skill"
|
|
124
|
-
);
|
|
125
|
-
if (existsSync(workspaceFallbackRoot)) {
|
|
126
|
-
return workspaceFallbackRoot;
|
|
127
|
-
}
|
|
128
|
-
throw new SkillInstallError({
|
|
129
|
-
code: "CLI_SKILL_PACKAGE_NOT_FOUND",
|
|
130
|
-
message: "Skill artifacts are unavailable. Set CLAWDENTITY_SKILL_PACKAGE_ROOT or provide bundled skill assets before using --skill mode.",
|
|
131
|
-
details: {
|
|
132
|
-
packageName: SKILL_PACKAGE_NAME,
|
|
133
|
-
bundledSkillRoot,
|
|
134
|
-
workspaceFallbackRoot
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
async function assertReadableFile(filePath, details) {
|
|
140
|
-
try {
|
|
141
|
-
await access(filePath, constants.R_OK);
|
|
142
|
-
} catch (error) {
|
|
143
|
-
if (getErrorCode(error) === "ENOENT") {
|
|
144
|
-
throw new SkillInstallError({
|
|
145
|
-
code: "CLI_SKILL_ARTIFACT_MISSING",
|
|
146
|
-
message: "Required skill artifact is missing",
|
|
147
|
-
details: {
|
|
148
|
-
...details,
|
|
149
|
-
sourcePath: filePath
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
throw error;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
async function listFilesRecursively(directoryPath) {
|
|
157
|
-
const entries = await readdir(directoryPath, { withFileTypes: true });
|
|
158
|
-
const files = [];
|
|
159
|
-
for (const entry of entries.sort(
|
|
160
|
-
(left, right) => left.name.localeCompare(right.name)
|
|
161
|
-
)) {
|
|
162
|
-
const entryPath = join(directoryPath, entry.name);
|
|
163
|
-
if (entry.isDirectory()) {
|
|
164
|
-
files.push(...await listFilesRecursively(entryPath));
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
if (entry.isFile()) {
|
|
168
|
-
files.push(entryPath);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return files;
|
|
172
|
-
}
|
|
173
|
-
async function resolveArtifacts(input) {
|
|
174
|
-
const skillRoot = join(input.skillPackageRoot, "skill");
|
|
175
|
-
const skillDocSource = join(skillRoot, "SKILL.md");
|
|
176
|
-
const referencesRoot = join(skillRoot, "references");
|
|
177
|
-
const relaySource = join(
|
|
178
|
-
input.skillPackageRoot,
|
|
179
|
-
"dist",
|
|
180
|
-
RELAY_MODULE_FILE_NAME
|
|
181
|
-
);
|
|
182
|
-
await assertReadableFile(skillDocSource, {
|
|
183
|
-
artifact: "SKILL.md"
|
|
184
|
-
});
|
|
185
|
-
await assertReadableFile(relaySource, {
|
|
186
|
-
artifact: RELAY_MODULE_FILE_NAME
|
|
187
|
-
});
|
|
188
|
-
let referenceFiles;
|
|
189
|
-
try {
|
|
190
|
-
referenceFiles = await listFilesRecursively(referencesRoot);
|
|
191
|
-
} catch (error) {
|
|
192
|
-
if (getErrorCode(error) === "ENOENT") {
|
|
193
|
-
throw new SkillInstallError({
|
|
194
|
-
code: "CLI_SKILL_ARTIFACT_MISSING",
|
|
195
|
-
message: "Required skill references directory is missing",
|
|
196
|
-
details: {
|
|
197
|
-
sourcePath: referencesRoot,
|
|
198
|
-
artifact: "references"
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
throw error;
|
|
203
|
-
}
|
|
204
|
-
if (referenceFiles.length === 0) {
|
|
205
|
-
throw new SkillInstallError({
|
|
206
|
-
code: "CLI_SKILL_REFERENCE_DIR_EMPTY",
|
|
207
|
-
message: "Required skill references directory is empty",
|
|
208
|
-
details: {
|
|
209
|
-
sourcePath: referencesRoot
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
const targetSkillRoot = join(
|
|
214
|
-
input.openclawDir,
|
|
215
|
-
"workspace",
|
|
216
|
-
"skills",
|
|
217
|
-
SKILL_DIR_NAME
|
|
218
|
-
);
|
|
219
|
-
const artifacts = [
|
|
220
|
-
{
|
|
221
|
-
sourcePath: skillDocSource,
|
|
222
|
-
targetPath: join(targetSkillRoot, "SKILL.md")
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
sourcePath: relaySource,
|
|
226
|
-
targetPath: join(targetSkillRoot, RELAY_MODULE_FILE_NAME)
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
sourcePath: relaySource,
|
|
230
|
-
targetPath: join(
|
|
231
|
-
input.openclawDir,
|
|
232
|
-
"hooks",
|
|
233
|
-
"transforms",
|
|
234
|
-
RELAY_MODULE_FILE_NAME
|
|
235
|
-
)
|
|
236
|
-
}
|
|
237
|
-
];
|
|
238
|
-
for (const referenceFile of referenceFiles) {
|
|
239
|
-
const relativePath = relative(referencesRoot, referenceFile);
|
|
240
|
-
artifacts.push({
|
|
241
|
-
sourcePath: referenceFile,
|
|
242
|
-
targetPath: join(targetSkillRoot, "references", relativePath)
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
return artifacts.sort(
|
|
246
|
-
(left, right) => left.targetPath.localeCompare(right.targetPath)
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
async function copyArtifact(input) {
|
|
250
|
-
const sourceContent = await readFile(input.sourcePath);
|
|
251
|
-
let existingContent;
|
|
252
|
-
try {
|
|
253
|
-
existingContent = await readFile(input.targetPath);
|
|
254
|
-
} catch (error) {
|
|
255
|
-
if (getErrorCode(error) !== "ENOENT") {
|
|
256
|
-
throw error;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
if (existingContent !== void 0 && sourceContent.equals(existingContent)) {
|
|
260
|
-
return "unchanged";
|
|
261
|
-
}
|
|
262
|
-
await mkdir(dirname(input.targetPath), { recursive: true });
|
|
263
|
-
await copyFile(input.sourcePath, input.targetPath);
|
|
264
|
-
if (existingContent !== void 0) {
|
|
265
|
-
return "updated";
|
|
266
|
-
}
|
|
267
|
-
return "installed";
|
|
268
|
-
}
|
|
269
|
-
async function installOpenclawSkillArtifacts(options = {}) {
|
|
270
|
-
const env = options.env ?? process.env;
|
|
271
|
-
const homeDir = resolveHomeDir(options.homeDir);
|
|
272
|
-
const openclawDir = resolveOpenclawDir(homeDir, options.openclawDir);
|
|
273
|
-
const skillPackageRoot = resolveSkillPackageRoot({
|
|
274
|
-
skillPackageRoot: options.skillPackageRoot,
|
|
275
|
-
env
|
|
276
|
-
});
|
|
277
|
-
const artifacts = await resolveArtifacts({
|
|
278
|
-
skillPackageRoot,
|
|
279
|
-
openclawDir
|
|
280
|
-
});
|
|
281
|
-
const records = [];
|
|
282
|
-
for (const artifact of artifacts) {
|
|
283
|
-
const action = await copyArtifact(artifact);
|
|
284
|
-
records.push({
|
|
285
|
-
action,
|
|
286
|
-
sourcePath: artifact.sourcePath,
|
|
287
|
-
targetPath: artifact.targetPath
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
return {
|
|
291
|
-
homeDir,
|
|
292
|
-
openclawDir,
|
|
293
|
-
skillPackageRoot,
|
|
294
|
-
targetSkillDirectory: join(
|
|
295
|
-
openclawDir,
|
|
296
|
-
"workspace",
|
|
297
|
-
"skills",
|
|
298
|
-
SKILL_DIR_NAME
|
|
299
|
-
),
|
|
300
|
-
records
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
function toSummaryCounts(records) {
|
|
304
|
-
const installed = records.filter((record) => record.action === "installed");
|
|
305
|
-
const updated = records.filter((record) => record.action === "updated");
|
|
306
|
-
const unchanged = records.filter((record) => record.action === "unchanged");
|
|
307
|
-
return `installed=${installed.length} updated=${updated.length} unchanged=${unchanged.length}`;
|
|
308
|
-
}
|
|
309
|
-
function formatSkillInstallError(error) {
|
|
310
|
-
if (error instanceof SkillInstallError) {
|
|
311
|
-
const details = Object.entries(error.details).map(([key, value]) => `${key}=${value}`).join(" ");
|
|
312
|
-
if (details.length === 0) {
|
|
313
|
-
return `${error.code}: ${error.message}`;
|
|
314
|
-
}
|
|
315
|
-
return `${error.code}: ${error.message} (${details})`;
|
|
316
|
-
}
|
|
317
|
-
if (error instanceof Error) {
|
|
318
|
-
return error.message;
|
|
319
|
-
}
|
|
320
|
-
return String(error);
|
|
321
|
-
}
|
|
322
|
-
async function runNpmSkillInstall(options = {}) {
|
|
323
|
-
const env = options.env ?? process.env;
|
|
324
|
-
const writeStdout = options.writeStdout ?? writeStdoutLine;
|
|
325
|
-
const writeStderr = options.writeStderr ?? writeStderrLine;
|
|
326
|
-
if (!isSkillInstallRequested(env)) {
|
|
327
|
-
return { skipped: true };
|
|
328
|
-
}
|
|
329
|
-
writeStdout("[clawdentity] skill install mode detected (--skill)");
|
|
330
|
-
try {
|
|
331
|
-
const result = await installOpenclawSkillArtifacts({
|
|
332
|
-
env,
|
|
333
|
-
homeDir: options.homeDir,
|
|
334
|
-
openclawDir: options.openclawDir,
|
|
335
|
-
skillPackageRoot: options.skillPackageRoot
|
|
336
|
-
});
|
|
337
|
-
for (const record of result.records) {
|
|
338
|
-
writeStdout(
|
|
339
|
-
`[clawdentity] ${record.action}: ${record.targetPath} (source: ${record.sourcePath})`
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
writeStdout(`[clawdentity] ${toSummaryCounts(result.records)}`);
|
|
343
|
-
return {
|
|
344
|
-
skipped: false,
|
|
345
|
-
...result
|
|
346
|
-
};
|
|
347
|
-
} catch (error) {
|
|
348
|
-
writeStderr(
|
|
349
|
-
`[clawdentity] skill install failed: ${formatSkillInstallError(error)}`
|
|
350
|
-
);
|
|
351
|
-
throw error;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
// src/postinstall.ts
|
|
356
|
-
runNpmSkillInstall().catch(() => {
|
|
357
|
-
process.exitCode = 1;
|
|
358
|
-
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawdentity",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
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/connector": "0.0.0",
|
|
36
|
+
"@clawdentity/protocol": "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
|
+
}
|
package/postinstall.mjs
CHANGED
|
@@ -1,46 +1,13 @@
|
|
|
1
|
-
import { constants } from "node:fs";
|
|
2
|
-
import { access } from "node:fs/promises";
|
|
3
1
|
import { dirname, join } from "node:path";
|
|
4
2
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
3
|
|
|
6
|
-
function parseBooleanFlag(value) {
|
|
7
|
-
if (typeof value !== "string") {
|
|
8
|
-
return undefined;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const normalized = value.trim().toLowerCase();
|
|
12
|
-
if (
|
|
13
|
-
normalized === "" ||
|
|
14
|
-
normalized === "1" ||
|
|
15
|
-
normalized === "true" ||
|
|
16
|
-
normalized === "yes"
|
|
17
|
-
) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (normalized === "0" || normalized === "false" || normalized === "no") {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
4
|
const packageRoot = dirname(fileURLToPath(import.meta.url));
|
|
29
5
|
const bundledPostinstallPath = join(packageRoot, "dist", "postinstall.js");
|
|
30
|
-
const skillRequested = parseBooleanFlag(process.env.npm_config_skill) === true;
|
|
31
6
|
|
|
32
7
|
try {
|
|
33
|
-
await access(bundledPostinstallPath, constants.R_OK);
|
|
34
8
|
await import(pathToFileURL(bundledPostinstallPath).href);
|
|
35
9
|
} catch (error) {
|
|
36
|
-
if (error && typeof error === "object" && error.code === "ENOENT") {
|
|
37
|
-
if (skillRequested) {
|
|
38
|
-
process.stderr.write(
|
|
39
|
-
`[clawdentity] skill install failed: build artifact not found at ${bundledPostinstallPath}\n`,
|
|
40
|
-
);
|
|
41
|
-
process.exitCode = 1;
|
|
42
|
-
}
|
|
43
|
-
} else {
|
|
10
|
+
if (!(error && typeof error === "object" && error.code === "ENOENT")) {
|
|
44
11
|
const message = error instanceof Error ? error.message : String(error);
|
|
45
12
|
process.stderr.write(`[clawdentity] postinstall failed: ${message}\n`);
|
|
46
13
|
process.exitCode = 1;
|
package/skill-bundle/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AGENTS.md (apps/cli/skill-bundle)
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
|
-
- Store bundled skill artifacts shipped with the CLI package for
|
|
4
|
+
- Store bundled skill artifacts shipped with the CLI package for `clawdentity skill install`.
|
|
5
5
|
|
|
6
6
|
## Rules
|
|
7
7
|
- Treat this folder as generated release input; do not hand-edit bundled files.
|
|
@@ -27,9 +27,9 @@ Relay invite codes are not part of this flow.
|
|
|
27
27
|
- Transform target path: `~/.openclaw/hooks/transforms/relay-to-peer.mjs`
|
|
28
28
|
- Transform runtime snapshot: `~/.openclaw/hooks/transforms/clawdentity-relay.json`
|
|
29
29
|
- Transform peers snapshot: `~/.openclaw/hooks/transforms/clawdentity-peers.json`
|
|
30
|
-
-
|
|
30
|
+
- Managed skill location: `~/.openclaw/skills/clawdentity-openclaw-relay/SKILL.md`
|
|
31
31
|
- Default transform source expected by CLI setup:
|
|
32
|
-
`~/.openclaw/
|
|
32
|
+
`~/.openclaw/skills/clawdentity-openclaw-relay/relay-to-peer.mjs`
|
|
33
33
|
|
|
34
34
|
### Clawdentity identity files
|
|
35
35
|
- Clawdentity root: `~/.clawdentity`
|
|
@@ -79,7 +79,6 @@ Note: Registry operators must run `admin bootstrap` before creating invites. See
|
|
|
79
79
|
- `clawdentity config init`
|
|
80
80
|
- `clawdentity config init --registry-url <registry-url>`
|
|
81
81
|
- `clawdentity config set registryUrl <registry-url>`
|
|
82
|
-
- `clawdentity config set proxyUrl <proxy-url>`
|
|
83
82
|
- `clawdentity config set apiKey <api-key>` (manual recovery only)
|
|
84
83
|
- `clawdentity config get <key>`
|
|
85
84
|
- `clawdentity config show`
|
|
@@ -103,6 +102,7 @@ Note: Registry operators must run `admin bootstrap` before creating invites. See
|
|
|
103
102
|
- `clawdentity api-key revoke <api-key-id>`
|
|
104
103
|
|
|
105
104
|
### OpenClaw relay setup
|
|
105
|
+
- `clawdentity skill install`
|
|
106
106
|
- `clawdentity openclaw setup <agent-name>`
|
|
107
107
|
- `clawdentity openclaw setup <agent-name> --transform-source <path>`
|
|
108
108
|
- `clawdentity openclaw setup <agent-name> --openclaw-dir <path> --openclaw-base-url <url>`
|
|
@@ -127,10 +127,9 @@ Note: Registry operators must run `admin bootstrap` before creating invites. See
|
|
|
127
127
|
### Pairing
|
|
128
128
|
- `clawdentity pair start <agent-name> --qr`
|
|
129
129
|
- `clawdentity pair start <agent-name> --qr --qr-output <path>`
|
|
130
|
-
- `clawdentity pair start <agent-name> --qr --owner-pat <token> --
|
|
130
|
+
- `clawdentity pair start <agent-name> --qr --owner-pat <token> --ttl-seconds <seconds>`
|
|
131
131
|
- `clawdentity pair confirm <agent-name> --qr-file <path>`
|
|
132
132
|
- `clawdentity pair confirm <agent-name> --ticket <clwpair1_...>`
|
|
133
|
-
- `clawdentity pair confirm <agent-name> --ticket <clwpair1_...> --proxy-url <url>`
|
|
134
133
|
|
|
135
134
|
### Token verification
|
|
136
135
|
- `clawdentity verify <tokenOrFile>`
|
|
@@ -156,8 +155,8 @@ Note: Registry operators must run `admin bootstrap` before creating invites. See
|
|
|
156
155
|
- Do not ask for pairing inputs before onboarding is complete.
|
|
157
156
|
|
|
158
157
|
2. Ensure skill artifact exists.
|
|
159
|
-
- Ensure `relay-to-peer.mjs` exists in
|
|
160
|
-
- If missing,
|
|
158
|
+
- Ensure `relay-to-peer.mjs` exists in managed skill path.
|
|
159
|
+
- If missing, run `clawdentity skill install` and continue.
|
|
161
160
|
|
|
162
161
|
3. Initialize local CLI config.
|
|
163
162
|
- Run `clawdentity config init`.
|
|
@@ -201,7 +200,7 @@ Note: Registry operators must run `admin bootstrap` before creating invites. See
|
|
|
201
200
|
|
|
202
201
|
| Check ID | Validates | Remediation on Failure |
|
|
203
202
|
|----------|-----------|----------------------|
|
|
204
|
-
| `config.registry` | `registryUrl` and `
|
|
203
|
+
| `config.registry` | `registryUrl`, `apiKey`, and `proxyUrl` in config (or proxy env override) | `clawdentity config init` or `invite redeem` |
|
|
205
204
|
| `state.selectedAgent` | Agent marker at `~/.clawdentity/openclaw-agent-name` | `clawdentity openclaw setup <agent-name>` |
|
|
206
205
|
| `state.credentials` | `ait.jwt` and `secret.key` exist and non-empty | `clawdentity agent create <agent-name>` or `agent auth refresh <agent-name>` |
|
|
207
206
|
| `state.peers` | Peers config valid; requested `--peer` alias exists | `clawdentity pair start` / `pair confirm` (optional until pairing) |
|
|
@@ -214,13 +213,12 @@ Note: Registry operators must run `admin bootstrap` before creating invites. See
|
|
|
214
213
|
|
|
215
214
|
9. Pairing phase (separate from onboarding).
|
|
216
215
|
- Initiator: `clawdentity pair start <agent-name> --qr`
|
|
217
|
-
- Optional overrides: `--owner-pat <token>`, `--
|
|
216
|
+
- Optional overrides: `--owner-pat <token>`, `--ttl-seconds <seconds>`, `--qr-output <path>`
|
|
218
217
|
- Owner PAT defaults to configured API key when `--owner-pat` is omitted.
|
|
219
218
|
- Responder (two mutually exclusive paths):
|
|
220
219
|
- QR path: `clawdentity pair confirm <agent-name> --qr-file <path>`
|
|
221
220
|
- Inline ticket path: `clawdentity pair confirm <agent-name> --ticket <clwpair1_...>`
|
|
222
221
|
- Cannot provide both `--qr-file` and `--ticket` simultaneously.
|
|
223
|
-
- Add `--proxy-url <url>` to override responder proxy.
|
|
224
222
|
- Pair confirm auto-saves peer DID/proxy mapping locally from QR ticket metadata.
|
|
225
223
|
- Confirm pairing success, then run `clawdentity openclaw relay test`.
|
|
226
224
|
|
|
@@ -286,7 +284,7 @@ Do not suggest switching endpoints unless user explicitly asks for endpoint chan
|
|
|
286
284
|
- `pair confirm` 404 (`PROXY_PAIR_TICKET_NOT_FOUND`): ticket is invalid or expired. Request a new ticket from initiator.
|
|
287
285
|
- `pair confirm` 410 (`PROXY_PAIR_TICKET_EXPIRED`): ticket has expired. Request a new ticket.
|
|
288
286
|
- `CLI_PAIR_CONFIRM_INPUT_CONFLICT`: cannot provide both `--ticket` and `--qr-file`. Use one path only.
|
|
289
|
-
- `
|
|
287
|
+
- `CLI_PAIR_PROXY_URL_MISMATCH`: local `proxyUrl` does not match registry metadata. Rerun `clawdentity invite redeem <clw_inv_...>`.
|
|
290
288
|
|
|
291
289
|
### Setup errors
|
|
292
290
|
- `405 Method Not Allowed` on hook path: rerun `clawdentity openclaw setup <agent-name>` and restart OpenClaw.
|
|
@@ -11,7 +11,7 @@ Define the exact runtime contract used by `relay-to-peer.mjs`.
|
|
|
11
11
|
- `<resolved-openclaw-state>/hooks/transforms/relay-to-peer.mjs`
|
|
12
12
|
- `<resolved-openclaw-state>/hooks/transforms/clawdentity-relay.json`
|
|
13
13
|
- `<resolved-openclaw-state>/hooks/transforms/clawdentity-peers.json`
|
|
14
|
-
- `<resolved-openclaw-state>/
|
|
14
|
+
- `<resolved-openclaw-state>/skills/clawdentity-openclaw-relay/SKILL.md`
|
|
15
15
|
- env overrides:
|
|
16
16
|
- `OPENCLAW_CONFIG_PATH`, `CLAWDBOT_CONFIG_PATH`
|
|
17
17
|
- `OPENCLAW_STATE_DIR`, `CLAWDBOT_STATE_DIR`
|