clawdentity 0.0.12 → 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/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 Command10 } from "commander";
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: npm install clawdentity --skill",
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: npm install clawdentity --skill",
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>/workspace/skills/clawdentity-openclaw-relay/relay-to-peer.mjs)"
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)"
@@ -23296,9 +23290,341 @@ var createPairCommand = (dependencies = {}) => {
23296
23290
  return pairCommand;
23297
23291
  };
23298
23292
 
23299
- // src/commands/verify.ts
23300
- import { readFile as readFile6 } from "fs/promises";
23293
+ // src/commands/skill.ts
23301
23294
  import { Command as Command9 } from "commander";
23295
+
23296
+ // src/install-skill-mode.ts
23297
+ import { constants, existsSync as existsSync2 } from "fs";
23298
+ import { access as access3, copyFile as copyFile2, mkdir as mkdir7, readdir as readdir2, readFile as readFile6 } from "fs/promises";
23299
+ import { createRequire } from "module";
23300
+ import { homedir as homedir4 } from "os";
23301
+ import { dirname as dirname6, join as join8, relative } from "path";
23302
+ import { fileURLToPath as fileURLToPath2 } from "url";
23303
+ var OPENCLAW_DIR_NAME2 = ".openclaw";
23304
+ var SKILL_PACKAGE_NAME = "@clawdentity/openclaw-skill";
23305
+ var SKILL_DIR_NAME2 = "clawdentity-openclaw-relay";
23306
+ var RELAY_MODULE_FILE_NAME2 = "relay-to-peer.mjs";
23307
+ function isRecord10(value) {
23308
+ return typeof value === "object" && value !== null;
23309
+ }
23310
+ var SkillInstallError = class extends Error {
23311
+ code;
23312
+ details;
23313
+ constructor(input) {
23314
+ super(input.message);
23315
+ this.name = "SkillInstallError";
23316
+ this.code = input.code;
23317
+ this.details = input.details ?? {};
23318
+ }
23319
+ };
23320
+ function getErrorCode3(error48) {
23321
+ if (!isRecord10(error48)) {
23322
+ return void 0;
23323
+ }
23324
+ return typeof error48.code === "string" ? error48.code : void 0;
23325
+ }
23326
+ function resolveHomeDir2(inputHomeDir) {
23327
+ if (typeof inputHomeDir === "string" && inputHomeDir.trim().length > 0) {
23328
+ return inputHomeDir.trim();
23329
+ }
23330
+ return homedir4();
23331
+ }
23332
+ function resolveOpenclawDir2(homeDir, inputOpenclawDir) {
23333
+ if (typeof inputOpenclawDir === "string" && inputOpenclawDir.trim().length > 0) {
23334
+ return inputOpenclawDir.trim();
23335
+ }
23336
+ return join8(homeDir, OPENCLAW_DIR_NAME2);
23337
+ }
23338
+ function resolveSkillPackageRoot(input) {
23339
+ if (typeof input.skillPackageRoot === "string" && input.skillPackageRoot.trim().length > 0) {
23340
+ return input.skillPackageRoot.trim();
23341
+ }
23342
+ const overriddenRoot = input.env.CLAWDENTITY_SKILL_PACKAGE_ROOT;
23343
+ if (typeof overriddenRoot === "string" && overriddenRoot.trim().length > 0) {
23344
+ return overriddenRoot.trim();
23345
+ }
23346
+ const bundledSkillRoot = join8(
23347
+ dirname6(fileURLToPath2(import.meta.url)),
23348
+ "..",
23349
+ "skill-bundle",
23350
+ "openclaw-skill"
23351
+ );
23352
+ if (existsSync2(bundledSkillRoot)) {
23353
+ return bundledSkillRoot;
23354
+ }
23355
+ const require3 = createRequire(import.meta.url);
23356
+ let packageJsonPath;
23357
+ try {
23358
+ packageJsonPath = require3.resolve(`${SKILL_PACKAGE_NAME}/package.json`);
23359
+ return dirname6(packageJsonPath);
23360
+ } catch {
23361
+ const workspaceFallbackRoot = join8(
23362
+ dirname6(fileURLToPath2(import.meta.url)),
23363
+ "..",
23364
+ "..",
23365
+ "openclaw-skill"
23366
+ );
23367
+ if (existsSync2(workspaceFallbackRoot)) {
23368
+ return workspaceFallbackRoot;
23369
+ }
23370
+ throw new SkillInstallError({
23371
+ code: "CLI_SKILL_PACKAGE_NOT_FOUND",
23372
+ message: "Skill artifacts are unavailable. Set CLAWDENTITY_SKILL_PACKAGE_ROOT or provide bundled skill assets before running skill install.",
23373
+ details: {
23374
+ packageName: SKILL_PACKAGE_NAME,
23375
+ bundledSkillRoot,
23376
+ workspaceFallbackRoot
23377
+ }
23378
+ });
23379
+ }
23380
+ }
23381
+ async function assertReadableFile(filePath, details) {
23382
+ try {
23383
+ await access3(filePath, constants.R_OK);
23384
+ } catch (error48) {
23385
+ if (getErrorCode3(error48) === "ENOENT") {
23386
+ throw new SkillInstallError({
23387
+ code: "CLI_SKILL_ARTIFACT_MISSING",
23388
+ message: "Required skill artifact is missing",
23389
+ details: {
23390
+ ...details,
23391
+ sourcePath: filePath
23392
+ }
23393
+ });
23394
+ }
23395
+ throw error48;
23396
+ }
23397
+ }
23398
+ async function listFilesRecursively(directoryPath) {
23399
+ const entries = await readdir2(directoryPath, { withFileTypes: true });
23400
+ const files = [];
23401
+ for (const entry of entries.sort(
23402
+ (left, right) => left.name.localeCompare(right.name)
23403
+ )) {
23404
+ const entryPath = join8(directoryPath, entry.name);
23405
+ if (entry.isDirectory()) {
23406
+ files.push(...await listFilesRecursively(entryPath));
23407
+ continue;
23408
+ }
23409
+ if (entry.isFile()) {
23410
+ files.push(entryPath);
23411
+ }
23412
+ }
23413
+ return files;
23414
+ }
23415
+ async function resolveArtifacts(input) {
23416
+ const skillRoot = join8(input.skillPackageRoot, "skill");
23417
+ const skillDocSource = join8(skillRoot, "SKILL.md");
23418
+ const referencesRoot = join8(skillRoot, "references");
23419
+ const relaySource = join8(
23420
+ input.skillPackageRoot,
23421
+ "dist",
23422
+ RELAY_MODULE_FILE_NAME2
23423
+ );
23424
+ await assertReadableFile(skillDocSource, {
23425
+ artifact: "SKILL.md"
23426
+ });
23427
+ await assertReadableFile(relaySource, {
23428
+ artifact: RELAY_MODULE_FILE_NAME2
23429
+ });
23430
+ let referenceFiles;
23431
+ try {
23432
+ referenceFiles = await listFilesRecursively(referencesRoot);
23433
+ } catch (error48) {
23434
+ if (getErrorCode3(error48) === "ENOENT") {
23435
+ throw new SkillInstallError({
23436
+ code: "CLI_SKILL_ARTIFACT_MISSING",
23437
+ message: "Required skill references directory is missing",
23438
+ details: {
23439
+ sourcePath: referencesRoot,
23440
+ artifact: "references"
23441
+ }
23442
+ });
23443
+ }
23444
+ throw error48;
23445
+ }
23446
+ if (referenceFiles.length === 0) {
23447
+ throw new SkillInstallError({
23448
+ code: "CLI_SKILL_REFERENCE_DIR_EMPTY",
23449
+ message: "Required skill references directory is empty",
23450
+ details: {
23451
+ sourcePath: referencesRoot
23452
+ }
23453
+ });
23454
+ }
23455
+ const targetSkillRoot = join8(
23456
+ input.openclawDir,
23457
+ "skills",
23458
+ SKILL_DIR_NAME2
23459
+ );
23460
+ const artifacts = [
23461
+ {
23462
+ sourcePath: skillDocSource,
23463
+ targetPath: join8(targetSkillRoot, "SKILL.md")
23464
+ },
23465
+ {
23466
+ sourcePath: relaySource,
23467
+ targetPath: join8(targetSkillRoot, RELAY_MODULE_FILE_NAME2)
23468
+ },
23469
+ {
23470
+ sourcePath: relaySource,
23471
+ targetPath: join8(
23472
+ input.openclawDir,
23473
+ "hooks",
23474
+ "transforms",
23475
+ RELAY_MODULE_FILE_NAME2
23476
+ )
23477
+ }
23478
+ ];
23479
+ for (const referenceFile of referenceFiles) {
23480
+ const relativePath = relative(referencesRoot, referenceFile);
23481
+ artifacts.push({
23482
+ sourcePath: referenceFile,
23483
+ targetPath: join8(targetSkillRoot, "references", relativePath)
23484
+ });
23485
+ }
23486
+ return artifacts.sort(
23487
+ (left, right) => left.targetPath.localeCompare(right.targetPath)
23488
+ );
23489
+ }
23490
+ async function copyArtifact(input) {
23491
+ const sourceContent = await readFile6(input.sourcePath);
23492
+ let existingContent;
23493
+ try {
23494
+ existingContent = await readFile6(input.targetPath);
23495
+ } catch (error48) {
23496
+ if (getErrorCode3(error48) !== "ENOENT") {
23497
+ throw error48;
23498
+ }
23499
+ }
23500
+ if (existingContent !== void 0 && sourceContent.equals(existingContent)) {
23501
+ return "unchanged";
23502
+ }
23503
+ await mkdir7(dirname6(input.targetPath), { recursive: true });
23504
+ await copyFile2(input.sourcePath, input.targetPath);
23505
+ if (existingContent !== void 0) {
23506
+ return "updated";
23507
+ }
23508
+ return "installed";
23509
+ }
23510
+ async function installOpenclawSkillArtifacts(options = {}) {
23511
+ const env = options.env ?? process.env;
23512
+ const homeDir = resolveHomeDir2(options.homeDir);
23513
+ const openclawDir = resolveOpenclawDir2(homeDir, options.openclawDir);
23514
+ const skillPackageRoot = resolveSkillPackageRoot({
23515
+ skillPackageRoot: options.skillPackageRoot,
23516
+ env
23517
+ });
23518
+ const artifacts = await resolveArtifacts({
23519
+ skillPackageRoot,
23520
+ openclawDir
23521
+ });
23522
+ const records = [];
23523
+ for (const artifact of artifacts) {
23524
+ const action = await copyArtifact(artifact);
23525
+ records.push({
23526
+ action,
23527
+ sourcePath: artifact.sourcePath,
23528
+ targetPath: artifact.targetPath
23529
+ });
23530
+ }
23531
+ return {
23532
+ homeDir,
23533
+ openclawDir,
23534
+ skillPackageRoot,
23535
+ targetSkillDirectory: join8(openclawDir, "skills", SKILL_DIR_NAME2),
23536
+ records
23537
+ };
23538
+ }
23539
+ function formatSkillInstallError(error48) {
23540
+ if (error48 instanceof SkillInstallError) {
23541
+ const details = Object.entries(error48.details).map(([key, value]) => `${key}=${value}`).join(" ");
23542
+ if (details.length === 0) {
23543
+ return `${error48.code}: ${error48.message}`;
23544
+ }
23545
+ return `${error48.code}: ${error48.message} (${details})`;
23546
+ }
23547
+ if (error48 instanceof Error) {
23548
+ return error48.message;
23549
+ }
23550
+ return String(error48);
23551
+ }
23552
+
23553
+ // src/commands/skill.ts
23554
+ function collectStringOption(value, previous) {
23555
+ const trimmed = value.trim();
23556
+ if (trimmed.length === 0) {
23557
+ return previous;
23558
+ }
23559
+ return [...previous, trimmed];
23560
+ }
23561
+ function toInstallSummary(records) {
23562
+ const installed = records.filter((record2) => record2.action === "installed");
23563
+ const updated = records.filter((record2) => record2.action === "updated");
23564
+ const unchanged = records.filter((record2) => record2.action === "unchanged");
23565
+ return `installed=${installed.length} updated=${updated.length} unchanged=${unchanged.length}`;
23566
+ }
23567
+ async function runSkillInstall(options) {
23568
+ const requestedDirs = (options.openclawDir ?? []).filter(
23569
+ (dir) => dir.trim().length > 0
23570
+ );
23571
+ const dirs = requestedDirs.length > 0 ? requestedDirs : [void 0];
23572
+ const results = [];
23573
+ for (const openclawDir of dirs) {
23574
+ const result = await installOpenclawSkillArtifacts({
23575
+ openclawDir,
23576
+ skillPackageRoot: options.skillPackageRoot
23577
+ });
23578
+ results.push(result);
23579
+ }
23580
+ return results;
23581
+ }
23582
+ var createSkillCommand = () => {
23583
+ const skillCommand = new Command9("skill").description(
23584
+ "Install and manage Clawdentity skill artifacts"
23585
+ );
23586
+ skillCommand.command("install").description("Install Clawdentity OpenClaw skill artifacts").option(
23587
+ "--openclaw-dir <path>",
23588
+ "OpenClaw state directory target (repeat for multiple profiles)",
23589
+ collectStringOption,
23590
+ []
23591
+ ).option(
23592
+ "--skill-package-root <path>",
23593
+ "Override skill package root (defaults to bundled assets)"
23594
+ ).option("--json", "Print machine-readable JSON output").action(
23595
+ withErrorHandling(
23596
+ "skill install",
23597
+ async (options) => {
23598
+ let results;
23599
+ try {
23600
+ results = await runSkillInstall(options);
23601
+ } catch (error48) {
23602
+ throw new Error(formatSkillInstallError(error48));
23603
+ }
23604
+ if (options.json) {
23605
+ writeStdoutLine(JSON.stringify({ installs: results }, null, 2));
23606
+ return;
23607
+ }
23608
+ for (const result of results) {
23609
+ writeStdoutLine(`OpenClaw dir: ${result.openclawDir}`);
23610
+ writeStdoutLine(`Skill source: ${result.skillPackageRoot}`);
23611
+ writeStdoutLine(`Target skill dir: ${result.targetSkillDirectory}`);
23612
+ for (const record2 of result.records) {
23613
+ writeStdoutLine(
23614
+ `${record2.action}: ${record2.targetPath} (source: ${record2.sourcePath})`
23615
+ );
23616
+ }
23617
+ writeStdoutLine(toInstallSummary(result.records));
23618
+ }
23619
+ }
23620
+ )
23621
+ );
23622
+ return skillCommand;
23623
+ };
23624
+
23625
+ // src/commands/verify.ts
23626
+ import { readFile as readFile7 } from "fs/promises";
23627
+ import { Command as Command10 } from "commander";
23302
23628
  var logger10 = createLogger({ service: "cli", module: "verify" });
