@cleocode/caamp 1.1.3 → 1.3.0

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.
@@ -1134,8 +1134,8 @@ async function linkToAgent(canonicalPath, provider, skillName, isGlobal, project
1134
1134
  await mkdir2(targetSkillsDir, { recursive: true });
1135
1135
  const linkPath = join4(targetSkillsDir, skillName);
1136
1136
  if (existsSync8(linkPath)) {
1137
- const stat = lstatSync(linkPath);
1138
- if (stat.isSymbolicLink()) {
1137
+ const stat2 = lstatSync(linkPath);
1138
+ if (stat2.isSymbolicLink()) {
1139
1139
  await rm(linkPath);
1140
1140
  } else {
1141
1141
  await rm(linkPath, { recursive: true });
@@ -1287,8 +1287,8 @@ async function snapshotSkillState(providerTargets, operation, projectDir, backup
1287
1287
  pathSnapshots.push({ linkPath, state: "missing" });
1288
1288
  continue;
1289
1289
  }
1290
- const stat = lstatSync2(linkPath);
1291
- if (stat.isSymbolicLink()) {
1290
+ const stat2 = lstatSync2(linkPath);
1291
+ if (stat2.isSymbolicLink()) {
1292
1292
  pathSnapshots.push({
1293
1293
  linkPath,
1294
1294
  state: "symlink",
@@ -1298,7 +1298,7 @@ async function snapshotSkillState(providerTargets, operation, projectDir, backup
1298
1298
  }
1299
1299
  const backupPath = join5(backupRoot, "links", provider.id, `${skillName}-${basename(linkPath)}`);
1300
1300
  await mkdir3(dirname4(backupPath), { recursive: true });
1301
- if (stat.isDirectory()) {
1301
+ if (stat2.isDirectory()) {
1302
1302
  await cp2(linkPath, backupPath, { recursive: true });
1303
1303
  pathSnapshots.push({ linkPath, state: "directory", backupPath });
1304
1304
  continue;
@@ -1614,11 +1614,23 @@ async function configureProviderGlobalAndProject(provider, options) {
1614
1614
  }
1615
1615
 
1616
1616
  // src/core/lock-utils.ts
1617
- import { open, readFile as readFile6, writeFile as writeFile6, mkdir as mkdir4, rm as rm3, rename } from "fs/promises";
1617
+ import { open, readFile as readFile6, writeFile as writeFile6, mkdir as mkdir4, rm as rm3, rename, stat } from "fs/promises";
1618
1618
  import { existsSync as existsSync10 } from "fs";
1619
1619
  var LOCK_GUARD_PATH = `${LOCK_FILE_PATH}.lock`;
1620
+ var STALE_LOCK_MS = 5e3;
1620
1621
  function sleep(ms) {
1621
- return new Promise((resolve3) => setTimeout(resolve3, ms));
1622
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
1623
+ }
1624
+ async function removeStaleLock() {
1625
+ try {
1626
+ const info = await stat(LOCK_GUARD_PATH);
1627
+ if (Date.now() - info.mtimeMs > STALE_LOCK_MS) {
1628
+ await rm3(LOCK_GUARD_PATH, { force: true });
1629
+ return true;
1630
+ }
1631
+ } catch {
1632
+ }
1633
+ return false;
1622
1634
  }
1623
1635
  async function acquireLockGuard(retries = 40, delayMs = 25) {
1624
1636
  await mkdir4(AGENTS_HOME, { recursive: true });
@@ -1631,6 +1643,10 @@ async function acquireLockGuard(retries = 40, delayMs = 25) {
1631
1643
  if (!(error instanceof Error) || !("code" in error) || error.code !== "EEXIST") {
1632
1644
  throw error;
1633
1645
  }
1646
+ if (attempt === 0) {
1647
+ const removed = await removeStaleLock();
1648
+ if (removed) continue;
1649
+ }
1634
1650
  await sleep(delayMs);
1635
1651
  }
1636
1652
  }
@@ -1708,6 +1724,135 @@ async function getLastSelectedAgents() {
1708
1724
  return lock.lastSelectedAgents;
1709
1725
  }
1710
1726
 
1727
+ // src/core/mcp/cleo.ts
1728
+ import { execFileSync as execFileSync2 } from "child_process";
1729
+ import { existsSync as existsSync11 } from "fs";
1730
+ import { homedir as homedir2 } from "os";
1731
+ import { isAbsolute as isAbsolute2, resolve as resolve3 } from "path";
1732
+ var CLEO_SERVER_NAMES = {
1733
+ stable: "cleo",
1734
+ beta: "cleo-beta",
1735
+ dev: "cleo-dev"
1736
+ };
1737
+ var CLEO_MCP_NPM_PACKAGE = "@cleocode/cleo";
1738
+ var CLEO_DEV_DIR_DEFAULT = "~/.cleo-dev";
1739
+ function normalizeCleoChannel(value) {
1740
+ if (!value || value.trim() === "") return "stable";
1741
+ const normalized = value.trim().toLowerCase();
1742
+ if (normalized === "stable" || normalized === "beta" || normalized === "dev") {
1743
+ return normalized;
1744
+ }
1745
+ throw new Error(`Invalid channel "${value}". Expected stable, beta, or dev.`);
1746
+ }
1747
+ function resolveCleoServerName(channel) {
1748
+ return CLEO_SERVER_NAMES[channel];
1749
+ }
1750
+ function resolveChannelFromServerName(serverName) {
1751
+ if (serverName === CLEO_SERVER_NAMES.stable) return "stable";
1752
+ if (serverName === CLEO_SERVER_NAMES.beta) return "beta";
1753
+ if (serverName === CLEO_SERVER_NAMES.dev) return "dev";
1754
+ return null;
1755
+ }
1756
+ function splitCommand(command, explicitArgs = []) {
1757
+ if (explicitArgs.length > 0) {
1758
+ return { command, args: explicitArgs };
1759
+ }
1760
+ const parts = command.trim().split(/\s+/);
1761
+ const binary = parts[0] ?? "";
1762
+ if (!binary) {
1763
+ throw new Error("Command is required for dev channel.");
1764
+ }
1765
+ return {
1766
+ command: binary,
1767
+ args: parts.slice(1)
1768
+ };
1769
+ }
1770
+ function normalizeEnv(env, channel, cleoDir) {
1771
+ const result = { ...env ?? {} };
1772
+ if (channel === "dev" && !result.CLEO_DIR) {
1773
+ result.CLEO_DIR = cleoDir ?? CLEO_DEV_DIR_DEFAULT;
1774
+ }
1775
+ return Object.keys(result).length > 0 ? result : void 0;
1776
+ }
1777
+ function resolvePackageSpec(channel, version) {
1778
+ const tag = version?.trim() || (channel === "stable" ? "latest" : "beta");
1779
+ return `${CLEO_MCP_NPM_PACKAGE}@${tag}`;
1780
+ }
1781
+ function buildCleoProfile(options) {
1782
+ const channel = options.channel;
1783
+ const serverName = resolveCleoServerName(channel);
1784
+ if (channel === "dev") {
1785
+ if (!options.command || options.command.trim() === "") {
1786
+ throw new Error("Dev channel requires --command.");
1787
+ }
1788
+ const parsed = splitCommand(options.command, options.args ?? []);
1789
+ const env = normalizeEnv(options.env, channel, options.cleoDir);
1790
+ return {
1791
+ channel,
1792
+ serverName,
1793
+ config: {
1794
+ command: parsed.command,
1795
+ args: parsed.args,
1796
+ ...env ? { env } : {}
1797
+ }
1798
+ };
1799
+ }
1800
+ const packageSpec = resolvePackageSpec(channel, options.version);
1801
+ return {
1802
+ channel,
1803
+ serverName,
1804
+ packageSpec,
1805
+ config: {
1806
+ command: "npx",
1807
+ args: ["-y", packageSpec, "cleo-mcp"]
1808
+ }
1809
+ };
1810
+ }
1811
+ function expandHome(pathValue) {
1812
+ if (pathValue === "~") return homedir2();
1813
+ if (pathValue.startsWith("~/")) {
1814
+ return resolve3(homedir2(), pathValue.slice(2));
1815
+ }
1816
+ return pathValue;
1817
+ }
1818
+ function checkCommandReachability(command) {
1819
+ const hasPathSeparator = command.includes("/") || command.includes("\\");
1820
+ if (hasPathSeparator || command.startsWith("~")) {
1821
+ const expanded = expandHome(command);
1822
+ const candidate = isAbsolute2(expanded) ? expanded : resolve3(process.cwd(), expanded);
1823
+ if (existsSync11(candidate)) {
1824
+ return { reachable: true, method: "path", detail: candidate };
1825
+ }
1826
+ return { reachable: false, method: "path", detail: candidate };
1827
+ }
1828
+ try {
1829
+ const lookup = process.platform === "win32" ? "where" : "which";
1830
+ execFileSync2(lookup, [command], { stdio: "pipe" });
1831
+ return { reachable: true, method: "lookup", detail: command };
1832
+ } catch {
1833
+ return { reachable: false, method: "lookup", detail: command };
1834
+ }
1835
+ }
1836
+ function parseEnvAssignments(values) {
1837
+ const env = {};
1838
+ for (const value of values) {
1839
+ const idx = value.indexOf("=");
1840
+ if (idx <= 0) {
1841
+ throw new Error(`Invalid --env value "${value}". Use KEY=value.`);
1842
+ }
1843
+ const key = value.slice(0, idx).trim();
1844
+ const val = value.slice(idx + 1).trim();
1845
+ if (!key) {
1846
+ throw new Error(`Invalid --env value "${value}". Key cannot be empty.`);
1847
+ }
1848
+ env[key] = val;
1849
+ }
1850
+ return env;
1851
+ }
1852
+ function isCleoSource(source) {
1853
+ return source.trim().toLowerCase() === "cleo";
1854
+ }
1855
+
1711
1856
  // src/core/sources/parser.ts
1712
1857
  var GITHUB_SHORTHAND = /^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)(?:\/(.+))?$/;
1713
1858
  var GITHUB_URL = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+)(?:\/(?:tree|blob)\/([^/]+)(?:\/(.+))?)?/;
@@ -1715,7 +1860,12 @@ var GITLAB_URL = /^https?:\/\/(?:www\.)?gitlab\.com\/([^/]+)\/([^/]+)(?:\/-\/(?:
1715
1860
  var HTTP_URL = /^https?:\/\//;
1716
1861
  var NPM_SCOPED = /^@[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/;
1717
1862
  var NPM_PACKAGE = /^[a-zA-Z0-9_.-]+$/;
1863
+ var LIBRARY_SKILL = /^(@[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+|[a-zA-Z0-9_.-]+):([a-zA-Z0-9_.-]+)$/;
1718
1864
  function inferName(source, type) {
1865
+ if (type === "library") {
1866
+ const match = source.match(LIBRARY_SKILL);
1867
+ return match?.[2] ?? source;
1868
+ }
1719
1869
  if (type === "remote") {
1720
1870
  try {
1721
1871
  const url = new URL(source);
@@ -1829,6 +1979,18 @@ function parseSource(input) {
1829
1979
  path
1830
1980
  };
1831
1981
  }
1982
+ const libraryMatch = input.match(LIBRARY_SKILL);
1983
+ if (libraryMatch) {
1984
+ return {
1985
+ type: "library",
1986
+ value: input,
1987
+ inferredName: inferName(input, "library"),
1988
+ owner: libraryMatch[1],
1989
+ // This will be the package name, e.g. @cleocode/ct-skills
1990
+ repo: libraryMatch[2]
1991
+ // This will be the skill name, e.g. ct-research-agent
1992
+ };
1993
+ }
1832
1994
  if (NPM_SCOPED.test(input)) {
1833
1995
  return {
1834
1996
  type: "package",
@@ -2105,7 +2267,7 @@ var MarketplaceClient = class {
2105
2267
 
2106
2268
  // src/core/skills/library-loader.ts
2107
2269
  import { createRequire } from "module";
2108
- import { existsSync as existsSync11, readdirSync, readFileSync as readFileSync2 } from "fs";
2270
+ import { existsSync as existsSync12, readdirSync, readFileSync as readFileSync2 } from "fs";
2109
2271
  import { basename as basename2, dirname as dirname5, join as join6 } from "path";
2110
2272
  var require2 = createRequire(import.meta.url);
2111
2273
  function loadLibraryFromModule(root) {
@@ -2155,7 +2317,7 @@ function loadLibraryFromModule(root) {
2155
2317
  }
2156
2318
  function buildLibraryFromFiles(root) {
2157
2319
  const catalogPath = join6(root, "skills.json");
2158
- if (!existsSync11(catalogPath)) {
2320
+ if (!existsSync12(catalogPath)) {
2159
2321
  throw new Error(`No skills.json found at ${root}`);
2160
2322
  }
2161
2323
  const catalogData = JSON.parse(readFileSync2(catalogPath, "utf-8"));
@@ -2163,7 +2325,7 @@ function buildLibraryFromFiles(root) {
2163
2325
  const version = catalogData.version ?? "0.0.0";
2164
2326
  const manifestPath = join6(root, "skills", "manifest.json");
2165
2327
  let manifest;
2166
- if (existsSync11(manifestPath)) {
2328
+ if (existsSync12(manifestPath)) {
2167
2329
  manifest = JSON.parse(readFileSync2(manifestPath, "utf-8"));
2168
2330
  } else {
2169
2331
  manifest = {
@@ -2175,7 +2337,7 @@ function buildLibraryFromFiles(root) {
2175
2337
  }
2176
2338
  const profilesDir = join6(root, "profiles");
2177
2339
  const profiles = /* @__PURE__ */ new Map();
2178
- if (existsSync11(profilesDir)) {
2340
+ if (existsSync12(profilesDir)) {
2179
2341
  for (const file of readdirSync(profilesDir)) {
2180
2342
  if (!file.endsWith(".json")) continue;
2181
2343
  try {
@@ -2224,7 +2386,7 @@ function buildLibraryFromFiles(root) {
2224
2386
  return resolveDeps([...new Set(skills)]);
2225
2387
  }
2226
2388
  function discoverFiles(dir, ext) {
2227
- if (!existsSync11(dir)) return [];
2389
+ if (!existsSync12(dir)) return [];
2228
2390
  return readdirSync(dir).filter((f) => f.endsWith(ext)).map((f) => basename2(f, ext));
2229
2391
  }
2230
2392
  const library = {
@@ -2248,7 +2410,7 @@ function buildLibraryFromFiles(root) {
2248
2410
  getSkillDir: getSkillDir2,
2249
2411
  readSkillContent(name) {
2250
2412
  const skillPath = library.getSkillPath(name);
2251
- if (!existsSync11(skillPath)) {
2413
+ if (!existsSync12(skillPath)) {
2252
2414
  throw new Error(`Skill content not found: ${skillPath}`);
2253
2415
  }
2254
2416
  return readFileSync2(skillPath, "utf-8");
@@ -2279,7 +2441,7 @@ function buildLibraryFromFiles(root) {
2279
2441
  },
2280
2442
  getSharedResourcePath(name) {
2281
2443
  const resourcePath = join6(root, "skills", "_shared", `${name}.md`);
2282
- return existsSync11(resourcePath) ? resourcePath : void 0;
2444
+ return existsSync12(resourcePath) ? resourcePath : void 0;
2283
2445
  },
2284
2446
  readSharedResource(name) {
2285
2447
  const resourcePath = library.getSharedResourcePath(name);
@@ -2293,9 +2455,9 @@ function buildLibraryFromFiles(root) {
2293
2455
  },
2294
2456
  getProtocolPath(name) {
2295
2457
  const rootPath = join6(root, "protocols", `${name}.md`);
2296
- if (existsSync11(rootPath)) return rootPath;
2458
+ if (existsSync12(rootPath)) return rootPath;
2297
2459
  const skillsPath = join6(root, "skills", "protocols", `${name}.md`);
2298
- return existsSync11(skillsPath) ? skillsPath : void 0;
2460
+ return existsSync12(skillsPath) ? skillsPath : void 0;
2299
2461
  },
2300
2462
  readProtocol(name) {
2301
2463
  const protocolPath = library.getProtocolPath(name);
@@ -2321,7 +2483,7 @@ function buildLibraryFromFiles(root) {
2321
2483
  issues.push({ level: "warn", field: "version", message: "Missing version" });
2322
2484
  }
2323
2485
  const skillPath = join6(root, entry.path);
2324
- if (!existsSync11(skillPath)) {
2486
+ if (!existsSync12(skillPath)) {
2325
2487
  issues.push({ level: "error", field: "path", message: `SKILL.md not found at ${entry.path}` });
2326
2488
  }
2327
2489
  return {
@@ -2376,7 +2538,7 @@ __export(catalog_exports, {
2376
2538
  validateAll: () => validateAll,
2377
2539
  validateSkillFrontmatter: () => validateSkillFrontmatter
2378
2540
  });
2379
- import { existsSync as existsSync12 } from "fs";
2541
+ import { existsSync as existsSync13 } from "fs";
2380
2542
  import { join as join7 } from "path";
2381
2543
  var _library = null;
2382
2544
  function registerSkillLibrary(library) {
@@ -2384,7 +2546,7 @@ function registerSkillLibrary(library) {
2384
2546
  }
2385
2547
  function registerSkillLibraryFromPath(root) {
2386
2548
  const indexPath = join7(root, "index.js");
2387
- if (existsSync12(indexPath)) {
2549
+ if (existsSync13(indexPath)) {
2388
2550
  _library = loadLibraryFromModule(root);
2389
2551
  return;
2390
2552
  }
@@ -2395,31 +2557,18 @@ function clearRegisteredLibrary() {
2395
2557
  }
2396
2558
  function discoverLibrary() {
2397
2559
  const envPath = process.env["CAAMP_SKILL_LIBRARY"];
2398
- if (envPath && existsSync12(envPath)) {
2560
+ if (envPath && existsSync13(envPath)) {
2399
2561
  try {
2400
2562
  const indexPath = join7(envPath, "index.js");
2401
- if (existsSync12(indexPath)) {
2563
+ if (existsSync13(indexPath)) {
2402
2564
  return loadLibraryFromModule(envPath);
2403
2565
  }
2404
- if (existsSync12(join7(envPath, "skills.json"))) {
2566
+ if (existsSync13(join7(envPath, "skills.json"))) {
2405
2567
  return buildLibraryFromFiles(envPath);
2406
2568
  }
2407
2569
  } catch {
2408
2570
  }
2409
2571
  }
2410
- const canonicalPath = join7(getAgentsHome(), "skill-library");
2411
- if (existsSync12(canonicalPath)) {
2412
- try {
2413
- const indexPath = join7(canonicalPath, "index.js");
2414
- if (existsSync12(indexPath)) {
2415
- return loadLibraryFromModule(canonicalPath);
2416
- }
2417
- if (existsSync12(join7(canonicalPath, "skills.json"))) {
2418
- return buildLibraryFromFiles(canonicalPath);
2419
- }
2420
- } catch {
2421
- }
2422
- }
2423
2572
  return null;
2424
2573
  }
2425
2574
  function getLibrary() {
@@ -2522,7 +2671,7 @@ function getLibraryRoot() {
2522
2671
 
2523
2672
  // src/core/skills/discovery.ts
2524
2673
  import { readFile as readFile7, readdir } from "fs/promises";
2525
- import { existsSync as existsSync13 } from "fs";
2674
+ import { existsSync as existsSync14 } from "fs";
2526
2675
  import { join as join8 } from "path";
2527
2676
  import matter from "gray-matter";
2528
2677
  async function parseSkillFile(filePath) {
@@ -2548,7 +2697,7 @@ async function parseSkillFile(filePath) {
2548
2697
  }
2549
2698
  async function discoverSkill(skillDir) {
2550
2699
  const skillFile = join8(skillDir, "SKILL.md");
2551
- if (!existsSync13(skillFile)) return null;
2700
+ if (!existsSync14(skillFile)) return null;
2552
2701
  const metadata = await parseSkillFile(skillFile);
2553
2702
  if (!metadata) return null;
2554
2703
  return {
@@ -2559,7 +2708,7 @@ async function discoverSkill(skillDir) {
2559
2708
  };
2560
2709
  }
2561
2710
  async function discoverSkills(rootDir) {
2562
- if (!existsSync13(rootDir)) return [];
2711
+ if (!existsSync14(rootDir)) return [];
2563
2712
  const entries = await readdir(rootDir, { withFileTypes: true });
2564
2713
  const skills = [];
2565
2714
  for (const entry of entries) {
@@ -2589,6 +2738,9 @@ async function discoverSkillsMulti(dirs) {
2589
2738
 
2590
2739
  // src/core/skills/lock.ts
2591
2740
  import { simpleGit } from "simple-git";
2741
+ import { execFile } from "child_process";
2742
+ import { promisify } from "util";
2743
+ var execFileAsync = promisify(execFile);
2592
2744
  async function recordSkillInstall(skillName, scopedName, source, sourceType, agents, canonicalPath, isGlobal, projectDir, version) {
2593
2745
  await updateLockFile((lock) => {
2594
2746
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -2635,13 +2787,21 @@ async function fetchLatestSha(repoUrl, ref) {
2635
2787
  return null;
2636
2788
  }
2637
2789
  }
2790
+ async function fetchLatestPackageVersion(packageName) {
2791
+ try {
2792
+ const { stdout } = await execFileAsync("npm", ["view", packageName, "version"]);
2793
+ return stdout.trim() || null;
2794
+ } catch {
2795
+ return null;
2796
+ }
2797
+ }
2638
2798
  async function checkSkillUpdate(skillName) {
2639
2799
  const lock = await readLockFile();
2640
2800
  const entry = lock.skills[skillName];
2641
2801
  if (!entry) {
2642
2802
  return { hasUpdate: false, status: "unknown" };
2643
2803
  }
2644
- if (entry.sourceType !== "github" && entry.sourceType !== "gitlab") {
2804
+ if (entry.sourceType !== "github" && entry.sourceType !== "gitlab" && entry.sourceType !== "library") {
2645
2805
  return {
2646
2806
  hasUpdate: false,
2647
2807
  currentVersion: entry.version,
@@ -2649,7 +2809,33 @@ async function checkSkillUpdate(skillName) {
2649
2809
  };
2650
2810
  }
2651
2811
  const parsed = parseSource(entry.source);
2652
- if (!parsed.owner || !parsed.repo) {
2812
+ if (!parsed.owner) {
2813
+ return {
2814
+ hasUpdate: false,
2815
+ currentVersion: entry.version,
2816
+ status: "unknown"
2817
+ };
2818
+ }
2819
+ if (entry.sourceType === "library") {
2820
+ const packageName = parsed.owner;
2821
+ const latestVersion = await fetchLatestPackageVersion(packageName);
2822
+ if (!latestVersion) {
2823
+ return {
2824
+ hasUpdate: false,
2825
+ currentVersion: entry.version,
2826
+ status: "unknown"
2827
+ };
2828
+ }
2829
+ const currentVersion2 = entry.version;
2830
+ const hasUpdate2 = !currentVersion2 || currentVersion2 !== latestVersion;
2831
+ return {
2832
+ hasUpdate: hasUpdate2,
2833
+ currentVersion: currentVersion2 ?? "unknown",
2834
+ latestVersion,
2835
+ status: hasUpdate2 ? "update-available" : "up-to-date"
2836
+ };
2837
+ }
2838
+ if (!parsed.repo) {
2653
2839
  return {
2654
2840
  hasUpdate: false,
2655
2841
  currentVersion: entry.version,
@@ -2675,6 +2861,15 @@ async function checkSkillUpdate(skillName) {
2675
2861
  status: hasUpdate ? "update-available" : "up-to-date"
2676
2862
  };
2677
2863
  }
2864
+ async function checkAllSkillUpdates() {
2865
+ const lock = await readLockFile();
2866
+ const skillNames = Object.keys(lock.skills);
2867
+ const results = {};
2868
+ await Promise.all(skillNames.map(async (name) => {
2869
+ results[name] = await checkSkillUpdate(name);
2870
+ }));
2871
+ return results;
2872
+ }
2678
2873
 
2679
2874
  // src/core/skills/recommendation.ts
2680
2875
  var RECOMMENDATION_ERROR_CODES = {
@@ -2944,7 +3139,7 @@ async function recommendSkills2(query, criteria, options = {}) {
2944
3139
  }
2945
3140
 
2946
3141
  // src/core/skills/audit/scanner.ts
2947
- import { existsSync as existsSync14 } from "fs";
3142
+ import { existsSync as existsSync15 } from "fs";
2948
3143
  import { readFile as readFile8 } from "fs/promises";
2949
3144
 
2950
3145
  // src/core/skills/audit/rules.ts
@@ -3324,7 +3519,7 @@ var SEVERITY_WEIGHTS = {
3324
3519
  info: 0
3325
3520
  };
3326
3521
  async function scanFile(filePath, rules) {
3327
- if (!existsSync14(filePath)) {
3522
+ if (!existsSync15(filePath)) {
3328
3523
  return { file: filePath, findings: [], score: 100, passed: true };
3329
3524
  }
3330
3525
  const content = await readFile8(filePath, "utf-8");
@@ -3357,13 +3552,13 @@ async function scanFile(filePath, rules) {
3357
3552
  async function scanDirectory(dirPath) {
3358
3553
  const { readdir: readdir2 } = await import("fs/promises");
3359
3554
  const { join: join9 } = await import("path");
3360
- if (!existsSync14(dirPath)) return [];
3555
+ if (!existsSync15(dirPath)) return [];
3361
3556
  const entries = await readdir2(dirPath, { withFileTypes: true });
3362
3557
  const results = [];
3363
3558
  for (const entry of entries) {
3364
3559
  if (entry.isDirectory() || entry.isSymbolicLink()) {
3365
3560
  const skillFile = join9(dirPath, entry.name, "SKILL.md");
3366
- if (existsSync14(skillFile)) {
3561
+ if (existsSync15(skillFile)) {
3367
3562
  results.push(await scanFile(skillFile));
3368
3563
  }
3369
3564
  }
@@ -3416,7 +3611,7 @@ function toSarif(results) {
3416
3611
 
3417
3612
  // src/core/skills/validator.ts
3418
3613
  import { readFile as readFile9 } from "fs/promises";
3419
- import { existsSync as existsSync15 } from "fs";
3614
+ import { existsSync as existsSync16 } from "fs";
3420
3615
  import matter2 from "gray-matter";
3421
3616
  var RESERVED_NAMES = [
3422
3617
  "anthropic",
@@ -3437,7 +3632,7 @@ var WARN_BODY_LINES = 500;
3437
3632
  var WARN_DESCRIPTION_LENGTH = 50;
3438
3633
  async function validateSkill(filePath) {
3439
3634
  const issues = [];
3440
- if (!existsSync15(filePath)) {
3635
+ if (!existsSync16(filePath)) {
3441
3636
  return {
3442
3637
  valid: false,
3443
3638
  issues: [{ level: "error", field: "file", message: "File does not exist" }],
@@ -3628,6 +3823,13 @@ export {
3628
3823
  getTrackedMcpServers,
3629
3824
  saveLastSelectedAgents,
3630
3825
  getLastSelectedAgents,
3826
+ normalizeCleoChannel,
3827
+ resolveCleoServerName,
3828
+ resolveChannelFromServerName,
3829
+ buildCleoProfile,
3830
+ checkCommandReachability,
3831
+ parseEnvAssignments,
3832
+ isCleoSource,
3631
3833
  parseSource,
3632
3834
  isMarketplaceScoped,
3633
3835
  formatNetworkError,
@@ -3652,6 +3854,7 @@ export {
3652
3854
  removeSkillFromLock,
3653
3855
  getTrackedSkills,
3654
3856
  checkSkillUpdate,
3857
+ checkAllSkillUpdates,
3655
3858
  RECOMMENDATION_ERROR_CODES,
3656
3859
  tokenizeCriteriaValue,
3657
3860
  validateRecommendationCriteria,
@@ -3666,4 +3869,4 @@ export {
3666
3869
  toSarif,
3667
3870
  validateSkill
3668
3871
  };
3669
- //# sourceMappingURL=chunk-7YV3KXEJ.js.map
3872
+ //# sourceMappingURL=chunk-O2YG5HT7.js.map