@cleocode/caamp 2026.5.88 → 2026.5.90

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.
@@ -3,20 +3,19 @@ import {
3
3
  getPrimaryProvider,
4
4
  groupByInstructFile,
5
5
  injectAll
6
- } from "./chunk-PGETUTYZ.js";
6
+ } from "./chunk-EH5U4PRC.js";
7
7
  import {
8
8
  __export,
9
9
  getAgentsConfigPath,
10
10
  getAgentsHome,
11
11
  getAgentsMcpDir,
12
12
  getAgentsMcpServersPath,
13
- getCanonicalSkillsDir,
14
13
  getLockFilePath,
15
14
  getPlatformLocations,
16
15
  resolveProviderConfigPath,
17
16
  resolveProviderProjectPath,
18
17
  resolveProviderSkillsDirs
19
- } from "./chunk-H5YXR2DC.js";
18
+ } from "./chunk-HDZYZTR2.js";
20
19
 
21
20
  // src/core/logger.ts
22
21
  var verboseMode = false;
@@ -188,12 +187,13 @@ function resetDetectionCache() {
188
187
  import { existsSync as existsSync2, lstatSync } from "fs";
189
188
  import { cp, mkdir, rm, symlink } from "fs/promises";
190
189
  import { join as join2 } from "path";
190
+ import { resolveSkillsRoot } from "@cleocode/core/skills/skill-root.js";
191
191
  async function ensureCanonicalDir() {
192
- await mkdir(getCanonicalSkillsDir(), { recursive: true });
192
+ await mkdir(resolveSkillsRoot(), { recursive: true });
193
193
  }
194
194
  async function installToCanonical(sourcePath, skillName) {
195
195
  await ensureCanonicalDir();
196
- const targetDir = join2(getCanonicalSkillsDir(), skillName);
196
+ const targetDir = join2(resolveSkillsRoot(), skillName);
197
197
  await rm(targetDir, { recursive: true, force: true });
198
198
  try {
199
199
  await cp(sourcePath, targetDir, { recursive: true });
@@ -308,7 +308,7 @@ async function removeSkill(skillName, providers, isGlobal, projectDir) {
308
308
  removed.push(provider.id);
309
309
  }
310
310
  }
311
- const canonicalPath = join2(getCanonicalSkillsDir(), skillName);
311
+ const canonicalPath = join2(resolveSkillsRoot(), skillName);
312
312
  if (existsSync2(canonicalPath)) {
313
313
  try {
314
314
  await rm(canonicalPath, { recursive: true });
@@ -319,9 +319,9 @@ async function removeSkill(skillName, providers, isGlobal, projectDir) {
319
319
  return { removed, errors };
320
320
  }
321
321
  async function listCanonicalSkills() {
322
- if (!existsSync2(getCanonicalSkillsDir())) return [];
323
- const { readdir: readdir4 } = await import("fs/promises");
324
- const entries = await readdir4(getCanonicalSkillsDir(), { withFileTypes: true });
322
+ if (!existsSync2(resolveSkillsRoot())) return [];
323
+ const { readdir: readdir3 } = await import("fs/promises");
324
+ const entries = await readdir3(resolveSkillsRoot(), { withFileTypes: true });
325
325
  return entries.filter((e) => e.isDirectory() || e.isSymbolicLink()).map((e) => e.name);
326
326
  }
327
327
 
@@ -330,16 +330,7 @@ import { existsSync as existsSync3, lstatSync as lstatSync2 } from "fs";
330
330
  import { cp as cp2, mkdir as mkdir2, readlink, rm as rm2, symlink as symlink2 } from "fs/promises";
331
331
  import { tmpdir } from "os";
332
332
  import { basename, dirname, join as join3 } from "path";
333
-
334
- // src/core/paths/agents.ts
335
- var AGENTS_HOME = getAgentsHome();
336
- var LOCK_FILE_PATH = getLockFilePath();
337
- var CANONICAL_SKILLS_DIR = getCanonicalSkillsDir();
338
- var AGENTS_MCP_DIR = getAgentsMcpDir();
339
- var AGENTS_MCP_SERVERS_PATH = getAgentsMcpServersPath();
340
- var AGENTS_CONFIG_PATH = getAgentsConfigPath();
341
-
342
- // src/core/advanced/orchestration.ts
333
+ import { resolveSkillsRoot as resolveSkillsRoot2 } from "@cleocode/core/skills/skill-root.js";
343
334
  var PRIORITY_ORDER = {
344
335
  primary: -1,
345
336
  high: 0,
@@ -357,7 +348,7 @@ function resolveSkillLinkPath(provider, skillName, isGlobal, projectDir) {
357
348
  async function snapshotSkillState(providerTargets, operation, projectDir, backupRoot) {
358
349
  const skillName = operation.skillName;
359
350
  const isGlobal = operation.isGlobal ?? true;
360
- const canonicalPath = join3(CANONICAL_SKILLS_DIR, skillName);
351
+ const canonicalPath = join3(resolveSkillsRoot2(), skillName);
361
352
  const canonicalExisted = existsSync3(canonicalPath);
362
353
  const canonicalBackupPath = join3(backupRoot, "canonical", skillName);
363
354
  if (canonicalExisted) {
@@ -1106,7 +1097,7 @@ ${MARKER_END}`;
1106
1097
  task.signal.addEventListener("abort", onAbort, { once: true });
1107
1098
  }
1108
1099
  }
1109
- const exitPromise = new Promise((resolve2) => {
1100
+ const exitPromise = new Promise((resolve) => {
1110
1101
  child.on("close", (exitCode, signal) => {
1111
1102
  flushStdoutBuffer(true);
1112
1103
  flushStderrBuffer(true);
@@ -1128,7 +1119,7 @@ ${MARKER_END}`;
1128
1119
  };
1129
1120
  Promise.allSettled(pendingWrites).then(() => {
1130
1121
  safeOnStream({ kind: "exit", subagentId, payload: result2 });
1131
- resolve2(result2);
1122
+ resolve(result2);
1132
1123
  });
1133
1124
  });
1134
1125
  child.on("error", () => {
@@ -1857,11 +1848,11 @@ async function terminateSubagent(child, graceMs) {
1857
1848
  }
1858
1849
  const pollInterval = Math.min(25, Math.max(1, graceMs));
1859
1850
  const deadline = Date.now() + graceMs;
1860
- await new Promise((resolve2) => {
1851
+ await new Promise((resolve) => {
1861
1852
  const timer = setInterval(() => {
1862
1853
  if (child.exitCode !== null || child.signalCode !== null) {
1863
1854
  clearInterval(timer);
1864
- resolve2();
1855
+ resolve();
1865
1856
  return;
1866
1857
  }
1867
1858
  if (Date.now() >= deadline) {
@@ -1870,12 +1861,12 @@ async function terminateSubagent(child, graceMs) {
1870
1861
  child.kill("SIGKILL");
1871
1862
  } catch {
1872
1863
  }
1873
- resolve2();
1864
+ resolve();
1874
1865
  }
1875
1866
  }, pollInterval);
1876
1867
  child.once("close", () => {
1877
1868
  clearInterval(timer);
1878
- resolve2();
1869
+ resolve();
1879
1870
  });
1880
1871
  });
1881
1872
  }
@@ -2225,9 +2216,9 @@ function getNestedValue(obj, keyPath) {
2225
2216
  return current;
2226
2217
  }
2227
2218
  async function ensureDir(filePath) {
2228
- const { mkdir: mkdir6 } = await import("fs/promises");
2229
- const { dirname: dirname5 } = await import("path");
2230
- await mkdir6(dirname5(filePath), { recursive: true });
2219
+ const { mkdir: mkdir5 } = await import("fs/promises");
2220
+ const { dirname: dirname4 } = await import("path");
2221
+ await mkdir5(dirname4(filePath), { recursive: true });
2231
2222
  }
2232
2223
 
2233
2224
  // src/core/formats/json.ts
@@ -2672,11 +2663,11 @@ function parseSource(input) {
2672
2663
  if (ghUrlMatch) {
2673
2664
  const owner = ghUrlMatch[1];
2674
2665
  const repo = ghUrlMatch[2];
2675
- const path2 = ghUrlMatch[4];
2666
+ const path = ghUrlMatch[4];
2676
2667
  if (!owner || !repo) {
2677
2668
  return { type: "command", value: input, inferredName: inferName(input, "command") };
2678
2669
  }
2679
- const inferredName = path2 ? path2.split("/").pop() ?? repo : repo;
2670
+ const inferredName = path ? path.split("/").pop() ?? repo : repo;
2680
2671
  return {
2681
2672
  type: "github",
2682
2673
  value: input,
@@ -2684,18 +2675,18 @@ function parseSource(input) {
2684
2675
  owner,
2685
2676
  repo,
2686
2677
  ref: ghUrlMatch[3],
2687
- path: path2
2678
+ path
2688
2679
  };
2689
2680
  }
2690
2681
  const glUrlMatch = input.match(GITLAB_URL);
2691
2682
  if (glUrlMatch) {
2692
2683
  const owner = glUrlMatch[1];
2693
2684
  const repo = glUrlMatch[2];
2694
- const path2 = glUrlMatch[4];
2685
+ const path = glUrlMatch[4];
2695
2686
  if (!owner || !repo) {
2696
2687
  return { type: "command", value: input, inferredName: inferName(input, "command") };
2697
2688
  }
2698
- const inferredName = path2 ? path2.split("/").pop() ?? repo : repo;
2689
+ const inferredName = path ? path.split("/").pop() ?? repo : repo;
2699
2690
  return {
2700
2691
  type: "gitlab",
2701
2692
  value: input,
@@ -2703,7 +2694,7 @@ function parseSource(input) {
2703
2694
  owner,
2704
2695
  repo,
2705
2696
  ref: glUrlMatch[3],
2706
- path: path2
2697
+ path
2707
2698
  };
2708
2699
  }
2709
2700
  if (HTTP_URL.test(input)) {
@@ -2724,18 +2715,18 @@ function parseSource(input) {
2724
2715
  if (ghShorthand && !NPM_SCOPED.test(input)) {
2725
2716
  const owner = ghShorthand[1];
2726
2717
  const repo = ghShorthand[2];
2727
- const path2 = ghShorthand[3];
2718
+ const path = ghShorthand[3];
2728
2719
  if (!owner || !repo) {
2729
2720
  return { type: "command", value: input, inferredName: inferName(input, "command") };
2730
2721
  }
2731
- const inferredName = path2 ? path2.split("/").pop() ?? repo : repo;
2722
+ const inferredName = path ? path.split("/").pop() ?? repo : repo;
2732
2723
  return {
2733
2724
  type: "github",
2734
2725
  value: `https://github.com/${owner}/${repo}`,
2735
2726
  inferredName,
2736
2727
  owner,
2737
2728
  repo,
2738
- path: path2
2729
+ path
2739
2730
  };
2740
2731
  }
2741
2732
  const libraryMatch = input.match(LIBRARY_SKILL);
@@ -3181,14 +3172,14 @@ async function scanFile(filePath, rules) {
3181
3172
  return { file: filePath, findings, score, passed };
3182
3173
  }
3183
3174
  async function scanDirectory(dirPath) {
3184
- const { readdir: readdir4 } = await import("fs/promises");
3185
- const { join: join11 } = await import("path");
3175
+ const { readdir: readdir3 } = await import("fs/promises");
3176
+ const { join: join9 } = await import("path");
3186
3177
  if (!existsSync10(dirPath)) return [];
3187
- const entries = await readdir4(dirPath, { withFileTypes: true });
3178
+ const entries = await readdir3(dirPath, { withFileTypes: true });
3188
3179
  const results = [];
3189
3180
  for (const entry of entries) {
3190
3181
  if (entry.isDirectory() || entry.isSymbolicLink()) {
3191
- const skillFile = join11(dirPath, entry.name, "SKILL.md");
3182
+ const skillFile = join9(dirPath, entry.name, "SKILL.md");
3192
3183
  if (existsSync10(skillFile)) {
3193
3184
  results.push(await scanFile(skillFile));
3194
3185
  }
@@ -3248,10 +3239,19 @@ import { simpleGit } from "simple-git";
3248
3239
  // src/core/lock-utils.ts
3249
3240
  import { existsSync as existsSync11 } from "fs";
3250
3241
  import { mkdir as mkdir4, open as open2, readFile as readFile6, rename as rename2, rm as rm4, stat as stat3, writeFile as writeFile5 } from "fs/promises";
3242
+
3243
+ // src/core/paths/agents.ts
3244
+ var AGENTS_HOME = getAgentsHome();
3245
+ var LOCK_FILE_PATH = getLockFilePath();
3246
+ var AGENTS_MCP_DIR = getAgentsMcpDir();
3247
+ var AGENTS_MCP_SERVERS_PATH = getAgentsMcpServersPath();
3248
+ var AGENTS_CONFIG_PATH = getAgentsConfigPath();
3249
+
3250
+ // src/core/lock-utils.ts
3251
3251
  var LOCK_GUARD_PATH = `${LOCK_FILE_PATH}.lock`;
3252
3252
  var STALE_LOCK_MS = 5e3;
3253
3253
  function sleep(ms) {
3254
- return new Promise((resolve2) => setTimeout(resolve2, ms));
3254
+ return new Promise((resolve) => setTimeout(resolve, ms));
3255
3255
  }
3256
3256
  async function removeStaleLock() {
3257
3257
  try {
@@ -3449,759 +3449,6 @@ async function checkAllSkillUpdates() {
3449
3449
  return results;
3450
3450
  }
3451
3451
 
3452
- // src/commands/skills/doctor-bridge.ts
3453
- import { existsSync as existsSync12, lstatSync as lstatSync3, readdirSync, readlinkSync, realpathSync } from "fs";
3454
- import { cp as cp4, mkdir as mkdir5, readdir as readdir2, rm as rm5, symlink as symlink3, unlink } from "fs/promises";
3455
- import { homedir as homedir3 } from "os";
3456
- import * as path from "path";
3457
- import pc from "picocolors";
3458
-
3459
- // src/core/lafs.ts
3460
- import { randomUUID } from "crypto";
3461
- import { resolveOutputFormat } from "@cleocode/lafs";
3462
- function resolveFormat(options) {
3463
- return resolveOutputFormat({
3464
- jsonFlag: options.jsonFlag ?? false,
3465
- humanFlag: (options.humanFlag ?? false) || isHuman(),
3466
- projectDefault: options.projectDefault ?? "json"
3467
- }).format;
3468
- }
3469
- function buildEnvelope(operation, mvi, result, error, page = null, sessionId, warnings) {
3470
- return {
3471
- $schema: "https://lafs.dev/schemas/v1/envelope.schema.json",
3472
- _meta: {
3473
- specVersion: "1.0.0",
3474
- schemaVersion: "1.0.0",
3475
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3476
- operation,
3477
- requestId: randomUUID(),
3478
- transport: "cli",
3479
- strict: true,
3480
- mvi,
3481
- contextVersion: 0,
3482
- ...sessionId && { sessionId },
3483
- ...warnings && warnings.length > 0 && { warnings }
3484
- },
3485
- success: error === null,
3486
- result,
3487
- error,
3488
- page
3489
- };
3490
- }
3491
- function emitError(operation, mvi, code, message, category, details = {}, exitCode = 1) {
3492
- const envelope = buildEnvelope(operation, mvi, null, {
3493
- code,
3494
- message,
3495
- category,
3496
- retryable: category === "TRANSIENT" || category === "RATE_LIMIT",
3497
- retryAfterMs: null,
3498
- details
3499
- });
3500
- console.error(JSON.stringify(envelope, null, 2));
3501
- process.exit(exitCode);
3502
- }
3503
- function emitJsonError(operation, mvi, code, message, category, details = {}) {
3504
- const envelope = buildEnvelope(operation, mvi, null, {
3505
- code,
3506
- message,
3507
- category,
3508
- retryable: category === "TRANSIENT" || category === "RATE_LIMIT",
3509
- retryAfterMs: null,
3510
- details
3511
- });
3512
- console.error(JSON.stringify(envelope, null, 2));
3513
- }
3514
- function outputSuccess(operation, mvi, result, page, sessionId, warnings) {
3515
- const envelope = buildEnvelope(operation, mvi, result, null, page ?? null, sessionId, warnings);
3516
- if (isQuiet() && !envelope.error) {
3517
- return;
3518
- }
3519
- console.log(JSON.stringify(envelope, null, 2));
3520
- }
3521
- function handleFormatError(error, operation, mvi, jsonFlag) {
3522
- const message = error instanceof Error ? error.message : String(error);
3523
- if (jsonFlag) {
3524
- emitJsonError(operation, mvi, "E_FORMAT_CONFLICT", message, "VALIDATION");
3525
- } else {
3526
- console.error(message);
3527
- }
3528
- process.exit(1);
3529
- }
3530
- var ErrorCategories = {
3531
- VALIDATION: "VALIDATION",
3532
- AUTH: "AUTH",
3533
- PERMISSION: "PERMISSION",
3534
- NOT_FOUND: "NOT_FOUND",
3535
- CONFLICT: "CONFLICT",
3536
- RATE_LIMIT: "RATE_LIMIT",
3537
- TRANSIENT: "TRANSIENT",
3538
- INTERNAL: "INTERNAL",
3539
- CONTRACT: "CONTRACT",
3540
- MIGRATION: "MIGRATION"
3541
- };
3542
- var ErrorCodes = {
3543
- // Format errors
3544
- FORMAT_CONFLICT: "E_FORMAT_CONFLICT",
3545
- INVALID_JSON: "E_INVALID_JSON",
3546
- // Not found errors
3547
- SKILL_NOT_FOUND: "E_SKILL_NOT_FOUND",
3548
- PROVIDER_NOT_FOUND: "E_PROVIDER_NOT_FOUND",
3549
- MCP_SERVER_NOT_FOUND: "E_MCP_SERVER_NOT_FOUND",
3550
- FILE_NOT_FOUND: "E_FILE_NOT_FOUND",
3551
- // Validation errors
3552
- INVALID_INPUT: "E_INVALID_INPUT",
3553
- INVALID_CONSTRAINT: "E_INVALID_CONSTRAINT",
3554
- INVALID_FORMAT: "E_INVALID_FORMAT",
3555
- // Operation errors
3556
- INSTALL_FAILED: "E_INSTALL_FAILED",
3557
- // Skills federation gates (T9564 — Sphere B)
3558
- SKILL_TRUST_GATE_BLOCKED: "E_SKILL_TRUST_GATE_BLOCKED",
3559
- FEDERATION_UNKNOWN_SOURCE_INTERACTIVE_REQUIRED: "E_FEDERATION_UNKNOWN_SOURCE_INTERACTIVE_REQUIRED",
3560
- FEDERATION_CHECKSUM_MISMATCH: "E_FEDERATION_CHECKSUM_MISMATCH",
3561
- REMOVE_FAILED: "E_REMOVE_FAILED",
3562
- UPDATE_FAILED: "E_UPDATE_FAILED",
3563
- VALIDATION_FAILED: "E_VALIDATION_FAILED",
3564
- AUDIT_FAILED: "E_AUDIT_FAILED",
3565
- // System errors
3566
- NETWORK_ERROR: "E_NETWORK_ERROR",
3567
- FILE_SYSTEM_ERROR: "E_FILE_SYSTEM_ERROR",
3568
- PERMISSION_DENIED: "E_PERMISSION_DENIED",
3569
- INTERNAL_ERROR: "E_INTERNAL_ERROR"
3570
- };
3571
-
3572
- // src/commands/skills/doctor-bridge.ts
3573
- var AgentsSkillsRealDirError = class extends Error {
3574
- /** LAFS error code surfaced by the CLI. */
3575
- code = "E_AGENTS_SKILLS_REAL_DIR";
3576
- /** Resolved path of the offending real directory. */
3577
- agentsSkillsPath;
3578
- /** Number of immediate entries in the offending directory. */
3579
- entryCount;
3580
- /**
3581
- * Construct an `AgentsSkillsRealDirError`.
3582
- *
3583
- * @param agentsSkillsPath - Path to the real `~/.agents/skills` directory.
3584
- * @param entryCount - Number of entries inside the directory.
3585
- */
3586
- constructor(agentsSkillsPath, entryCount) {
3587
- super(
3588
- `Refusing to replace real directory at ${agentsSkillsPath} (${entryCount} entries). Pass --force to back up and bridge.`
3589
- );
3590
- this.name = "AgentsSkillsRealDirError";
3591
- this.agentsSkillsPath = agentsSkillsPath;
3592
- this.entryCount = entryCount;
3593
- }
3594
- };
3595
- function buildBackupTimestamp() {
3596
- const d = /* @__PURE__ */ new Date();
3597
- const pad = (n) => n.toString().padStart(2, "0");
3598
- return `${d.getUTCFullYear()}${pad(d.getUTCMonth() + 1)}${pad(d.getUTCDate())}-${pad(d.getUTCHours())}${pad(d.getUTCMinutes())}${pad(d.getUTCSeconds())}`;
3599
- }
3600
- function resolveBridgePaths(homeRoot) {
3601
- return {
3602
- skillsRoot: path.join(homeRoot, ".cleo", "skills"),
3603
- bridgeTarget: path.join(homeRoot, ".claude", "skills", "agents-shared"),
3604
- bridgePath: path.join(homeRoot, ".agents", "skills"),
3605
- backupsRoot: path.join(homeRoot, ".cleo", "backups"),
3606
- claudeSkillsRoot: path.join(homeRoot, ".claude", "skills")
3607
- };
3608
- }
3609
- function listSkillDirs(skillsRoot) {
3610
- if (!existsSync12(skillsRoot)) return [];
3611
- const entries = readdirSync(skillsRoot, { withFileTypes: true });
3612
- return entries.filter((e) => e.isDirectory() || e.isSymbolicLink()).map((e) => e.name).filter((n) => !n.startsWith(".")).sort();
3613
- }
3614
- function symlinkPointsAt(linkPath, target) {
3615
- try {
3616
- const stat4 = lstatSync3(linkPath);
3617
- if (!stat4.isSymbolicLink()) return false;
3618
- const current = readlinkSync(linkPath);
3619
- const resolved = path.isAbsolute(current) ? current : path.resolve(path.dirname(linkPath), current);
3620
- return path.resolve(resolved) === path.resolve(target);
3621
- } catch {
3622
- return false;
3623
- }
3624
- }
3625
- async function ensureSymlink(linkPath, target, dryRun) {
3626
- if (dryRun) return;
3627
- await mkdir5(path.dirname(linkPath), { recursive: true });
3628
- if (existsSync12(linkPath)) {
3629
- try {
3630
- await unlink(linkPath);
3631
- } catch {
3632
- }
3633
- }
3634
- await symlink3(target, linkPath, "dir");
3635
- }
3636
- async function countEntries(dir) {
3637
- try {
3638
- const entries = await readdir2(dir);
3639
- return entries.length;
3640
- } catch {
3641
- return 0;
3642
- }
3643
- }
3644
- async function runDoctorBridge(options = {}) {
3645
- const homeRoot = options.homeDir ?? homedir3();
3646
- const force = options.force ?? false;
3647
- const dryRun = options.dryRun ?? false;
3648
- const { skillsRoot, bridgeTarget, bridgePath, backupsRoot, claudeSkillsRoot } = resolveBridgePaths(homeRoot);
3649
- if (!dryRun) {
3650
- await mkdir5(bridgeTarget, { recursive: true });
3651
- }
3652
- const skillNames = listSkillDirs(skillsRoot);
3653
- const created = [];
3654
- for (const name of skillNames) {
3655
- const linkPath = path.join(bridgeTarget, name);
3656
- const target = path.join(skillsRoot, name);
3657
- if (symlinkPointsAt(linkPath, target)) continue;
3658
- await ensureSymlink(linkPath, target, dryRun);
3659
- created.push({ name, linkPath, target });
3660
- }
3661
- const removed = [];
3662
- if (existsSync12(claudeSkillsRoot)) {
3663
- const entries = readdirSync(claudeSkillsRoot, { withFileTypes: true });
3664
- for (const entry of entries) {
3665
- if (entry.name === "agents-shared") continue;
3666
- const entryPath = path.join(claudeSkillsRoot, entry.name);
3667
- let stat4;
3668
- try {
3669
- stat4 = lstatSync3(entryPath);
3670
- } catch {
3671
- continue;
3672
- }
3673
- if (!stat4.isSymbolicLink()) continue;
3674
- let resolvedTarget = null;
3675
- try {
3676
- const raw = readlinkSync(entryPath);
3677
- resolvedTarget = path.isAbsolute(raw) ? raw : path.resolve(path.dirname(entryPath), raw);
3678
- } catch {
3679
- resolvedTarget = null;
3680
- }
3681
- if (resolvedTarget !== null) {
3682
- const realResolved = (() => {
3683
- try {
3684
- return realpathSync(resolvedTarget);
3685
- } catch {
3686
- return resolvedTarget;
3687
- }
3688
- })();
3689
- if (realResolved === bridgeTarget || realResolved.startsWith(`${bridgeTarget}${path.sep}`)) {
3690
- continue;
3691
- }
3692
- }
3693
- if (!dryRun) {
3694
- await unlink(entryPath);
3695
- }
3696
- removed.push({ linkPath: entryPath, previousTarget: resolvedTarget });
3697
- }
3698
- }
3699
- let backupPath = null;
3700
- const bridgeAlreadyCorrect = symlinkPointsAt(bridgePath, bridgeTarget);
3701
- let bridgeSymlinkActive = bridgeAlreadyCorrect;
3702
- if (!bridgeAlreadyCorrect) {
3703
- if (existsSync12(bridgePath)) {
3704
- const lstat = lstatSync3(bridgePath);
3705
- if (lstat.isSymbolicLink()) {
3706
- if (!dryRun) await unlink(bridgePath);
3707
- } else if (lstat.isDirectory()) {
3708
- const entryCount = await countEntries(bridgePath);
3709
- if (entryCount > 0 && !force) {
3710
- throw new AgentsSkillsRealDirError(bridgePath, entryCount);
3711
- }
3712
- if (entryCount > 0) {
3713
- backupPath = path.join(backupsRoot, `agents-skills-pre-bridge-${buildBackupTimestamp()}`);
3714
- if (!dryRun) {
3715
- await mkdir5(backupsRoot, { recursive: true });
3716
- await cp4(bridgePath, backupPath, { recursive: true, dereference: false });
3717
- await rm5(bridgePath, { recursive: true, force: true });
3718
- }
3719
- } else if (!dryRun) {
3720
- await rm5(bridgePath, { recursive: true, force: true });
3721
- }
3722
- } else if (!dryRun) {
3723
- await unlink(bridgePath);
3724
- }
3725
- }
3726
- if (!dryRun) {
3727
- await mkdir5(path.dirname(bridgePath), { recursive: true });
3728
- await symlink3(bridgeTarget, bridgePath, "dir");
3729
- bridgeSymlinkActive = true;
3730
- }
3731
- }
3732
- return {
3733
- bridgeCreated: !bridgeAlreadyCorrect,
3734
- bridgeSymlinkActive,
3735
- perSkillSymlinksCreated: created,
3736
- perSkillSymlinksRemoved: removed,
3737
- backupPath,
3738
- dryRun,
3739
- skillsRoot,
3740
- bridgeTarget,
3741
- bridgePath
3742
- };
3743
- }
3744
- function printHumanSummary(result) {
3745
- if (result.dryRun) {
3746
- console.log(pc.dim("(dry-run \u2014 no disk state mutated)"));
3747
- }
3748
- if (!result.bridgeCreated && result.perSkillSymlinksCreated.length === 0) {
3749
- console.log(pc.green("Bridge already correct \u2014 nothing to do."));
3750
- } else {
3751
- console.log(pc.green("Bridge configured."));
3752
- }
3753
- console.log(` ${pc.dim("bridge:")} ${result.bridgePath} -> ${result.bridgeTarget}`);
3754
- console.log(
3755
- ` ${pc.dim("per-skill symlinks created:")} ${result.perSkillSymlinksCreated.length}`
3756
- );
3757
- console.log(
3758
- ` ${pc.dim("per-skill symlinks removed:")} ${result.perSkillSymlinksRemoved.length}`
3759
- );
3760
- if (result.backupPath) {
3761
- console.log(` ${pc.yellow("backup:")} ${result.backupPath}`);
3762
- }
3763
- }
3764
- function registerDoctorBridge(parent) {
3765
- parent.command("bridge").description("Create the single ~/.agents/skills bridge symlink and rip per-skill symlinks").option("--force", "Back up and replace a real ~/.agents/skills directory if present").option("--dry-run", "Print planned actions without mutating disk state").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(
3766
- async (opts) => {
3767
- const operation = "skills.doctor.bridge";
3768
- const mvi = "standard";
3769
- let format;
3770
- try {
3771
- format = resolveFormat({
3772
- jsonFlag: opts.json ?? false,
3773
- humanFlag: opts.human ?? false,
3774
- projectDefault: "json"
3775
- });
3776
- } catch (error) {
3777
- const message = error instanceof Error ? error.message : String(error);
3778
- emitJsonError(
3779
- operation,
3780
- mvi,
3781
- ErrorCodes.FORMAT_CONFLICT,
3782
- message,
3783
- ErrorCategories.VALIDATION
3784
- );
3785
- process.exit(1);
3786
- }
3787
- try {
3788
- const result = await runDoctorBridge({
3789
- force: opts.force ?? false,
3790
- dryRun: opts.dryRun ?? false
3791
- });
3792
- if (format === "json") {
3793
- outputSuccess(operation, mvi, result);
3794
- } else {
3795
- printHumanSummary(result);
3796
- }
3797
- } catch (error) {
3798
- if (error instanceof AgentsSkillsRealDirError) {
3799
- if (format === "json") {
3800
- emitJsonError(operation, mvi, error.code, error.message, ErrorCategories.CONFLICT, {
3801
- agentsSkillsPath: error.agentsSkillsPath,
3802
- entryCount: error.entryCount
3803
- });
3804
- } else {
3805
- console.error(pc.red(error.message));
3806
- }
3807
- process.exit(1);
3808
- }
3809
- const message = error instanceof Error ? error.message : String(error);
3810
- if (format === "json") {
3811
- emitJsonError(
3812
- operation,
3813
- mvi,
3814
- ErrorCodes.INTERNAL_ERROR,
3815
- message,
3816
- ErrorCategories.INTERNAL
3817
- );
3818
- } else {
3819
- console.error(pc.red(message));
3820
- }
3821
- process.exit(1);
3822
- }
3823
- }
3824
- );
3825
- }
3826
-
3827
- // src/commands/skills/doctor-adopt.ts
3828
- import { randomUUID as randomUUID2 } from "crypto";
3829
- import {
3830
- cpSync,
3831
- existsSync as existsSync13,
3832
- lstatSync as lstatSync4,
3833
- mkdirSync,
3834
- readdirSync as readdirSync2,
3835
- realpathSync as realpathSync2,
3836
- renameSync,
3837
- rmSync,
3838
- statSync,
3839
- writeFileSync
3840
- } from "fs";
3841
- import { homedir as homedir4 } from "os";
3842
- import { join as join7 } from "path";
3843
- import { createInterface } from "readline/promises";
3844
- import pc2 from "picocolors";
3845
- function cleoSkillsRoot() {
3846
- return join7(homedir4(), ".cleo", "skills");
3847
- }
3848
- function legacyAgentsSkillsRoot() {
3849
- return join7(homedir4(), ".local", "share", "agents", "skills");
3850
- }
3851
- function homeAgentsSkillsRoot() {
3852
- return join7(homedir4(), ".agents", "skills");
3853
- }
3854
- function archiveRoot() {
3855
- return join7(cleoSkillsRoot(), ".archive");
3856
- }
3857
- function auditLogRoot() {
3858
- return join7(cleoSkillsRoot(), ".audit-log");
3859
- }
3860
- function listCandidates(root) {
3861
- if (!existsSync13(root)) return [];
3862
- let entries;
3863
- try {
3864
- entries = readdirSync2(root);
3865
- } catch {
3866
- return [];
3867
- }
3868
- const out = [];
3869
- for (const name of entries) {
3870
- if (name.startsWith(".")) continue;
3871
- const full = join7(root, name);
3872
- let isDirLike = false;
3873
- try {
3874
- const stat4 = lstatSync4(full);
3875
- if (stat4.isDirectory()) {
3876
- isDirLike = true;
3877
- } else if (stat4.isSymbolicLink()) {
3878
- try {
3879
- const real = statSync(full);
3880
- isDirLike = real.isDirectory();
3881
- } catch {
3882
- isDirLike = false;
3883
- }
3884
- }
3885
- } catch {
3886
- isDirLike = false;
3887
- }
3888
- if (isDirLike) {
3889
- out.push({ name, path: full });
3890
- }
3891
- }
3892
- return out;
3893
- }
3894
- function approxDirSize(dir) {
3895
- let total = 0;
3896
- try {
3897
- const entries = readdirSync2(dir);
3898
- for (const entry of entries) {
3899
- try {
3900
- const stat4 = statSync(join7(dir, entry));
3901
- if (stat4.isFile()) total += stat4.size;
3902
- } catch {
3903
- }
3904
- }
3905
- } catch {
3906
- return 0;
3907
- }
3908
- return total;
3909
- }
3910
- function discoverOrphans(registeredNames) {
3911
- const cleoRoot = cleoSkillsRoot();
3912
- const legacyRoot = legacyAgentsSkillsRoot();
3913
- const homeRoot = homeAgentsSkillsRoot();
3914
- const seen = /* @__PURE__ */ new Map();
3915
- const visit = (root, via, filter) => {
3916
- for (const candidate of listCandidates(root)) {
3917
- if (seen.has(candidate.name)) continue;
3918
- if (registeredNames.has(candidate.name)) continue;
3919
- if (filter && !filter(candidate.path)) continue;
3920
- seen.set(candidate.name, {
3921
- name: candidate.name,
3922
- path: candidate.path,
3923
- discoveredVia: via,
3924
- hasSkillMd: existsSync13(join7(candidate.path, "SKILL.md")),
3925
- sizeBytes: approxDirSize(candidate.path)
3926
- });
3927
- }
3928
- };
3929
- visit(cleoRoot, "cleo");
3930
- visit(legacyRoot, "legacy-agents");
3931
- visit(homeRoot, "home-agents", (path2) => {
3932
- try {
3933
- const real = realpathSync2(path2);
3934
- return !real.startsWith(`${cleoRoot}/`);
3935
- } catch {
3936
- return true;
3937
- }
3938
- });
3939
- return Array.from(seen.values()).sort((a, b) => a.name.localeCompare(b.name));
3940
- }
3941
- function canonicalAdoptRefusal() {
3942
- return {
3943
- code: "E_CANONICAL_ADOPT_REFUSED",
3944
- message: "Canonical adoption is refused on user machines. Canonical skills are owned by the CLEO core team and ONLY the owner-CI workflow may write them (architecture-v3 \xA76 invariant).",
3945
- remediation: "To contribute this skill to canonical: clone https://github.com/kryptobaseddev/cleo, place the skill under packages/skills/skills/<name>/, and open a PR. Local user-machine canonical writes are blocked by design."
3946
- };
3947
- }
3948
- function buildAdoptedRow(orphan, now) {
3949
- return {
3950
- name: orphan.name,
3951
- installPath: orphan.path,
3952
- installedAt: now,
3953
- sourceType: "user",
3954
- lifecycleState: "active"
3955
- };
3956
- }
3957
- function archiveAndDelete(orphan, now) {
3958
- const tsToken = now.replace(/[:.]/g, "-");
3959
- const archiveDir = join7(archiveRoot(), `${orphan.name}-${tsToken}`);
3960
- mkdirSync(archiveRoot(), { recursive: true });
3961
- cpSync(orphan.path, archiveDir, { recursive: true, dereference: false });
3962
- rmSync(orphan.path, { recursive: true, force: true });
3963
- return archiveDir;
3964
- }
3965
- async function applyDecision(orphan, decision, now, recordRow) {
3966
- const base = {
3967
- orphan,
3968
- decidedAt: now
3969
- };
3970
- if (decision === "canonical-adopt") {
3971
- return {
3972
- ...base,
3973
- decision,
3974
- applied: false,
3975
- refusal: canonicalAdoptRefusal(),
3976
- archivedTo: null
3977
- };
3978
- }
3979
- if (decision === "skip") {
3980
- return { ...base, decision, applied: true, refusal: null, archivedTo: null };
3981
- }
3982
- if (decision === "user-adopt") {
3983
- try {
3984
- await recordRow(buildAdoptedRow(orphan, now));
3985
- return { ...base, decision, applied: true, refusal: null, archivedTo: null };
3986
- } catch (err) {
3987
- const message = err instanceof Error ? err.message : String(err);
3988
- return {
3989
- ...base,
3990
- decision,
3991
- applied: false,
3992
- refusal: {
3993
- code: "E_CANONICAL_ADOPT_REFUSED",
3994
- message: `user-adopt failed: ${message}`,
3995
- remediation: "Initialise the registry with `cleo skills list` then re-run."
3996
- },
3997
- archivedTo: null
3998
- };
3999
- }
4000
- }
4001
- try {
4002
- const archived = archiveAndDelete(orphan, now);
4003
- return { ...base, decision, applied: true, refusal: null, archivedTo: archived };
4004
- } catch (err) {
4005
- const message = err instanceof Error ? err.message : String(err);
4006
- return {
4007
- ...base,
4008
- decision,
4009
- applied: false,
4010
- refusal: {
4011
- code: "E_CANONICAL_ADOPT_REFUSED",
4012
- message: `delete failed: ${message}`,
4013
- remediation: "Inspect filesystem permissions and rerun with --non-interactive to verify."
4014
- },
4015
- archivedTo: null
4016
- };
4017
- }
4018
- }
4019
- function writeAuditLog(result) {
4020
- const dir = auditLogRoot();
4021
- mkdirSync(dir, { recursive: true });
4022
- const tsToken = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
4023
- const path2 = join7(dir, `adopt-${tsToken}.json`);
4024
- const tmp = `${path2}.tmp`;
4025
- const payload = {
4026
- runId: randomUUID2(),
4027
- writtenAt: (/* @__PURE__ */ new Date()).toISOString(),
4028
- ...result
4029
- };
4030
- writeFileSync(tmp, `${JSON.stringify(payload, null, 2)}
4031
- `, "utf8");
4032
- renameSync(tmp, path2);
4033
- return path2;
4034
- }
4035
- async function promptDecision(rl, orphan) {
4036
- const kb = Math.round(orphan.sizeBytes / 1024);
4037
- process.stderr.write(
4038
- `
4039
- ${pc2.bold(orphan.name)}
4040
- path: ${orphan.path}
4041
- via: ${orphan.discoveredVia}
4042
- size: ~${kb} KiB
4043
- SKILL.md: ${orphan.hasSkillMd ? "yes" : "no"}
4044
- `
4045
- );
4046
- for (let attempt = 0; attempt < 3; attempt++) {
4047
- const answer = (await rl.question(" [c]anonical-adopt | [u]ser-adopt | [d]elete | [s]kip: ")).trim().toLowerCase();
4048
- if (answer === "c" || answer === "canonical" || answer === "canonical-adopt") {
4049
- return "canonical-adopt";
4050
- }
4051
- if (answer === "u" || answer === "user" || answer === "user-adopt") {
4052
- return "user-adopt";
4053
- }
4054
- if (answer === "d" || answer === "delete") return "delete";
4055
- if (answer === "s" || answer === "skip" || answer === "") return "skip";
4056
- process.stderr.write(` ${pc2.yellow("unrecognised input \u2014 try one of c/u/d/s")}
4057
- `);
4058
- }
4059
- return "skip";
4060
- }
4061
- async function runDoctorAdopt(options) {
4062
- const discover = options.discoverFn ?? discoverOrphans;
4063
- const registeredNames = await options.loadRegisteredNames();
4064
- const orphans = discover(registeredNames);
4065
- const results = [];
4066
- const mode = options.nonInteractive ? "non-interactive" : options.autoUserAdopt ? "auto-user-adopt" : "interactive";
4067
- if (orphans.length === 0) {
4068
- const empty = {
4069
- totalOrphans: 0,
4070
- results: [],
4071
- auditLogPath: "",
4072
- mode
4073
- };
4074
- if (!options.skipAuditLog) empty.auditLogPath = writeAuditLog(empty);
4075
- return empty;
4076
- }
4077
- if (mode === "non-interactive") {
4078
- const now = (/* @__PURE__ */ new Date()).toISOString();
4079
- for (const orphan of orphans) {
4080
- results.push({
4081
- orphan,
4082
- decision: "skip",
4083
- applied: true,
4084
- refusal: null,
4085
- archivedTo: null,
4086
- decidedAt: now
4087
- });
4088
- }
4089
- } else if (mode === "auto-user-adopt") {
4090
- for (const orphan of orphans) {
4091
- results.push(
4092
- await applyDecision(orphan, "user-adopt", (/* @__PURE__ */ new Date()).toISOString(), options.recordRow)
4093
- );
4094
- }
4095
- } else {
4096
- const promptFn = options.prompt ?? (async (orphan) => {
4097
- const rl = createInterface({ input: process.stdin, output: process.stderr });
4098
- try {
4099
- return await promptDecision(rl, orphan);
4100
- } finally {
4101
- rl.close();
4102
- }
4103
- });
4104
- for (const orphan of orphans) {
4105
- const decision = await promptFn(orphan);
4106
- results.push(
4107
- await applyDecision(orphan, decision, (/* @__PURE__ */ new Date()).toISOString(), options.recordRow)
4108
- );
4109
- }
4110
- }
4111
- const result = {
4112
- totalOrphans: orphans.length,
4113
- results,
4114
- auditLogPath: "",
4115
- mode
4116
- };
4117
- if (!options.skipAuditLog) result.auditLogPath = writeAuditLog(result);
4118
- return result;
4119
- }
4120
- var caampStandaloneAdapters = {
4121
- loadRegisteredNames: () => /* @__PURE__ */ new Set(),
4122
- recordRow: () => {
4123
- throw new Error(
4124
- "caamp standalone CLI cannot write to skills.db. Use `cleo skills doctor adopt-orphans` instead."
4125
- );
4126
- }
4127
- };
4128
- function registerSkillsDoctorAdopt(parent, adapters = caampStandaloneAdapters) {
4129
- const existing = parent.commands.find((c) => c.name() === "doctor");
4130
- const doctor = existing ?? parent.command("doctor").description("Diagnostics + repair for the skill system");
4131
- doctor.command("adopt-orphans").description(
4132
- "Interactive audit of on-disk skill dirs not tracked in skills.db (canonical/user/delete/skip)"
4133
- ).option("--json", "Output as LAFS JSON envelope (default)").option("--human", "Output a colorised human-readable summary").option("--non-interactive", "List orphans + exit without action").option("--auto-user-adopt", "Bulk-mark all orphans as source_type=user without prompting").action(
4134
- async (opts) => {
4135
- const operation = "skills.doctor.adopt-orphans";
4136
- const mvi = "standard";
4137
- let format;
4138
- try {
4139
- format = resolveFormat({
4140
- jsonFlag: opts.json ?? false,
4141
- humanFlag: opts.human ?? false,
4142
- projectDefault: "json"
4143
- });
4144
- } catch (error) {
4145
- handleFormatError(error, operation, mvi, opts.json);
4146
- }
4147
- try {
4148
- const result = await runDoctorAdopt({
4149
- nonInteractive: opts.nonInteractive ?? false,
4150
- autoUserAdopt: opts.autoUserAdopt ?? false,
4151
- loadRegisteredNames: adapters.loadRegisteredNames,
4152
- recordRow: adapters.recordRow
4153
- });
4154
- if (format === "json") {
4155
- outputSuccess(operation, mvi, result);
4156
- return;
4157
- }
4158
- const ok = result.results.filter((r) => r.applied);
4159
- const blocked = result.results.filter((r) => !r.applied);
4160
- console.log(pc2.bold(`
4161
- skills doctor adopt-orphans (${result.mode})
4162
- `));
4163
- console.log(
4164
- ` ${pc2.bold("Discovered")}: ${result.totalOrphans} orphan${result.totalOrphans === 1 ? "" : "s"}`
4165
- );
4166
- for (const r of result.results) {
4167
- const icon = r.decision === "skip" ? pc2.dim("\xB7") : r.applied ? pc2.green("\u2713") : pc2.red("\u2717");
4168
- const verb = r.applied ? r.decision : `${r.decision} (refused)`;
4169
- console.log(` ${icon} ${r.orphan.name.padEnd(32)} ${pc2.dim(verb)}`);
4170
- if (r.refusal) {
4171
- console.log(` ${pc2.yellow(r.refusal.message)}`);
4172
- console.log(` ${pc2.dim(r.refusal.remediation)}`);
4173
- }
4174
- if (r.archivedTo) {
4175
- console.log(` ${pc2.dim(`archived \u2192 ${r.archivedTo}`)}`);
4176
- }
4177
- }
4178
- console.log(
4179
- `
4180
- ${pc2.bold("Summary")}: ${pc2.green(`${ok.length} applied`)}, ${pc2.red(`${blocked.length} blocked`)}`
4181
- );
4182
- if (result.auditLogPath) {
4183
- console.log(` ${pc2.dim(`audit log \u2192 ${result.auditLogPath}`)}`);
4184
- }
4185
- console.log();
4186
- } catch (error) {
4187
- const message = error instanceof Error ? error.message : String(error);
4188
- if (format === "json") {
4189
- emitJsonError(
4190
- operation,
4191
- mvi,
4192
- ErrorCodes.INTERNAL_ERROR,
4193
- message,
4194
- ErrorCategories.INTERNAL
4195
- );
4196
- } else {
4197
- console.error(pc2.red(`Error: ${message}`));
4198
- }
4199
- process.exit(1);
4200
- }
4201
- }
4202
- );
4203
- }
4204
-
4205
3452
  // src/core/network/fetch.ts
4206
3453
  var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
4207
3454
  var NetworkError = class extends Error {
@@ -4778,9 +4025,9 @@ async function recommendSkills2(query, criteria, options = {}) {
4778
4025
  }
4779
4026
 
4780
4027
  // src/core/skills/library-loader.ts
4781
- import { existsSync as existsSync14, readdirSync as readdirSync3, readFileSync } from "fs";
4028
+ import { existsSync as existsSync12, readdirSync, readFileSync } from "fs";
4782
4029
  import { createRequire } from "module";
4783
- import { basename as basename3, dirname as dirname4, join as join8 } from "path";
4030
+ import { basename as basename3, dirname as dirname3, join as join6 } from "path";
4784
4031
  var require2 = createRequire(import.meta.url);
4785
4032
  function loadLibraryFromModule(root) {
4786
4033
  let mod;
@@ -4826,16 +4073,16 @@ function loadLibraryFromModule(root) {
4826
4073
  return mod;
4827
4074
  }
4828
4075
  function buildLibraryFromFiles(root) {
4829
- const catalogPath = join8(root, "skills.json");
4830
- if (!existsSync14(catalogPath)) {
4076
+ const catalogPath = join6(root, "skills.json");
4077
+ if (!existsSync12(catalogPath)) {
4831
4078
  throw new Error(`No skills.json found at ${root}`);
4832
4079
  }
4833
4080
  const catalogData = JSON.parse(readFileSync(catalogPath, "utf-8"));
4834
4081
  const entries = catalogData.skills ?? [];
4835
4082
  const version = catalogData.version ?? "0.0.0";
4836
- const manifestPath = join8(root, "skills", "manifest.json");
4083
+ const manifestPath = join6(root, "skills", "manifest.json");
4837
4084
  let manifest;
4838
- if (existsSync14(manifestPath)) {
4085
+ if (existsSync12(manifestPath)) {
4839
4086
  manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
4840
4087
  } else {
4841
4088
  manifest = {
@@ -4845,14 +4092,14 @@ function buildLibraryFromFiles(root) {
4845
4092
  skills: []
4846
4093
  };
4847
4094
  }
4848
- const profilesDir = join8(root, "profiles");
4095
+ const profilesDir = join6(root, "profiles");
4849
4096
  const profiles = /* @__PURE__ */ new Map();
4850
- if (existsSync14(profilesDir)) {
4851
- for (const file of readdirSync3(profilesDir)) {
4097
+ if (existsSync12(profilesDir)) {
4098
+ for (const file of readdirSync(profilesDir)) {
4852
4099
  if (!file.endsWith(".json")) continue;
4853
4100
  try {
4854
4101
  const profile = JSON.parse(
4855
- readFileSync(join8(profilesDir, file), "utf-8")
4102
+ readFileSync(join6(profilesDir, file), "utf-8")
4856
4103
  );
4857
4104
  profiles.set(profile.name, profile);
4858
4105
  } catch {
@@ -4866,9 +4113,9 @@ function buildLibraryFromFiles(root) {
4866
4113
  function getSkillDir2(name) {
4867
4114
  const entry = skillMap.get(name);
4868
4115
  if (entry) {
4869
- return dirname4(join8(root, entry.path));
4116
+ return dirname3(join6(root, entry.path));
4870
4117
  }
4871
- return join8(root, "skills", name);
4118
+ return join6(root, "skills", name);
4872
4119
  }
4873
4120
  function resolveDeps(names, visited = /* @__PURE__ */ new Set()) {
4874
4121
  const result = [];
@@ -4896,8 +4143,8 @@ function buildLibraryFromFiles(root) {
4896
4143
  return resolveDeps([...new Set(skills)]);
4897
4144
  }
4898
4145
  function discoverFiles(dir, ext) {
4899
- if (!existsSync14(dir)) return [];
4900
- return readdirSync3(dir).filter((f) => f.endsWith(ext)).map((f) => basename3(f, ext));
4146
+ if (!existsSync12(dir)) return [];
4147
+ return readdirSync(dir).filter((f) => f.endsWith(ext)).map((f) => basename3(f, ext));
4901
4148
  }
4902
4149
  const library = {
4903
4150
  version,
@@ -4913,14 +4160,14 @@ function buildLibraryFromFiles(root) {
4913
4160
  getSkillPath(name) {
4914
4161
  const entry = skillMap.get(name);
4915
4162
  if (entry) {
4916
- return join8(root, entry.path);
4163
+ return join6(root, entry.path);
4917
4164
  }
4918
- return join8(root, "skills", name, "SKILL.md");
4165
+ return join6(root, "skills", name, "SKILL.md");
4919
4166
  },
4920
4167
  getSkillDir: getSkillDir2,
4921
4168
  readSkillContent(name) {
4922
4169
  const skillPath = library.getSkillPath(name);
4923
- if (!existsSync14(skillPath)) {
4170
+ if (!existsSync12(skillPath)) {
4924
4171
  throw new Error(`Skill content not found: ${skillPath}`);
4925
4172
  }
4926
4173
  return readFileSync(skillPath, "utf-8");
@@ -4947,11 +4194,11 @@ function buildLibraryFromFiles(root) {
4947
4194
  return resolveProfileByName(name);
4948
4195
  },
4949
4196
  listSharedResources() {
4950
- return discoverFiles(join8(root, "skills", "_shared"), ".md");
4197
+ return discoverFiles(join6(root, "skills", "_shared"), ".md");
4951
4198
  },
4952
4199
  getSharedResourcePath(name) {
4953
- const resourcePath = join8(root, "skills", "_shared", `${name}.md`);
4954
- return existsSync14(resourcePath) ? resourcePath : void 0;
4200
+ const resourcePath = join6(root, "skills", "_shared", `${name}.md`);
4201
+ return existsSync12(resourcePath) ? resourcePath : void 0;
4955
4202
  },
4956
4203
  readSharedResource(name) {
4957
4204
  const resourcePath = library.getSharedResourcePath(name);
@@ -4959,15 +4206,15 @@ function buildLibraryFromFiles(root) {
4959
4206
  return readFileSync(resourcePath, "utf-8");
4960
4207
  },
4961
4208
  listProtocols() {
4962
- const rootProtocols = discoverFiles(join8(root, "protocols"), ".md");
4209
+ const rootProtocols = discoverFiles(join6(root, "protocols"), ".md");
4963
4210
  if (rootProtocols.length > 0) return rootProtocols;
4964
- return discoverFiles(join8(root, "skills", "protocols"), ".md");
4211
+ return discoverFiles(join6(root, "skills", "protocols"), ".md");
4965
4212
  },
4966
4213
  getProtocolPath(name) {
4967
- const rootPath = join8(root, "protocols", `${name}.md`);
4968
- if (existsSync14(rootPath)) return rootPath;
4969
- const skillsPath = join8(root, "skills", "protocols", `${name}.md`);
4970
- return existsSync14(skillsPath) ? skillsPath : void 0;
4214
+ const rootPath = join6(root, "protocols", `${name}.md`);
4215
+ if (existsSync12(rootPath)) return rootPath;
4216
+ const skillsPath = join6(root, "skills", "protocols", `${name}.md`);
4217
+ return existsSync12(skillsPath) ? skillsPath : void 0;
4971
4218
  },
4972
4219
  readProtocol(name) {
4973
4220
  const protocolPath = library.getProtocolPath(name);
@@ -4992,8 +4239,8 @@ function buildLibraryFromFiles(root) {
4992
4239
  if (!entry.version) {
4993
4240
  issues.push({ level: "warn", field: "version", message: "Missing version" });
4994
4241
  }
4995
- const skillPath = join8(root, entry.path);
4996
- if (!existsSync14(skillPath)) {
4242
+ const skillPath = join6(root, entry.path);
4243
+ if (!existsSync12(skillPath)) {
4997
4244
  issues.push({
4998
4245
  level: "error",
4999
4246
  field: "path",
@@ -5052,15 +4299,15 @@ __export(catalog_exports, {
5052
4299
  validateAll: () => validateAll,
5053
4300
  validateSkillFrontmatter: () => validateSkillFrontmatter
5054
4301
  });
5055
- import { existsSync as existsSync15 } from "fs";
5056
- import { join as join9 } from "path";
4302
+ import { existsSync as existsSync13 } from "fs";
4303
+ import { join as join7 } from "path";
5057
4304
  var _library = null;
5058
4305
  function registerSkillLibrary(library) {
5059
4306
  _library = library;
5060
4307
  }
5061
4308
  function registerSkillLibraryFromPath(root) {
5062
- const indexPath = join9(root, "index.js");
5063
- if (existsSync15(indexPath)) {
4309
+ const indexPath = join7(root, "index.js");
4310
+ if (existsSync13(indexPath)) {
5064
4311
  _library = loadLibraryFromModule(root);
5065
4312
  return;
5066
4313
  }
@@ -5071,13 +4318,13 @@ function clearRegisteredLibrary() {
5071
4318
  }
5072
4319
  function discoverLibrary() {
5073
4320
  const envPath = process.env["CAAMP_SKILL_LIBRARY"];
5074
- if (envPath && existsSync15(envPath)) {
4321
+ if (envPath && existsSync13(envPath)) {
5075
4322
  try {
5076
- const indexPath = join9(envPath, "index.js");
5077
- if (existsSync15(indexPath)) {
4323
+ const indexPath = join7(envPath, "index.js");
4324
+ if (existsSync13(indexPath)) {
5078
4325
  return loadLibraryFromModule(envPath);
5079
4326
  }
5080
- if (existsSync15(join9(envPath, "skills.json"))) {
4327
+ if (existsSync13(join7(envPath, "skills.json"))) {
5081
4328
  return buildLibraryFromFiles(envPath);
5082
4329
  }
5083
4330
  } catch {
@@ -5184,9 +4431,9 @@ function getLibraryRoot() {
5184
4431
  }
5185
4432
 
5186
4433
  // src/core/skills/discovery.ts
5187
- import { existsSync as existsSync16 } from "fs";
5188
- import { readdir as readdir3, readFile as readFile7 } from "fs/promises";
5189
- import { join as join10 } from "path";
4434
+ import { existsSync as existsSync14 } from "fs";
4435
+ import { readdir as readdir2, readFile as readFile7 } from "fs/promises";
4436
+ import { join as join8 } from "path";
5190
4437
  import matter from "gray-matter";
5191
4438
  async function parseSkillFile(filePath) {
5192
4439
  try {
@@ -5210,8 +4457,8 @@ async function parseSkillFile(filePath) {
5210
4457
  }
5211
4458
  }
5212
4459
  async function discoverSkill(skillDir) {
5213
- const skillFile = join10(skillDir, "SKILL.md");
5214
- if (!existsSync16(skillFile)) return null;
4460
+ const skillFile = join8(skillDir, "SKILL.md");
4461
+ if (!existsSync14(skillFile)) return null;
5215
4462
  const metadata = await parseSkillFile(skillFile);
5216
4463
  if (!metadata) return null;
5217
4464
  return {
@@ -5222,12 +4469,12 @@ async function discoverSkill(skillDir) {
5222
4469
  };
5223
4470
  }
5224
4471
  async function discoverSkills(rootDir) {
5225
- if (!existsSync16(rootDir)) return [];
5226
- const entries = await readdir3(rootDir, { withFileTypes: true });
4472
+ if (!existsSync14(rootDir)) return [];
4473
+ const entries = await readdir2(rootDir, { withFileTypes: true });
5227
4474
  const skills = [];
5228
4475
  for (const entry of entries) {
5229
4476
  if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
5230
- const skillDir = join10(rootDir, entry.name);
4477
+ const skillDir = join8(rootDir, entry.name);
5231
4478
  const skill = await discoverSkill(skillDir);
5232
4479
  if (skill) {
5233
4480
  skills.push(skill);
@@ -5251,7 +4498,7 @@ async function discoverSkillsMulti(dirs) {
5251
4498
  }
5252
4499
 
5253
4500
  // src/core/skills/validator.ts
5254
- import { existsSync as existsSync17 } from "fs";
4501
+ import { existsSync as existsSync15 } from "fs";
5255
4502
  import { readFile as readFile8 } from "fs/promises";
5256
4503
  import matter2 from "gray-matter";
5257
4504
  var RESERVED_NAMES = [
@@ -5273,7 +4520,7 @@ var WARN_BODY_LINES = 500;
5273
4520
  var WARN_DESCRIPTION_LENGTH = 50;
5274
4521
  async function validateSkill(filePath) {
5275
4522
  const issues = [];
5276
- if (!existsSync17(filePath)) {
4523
+ if (!existsSync15(filePath)) {
5277
4524
  return {
5278
4525
  valid: false,
5279
4526
  issues: [{ level: "error", field: "file", message: "File does not exist" }],
@@ -5390,7 +4637,6 @@ async function validateSkill(filePath) {
5390
4637
  }
5391
4638
 
5392
4639
  export {
5393
- CANONICAL_SKILLS_DIR,
5394
4640
  setVerbose,
5395
4641
  setQuiet,
5396
4642
  isVerbose,
@@ -5429,14 +4675,6 @@ export {
5429
4675
  readConfig,
5430
4676
  writeConfig,
5431
4677
  removeConfig,
5432
- resolveFormat,
5433
- buildEnvelope,
5434
- emitError,
5435
- emitJsonError,
5436
- outputSuccess,
5437
- handleFormatError,
5438
- ErrorCategories,
5439
- ErrorCodes,
5440
4678
  readLockFile,
5441
4679
  resolveMcpConfigPath,
5442
4680
  listMcpServers,
@@ -5457,16 +4695,6 @@ export {
5457
4695
  getTrackedSkills,
5458
4696
  checkSkillUpdate,
5459
4697
  checkAllSkillUpdates,
5460
- AgentsSkillsRealDirError,
5461
- buildBackupTimestamp,
5462
- runDoctorBridge,
5463
- registerDoctorBridge,
5464
- discoverOrphans,
5465
- applyDecision,
5466
- writeAuditLog,
5467
- runDoctorAdopt,
5468
- caampStandaloneAdapters,
5469
- registerSkillsDoctorAdopt,
5470
4698
  MarketplaceClient,
5471
4699
  RECOMMENDATION_ERROR_CODES,
5472
4700
  tokenizeCriteriaValue,
@@ -5495,4 +4723,4 @@ export {
5495
4723
  discoverSkillsMulti,
5496
4724
  validateSkill
5497
4725
  };
5498
- //# sourceMappingURL=chunk-WXL7RPS4.js.map
4726
+ //# sourceMappingURL=chunk-RTK4A3WY.js.map