23303
23629
  var REGISTRY_KEYS_CACHE_FILE = "registry-keys.json";
23304
23630
  var CRL_CLAIMS_CACHE_FILE = "crl-claims.json";
@@ -23310,7 +23636,7 @@ var VerifyCommandError = class extends Error {
23310
23636
  this.name = "VerifyCommandError";
23311
23637
  }
23312
23638
  };
23313
- var isRecord10 = (value) => {
23639
+ var isRecord11 = (value) => {
23314
23640
  return typeof value === "object" && value !== null;
23315
23641
  };
23316
23642
  var normalizeRegistryUrl2 = (registryUrl) => {
@@ -23346,7 +23672,7 @@ var resolveToken = async (tokenOrFile) => {
23346
23672
  throw new VerifyCommandError("invalid token (value is empty)");
23347
23673
  }
23348
23674
  try {
23349
- const fileContents = await readFile6(input, "utf-8");
23675
+ const fileContents = await readFile7(input, "utf-8");
23350
23676
  const token = fileContents.trim();
23351
23677
  if (token.length === 0) {
23352
23678
  throw new VerifyCommandError(`invalid token (${input} is empty)`);
@@ -23378,7 +23704,7 @@ var parseResponseJson = async (response) => {
23378
23704
  }
23379
23705
  };
23380
23706
  var parseSigningKeys = (payload) => {
23381
- if (!isRecord10(payload) || !Array.isArray(payload.keys)) {
23707
+ if (!isRecord11(payload) || !Array.isArray(payload.keys)) {
23382
23708
  throw new VerifyCommandError(
23383
23709
  "verification keys unavailable (response payload is invalid)"
23384
23710
  );
@@ -23397,7 +23723,7 @@ var parseSigningKeys = (payload) => {
23397
23723
  };
23398
23724
  var parseRegistryKeysCache = (rawCache) => {
23399
23725
  const parsed = parseJson(rawCache);
23400
- if (!isRecord10(parsed)) {
23726
+ if (!isRecord11(parsed)) {
23401
23727
  return void 0;
23402
23728
  }
23403
23729
  const { registryUrl, fetchedAtMs, keys } = parsed;
@@ -23423,7 +23749,7 @@ var parseRegistryKeysCache = (rawCache) => {
23423
23749
  };
23424
23750
  var parseCrlCache = (rawCache) => {
23425
23751
  const parsed = parseJson(rawCache);
23426
- if (!isRecord10(parsed)) {
23752
+ if (!isRecord11(parsed)) {
23427
23753
  return void 0;
23428
23754
  }
23429
23755
  const { registryUrl, fetchedAtMs, claims } = parsed;
@@ -23521,7 +23847,7 @@ var fetchCrlClaims = async (input) => {
23521
23847
  );
23522
23848
  }
23523
23849
  const payload = await parseResponseJson(response);
23524
- if (!isRecord10(payload) || typeof payload.crl !== "string") {
23850
+ if (!isRecord11(payload) || typeof payload.crl !== "string") {
23525
23851
  throw new VerifyCommandError(
23526
23852
  "revocation check unavailable (response payload is invalid)"
23527
23853
  );
@@ -23566,7 +23892,7 @@ var loadCrlClaims = async (input) => {
23566
23892
  return claims;
23567
23893
  };
23568
23894
  var toInvalidTokenReason = (error48) => {
23569
- if (isRecord10(error48) && typeof error48.message === "string") {
23895
+ if (isRecord11(error48) && typeof error48.message === "string") {
23570
23896
  return `invalid token (${error48.message})`;
23571
23897
  }
23572
23898
  if (error48 instanceof Error && error48.message.length > 0) {
@@ -23642,7 +23968,7 @@ var runVerify = async (tokenOrFile) => {
23642
23968
  printResult(true, `token verified (${claims.sub})`);
23643
23969
  };
23644
23970
  var createVerifyCommand = () => {
23645
- return new Command9("verify").description("Verify an AIT using registry keys and CRL state").argument(
23971
+ return new Command10("verify").description("Verify an AIT using registry keys and CRL state").argument(
23646
23972
  "<tokenOrFile>",
23647
23973
  "Raw AIT token or file path containing the token"
23648
23974
  ).action(
@@ -23653,7 +23979,7 @@ var createVerifyCommand = () => {
23653
23979
  };
23654
23980
 
23655
23981
  // src/index.ts
23656
- var require2 = createRequire(import.meta.url);
23982
+ var require2 = createRequire2(import.meta.url);
23657
23983
  var resolveCliVersion = () => {
23658
23984
  const packageJson = require2("../package.json");
23659
23985
  if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
@@ -23663,7 +23989,7 @@ var resolveCliVersion = () => {
23663
23989
  };
23664
23990
  var CLI_VERSION = resolveCliVersion();
23665
23991
  var createProgram = () => {
23666
- return new Command10("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(createVerifyCommand());
23992
+ 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
23993
  };
23668
23994
  export {
23669
23995
  CLI_VERSION,