@cleocode/caamp 1.2.1 → 1.3.1

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.
@@ -1619,7 +1619,7 @@ import { existsSync as existsSync10 } from "fs";
1619
1619
  var LOCK_GUARD_PATH = `${LOCK_FILE_PATH}.lock`;
1620
1620
  var STALE_LOCK_MS = 5e3;
1621
1621
  function sleep(ms) {
1622
- return new Promise((resolve3) => setTimeout(resolve3, ms));
1622
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
1623
1623
  }
1624
1624
  async function removeStaleLock() {
1625
1625
  try {
@@ -1724,6 +1724,135 @@ async function getLastSelectedAgents() {
1724
1724
  return lock.lastSelectedAgents;
1725
1725
  }
1726
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, "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
+
1727
1856
  // src/core/sources/parser.ts
1728
1857
  var GITHUB_SHORTHAND = /^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)(?:\/(.+))?$/;
1729
1858
  var GITHUB_URL = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+)(?:\/(?:tree|blob)\/([^/]+)(?:\/(.+))?)?/;
@@ -2138,7 +2267,7 @@ var MarketplaceClient = class {
2138
2267
 
2139
2268
  // src/core/skills/library-loader.ts
2140
2269
  import { createRequire } from "module";
2141
- import { existsSync as existsSync11, readdirSync, readFileSync as readFileSync2 } from "fs";
2270
+ import { existsSync as existsSync12, readdirSync, readFileSync as readFileSync2 } from "fs";
2142
2271
  import { basename as basename2, dirname as dirname5, join as join6 } from "path";
2143
2272
  var require2 = createRequire(import.meta.url);
2144
2273
  function loadLibraryFromModule(root) {
@@ -2188,7 +2317,7 @@ function loadLibraryFromModule(root) {
2188
2317
  }
2189
2318
  function buildLibraryFromFiles(root) {
2190
2319
  const catalogPath = join6(root, "skills.json");
2191
- if (!existsSync11(catalogPath)) {
2320
+ if (!existsSync12(catalogPath)) {
2192
2321
  throw new Error(`No skills.json found at ${root}`);
2193
2322
  }
2194
2323
  const catalogData = JSON.parse(readFileSync2(catalogPath, "utf-8"));
@@ -2196,7 +2325,7 @@ function buildLibraryFromFiles(root) {
2196
2325
  const version = catalogData.version ?? "0.0.0";
2197
2326
  const manifestPath = join6(root, "skills", "manifest.json");
2198
2327
  let manifest;
2199
- if (existsSync11(manifestPath)) {
2328
+ if (existsSync12(manifestPath)) {
2200
2329
  manifest = JSON.parse(readFileSync2(manifestPath, "utf-8"));
2201
2330
  } else {
2202
2331
  manifest = {
@@ -2208,7 +2337,7 @@ function buildLibraryFromFiles(root) {
2208
2337
  }
2209
2338
  const profilesDir = join6(root, "profiles");
2210
2339
  const profiles = /* @__PURE__ */ new Map();
2211
- if (existsSync11(profilesDir)) {
2340
+ if (existsSync12(profilesDir)) {
2212
2341
  for (const file of readdirSync(profilesDir)) {
2213
2342
  if (!file.endsWith(".json")) continue;
2214
2343
  try {
@@ -2257,7 +2386,7 @@ function buildLibraryFromFiles(root) {
2257
2386
  return resolveDeps([...new Set(skills)]);
2258
2387
  }
2259
2388
  function discoverFiles(dir, ext) {
2260
- if (!existsSync11(dir)) return [];
2389
+ if (!existsSync12(dir)) return [];
2261
2390
  return readdirSync(dir).filter((f) => f.endsWith(ext)).map((f) => basename2(f, ext));
2262
2391
  }
2263
2392
  const library = {
@@ -2281,7 +2410,7 @@ function buildLibraryFromFiles(root) {
2281
2410
  getSkillDir: getSkillDir2,
2282
2411
  readSkillContent(name) {
2283
2412
  const skillPath = library.getSkillPath(name);
2284
- if (!existsSync11(skillPath)) {
2413
+ if (!existsSync12(skillPath)) {
2285
2414
  throw new Error(`Skill content not found: ${skillPath}`);
2286
2415
  }
2287
2416
  return readFileSync2(skillPath, "utf-8");
@@ -2312,7 +2441,7 @@ function buildLibraryFromFiles(root) {
2312
2441
  },
2313
2442
  getSharedResourcePath(name) {
2314
2443
  const resourcePath = join6(root, "skills", "_shared", `${name}.md`);
2315
- return existsSync11(resourcePath) ? resourcePath : void 0;
2444
+ return existsSync12(resourcePath) ? resourcePath : void 0;
2316
2445
  },
2317
2446
  readSharedResource(name) {
2318
2447
  const resourcePath = library.getSharedResourcePath(name);
@@ -2326,9 +2455,9 @@ function buildLibraryFromFiles(root) {
2326
2455
  },
2327
2456
  getProtocolPath(name) {
2328
2457
  const rootPath = join6(root, "protocols", `${name}.md`);
2329
- if (existsSync11(rootPath)) return rootPath;
2458
+ if (existsSync12(rootPath)) return rootPath;
2330
2459
  const skillsPath = join6(root, "skills", "protocols", `${name}.md`);
2331
- return existsSync11(skillsPath) ? skillsPath : void 0;
2460
+ return existsSync12(skillsPath) ? skillsPath : void 0;
2332
2461
  },
2333
2462
  readProtocol(name) {
2334
2463
  const protocolPath = library.getProtocolPath(name);
@@ -2354,7 +2483,7 @@ function buildLibraryFromFiles(root) {
2354
2483
  issues.push({ level: "warn", field: "version", message: "Missing version" });
2355
2484
  }
2356
2485
  const skillPath = join6(root, entry.path);
2357
- if (!existsSync11(skillPath)) {
2486
+ if (!existsSync12(skillPath)) {
2358
2487
  issues.push({ level: "error", field: "path", message: `SKILL.md not found at ${entry.path}` });
2359
2488
  }
2360
2489
  return {
@@ -2409,7 +2538,7 @@ __export(catalog_exports, {
2409
2538
  validateAll: () => validateAll,
2410
2539
  validateSkillFrontmatter: () => validateSkillFrontmatter
2411
2540
  });
2412
- import { existsSync as existsSync12 } from "fs";
2541
+ import { existsSync as existsSync13 } from "fs";
2413
2542
  import { join as join7 } from "path";
2414
2543
  var _library = null;
2415
2544
  function registerSkillLibrary(library) {
@@ -2417,7 +2546,7 @@ function registerSkillLibrary(library) {
2417
2546
  }
2418
2547
  function registerSkillLibraryFromPath(root) {
2419
2548
  const indexPath = join7(root, "index.js");
2420
- if (existsSync12(indexPath)) {
2549
+ if (existsSync13(indexPath)) {
2421
2550
  _library = loadLibraryFromModule(root);
2422
2551
  return;
2423
2552
  }
@@ -2428,13 +2557,13 @@ function clearRegisteredLibrary() {
2428
2557
  }
2429
2558
  function discoverLibrary() {
2430
2559
  const envPath = process.env["CAAMP_SKILL_LIBRARY"];
2431
- if (envPath && existsSync12(envPath)) {
2560
+ if (envPath && existsSync13(envPath)) {
2432
2561
  try {
2433
2562
  const indexPath = join7(envPath, "index.js");
2434
- if (existsSync12(indexPath)) {
2563
+ if (existsSync13(indexPath)) {
2435
2564
  return loadLibraryFromModule(envPath);
2436
2565
  }
2437
- if (existsSync12(join7(envPath, "skills.json"))) {
2566
+ if (existsSync13(join7(envPath, "skills.json"))) {
2438
2567
  return buildLibraryFromFiles(envPath);
2439
2568
  }
2440
2569
  } catch {
@@ -2542,7 +2671,7 @@ function getLibraryRoot() {
2542
2671
 
2543
2672
  // src/core/skills/discovery.ts
2544
2673
  import { readFile as readFile7, readdir } from "fs/promises";
2545
- import { existsSync as existsSync13 } from "fs";
2674
+ import { existsSync as existsSync14 } from "fs";
2546
2675
  import { join as join8 } from "path";
2547
2676
  import matter from "gray-matter";
2548
2677
  async function parseSkillFile(filePath) {
@@ -2568,7 +2697,7 @@ async function parseSkillFile(filePath) {
2568
2697
  }
2569
2698
  async function discoverSkill(skillDir) {
2570
2699
  const skillFile = join8(skillDir, "SKILL.md");
2571
- if (!existsSync13(skillFile)) return null;
2700
+ if (!existsSync14(skillFile)) return null;
2572
2701
  const metadata = await parseSkillFile(skillFile);
2573
2702
  if (!metadata) return null;
2574
2703
  return {
@@ -2579,7 +2708,7 @@ async function discoverSkill(skillDir) {
2579
2708
  };
2580
2709
  }
2581
2710
  async function discoverSkills(rootDir) {
2582
- if (!existsSync13(rootDir)) return [];
2711
+ if (!existsSync14(rootDir)) return [];
2583
2712
  const entries = await readdir(rootDir, { withFileTypes: true });
2584
2713
  const skills = [];
2585
2714
  for (const entry of entries) {
@@ -3010,7 +3139,7 @@ async function recommendSkills2(query, criteria, options = {}) {
3010
3139
  }
3011
3140
 
3012
3141
  // src/core/skills/audit/scanner.ts
3013
- import { existsSync as existsSync14 } from "fs";
3142
+ import { existsSync as existsSync15 } from "fs";
3014
3143
  import { readFile as readFile8 } from "fs/promises";
3015
3144
 
3016
3145
  // src/core/skills/audit/rules.ts
@@ -3390,7 +3519,7 @@ var SEVERITY_WEIGHTS = {
3390
3519
  info: 0
3391
3520
  };
3392
3521
  async function scanFile(filePath, rules) {
3393
- if (!existsSync14(filePath)) {
3522
+ if (!existsSync15(filePath)) {
3394
3523
  return { file: filePath, findings: [], score: 100, passed: true };
3395
3524
  }
3396
3525
  const content = await readFile8(filePath, "utf-8");
@@ -3423,13 +3552,13 @@ async function scanFile(filePath, rules) {
3423
3552
  async function scanDirectory(dirPath) {
3424
3553
  const { readdir: readdir2 } = await import("fs/promises");
3425
3554
  const { join: join9 } = await import("path");
3426
- if (!existsSync14(dirPath)) return [];
3555
+ if (!existsSync15(dirPath)) return [];
3427
3556
  const entries = await readdir2(dirPath, { withFileTypes: true });
3428
3557
  const results = [];
3429
3558
  for (const entry of entries) {
3430
3559
  if (entry.isDirectory() || entry.isSymbolicLink()) {
3431
3560
  const skillFile = join9(dirPath, entry.name, "SKILL.md");
3432
- if (existsSync14(skillFile)) {
3561
+ if (existsSync15(skillFile)) {
3433
3562
  results.push(await scanFile(skillFile));
3434
3563
  }
3435
3564
  }
@@ -3482,7 +3611,7 @@ function toSarif(results) {
3482
3611
 
3483
3612
  // src/core/skills/validator.ts
3484
3613
  import { readFile as readFile9 } from "fs/promises";
3485
- import { existsSync as existsSync15 } from "fs";
3614
+ import { existsSync as existsSync16 } from "fs";
3486
3615
  import matter2 from "gray-matter";
3487
3616
  var RESERVED_NAMES = [
3488
3617
  "anthropic",
@@ -3503,7 +3632,7 @@ var WARN_BODY_LINES = 500;
3503
3632
  var WARN_DESCRIPTION_LENGTH = 50;
3504
3633
  async function validateSkill(filePath) {
3505
3634
  const issues = [];
3506
- if (!existsSync15(filePath)) {
3635
+ if (!existsSync16(filePath)) {
3507
3636
  return {
3508
3637
  valid: false,
3509
3638
  issues: [{ level: "error", field: "file", message: "File does not exist" }],
@@ -3694,6 +3823,13 @@ export {
3694
3823
  getTrackedMcpServers,
3695
3824
  saveLastSelectedAgents,
3696
3825
  getLastSelectedAgents,
3826
+ normalizeCleoChannel,
3827
+ resolveCleoServerName,
3828
+ resolveChannelFromServerName,
3829
+ buildCleoProfile,
3830
+ checkCommandReachability,
3831
+ parseEnvAssignments,
3832
+ isCleoSource,
3697
3833
  parseSource,
3698
3834
  isMarketplaceScoped,
3699
3835
  formatNetworkError,
@@ -3733,4 +3869,4 @@ export {
3733
3869
  toSarif,
3734
3870
  validateSkill
3735
3871
  };
3736
- //# sourceMappingURL=chunk-GR47LTXR.js.map
3872
+ //# sourceMappingURL=chunk-DT22SZ7X.js.map