@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.
- package/dist/{chunk-GR47LTXR.js → chunk-DT22SZ7X.js} +162 -26
- package/dist/chunk-DT22SZ7X.js.map +1 -0
- package/dist/cli.js +39 -141
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +15 -1
- package/package.json +1 -1
- package/dist/chunk-GR47LTXR.js.map +0 -1
|
@@ -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((
|
|
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
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 (
|
|
2458
|
+
if (existsSync12(rootPath)) return rootPath;
|
|
2330
2459
|
const skillsPath = join6(root, "skills", "protocols", `${name}.md`);
|
|
2331
|
-
return
|
|
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 (!
|
|
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
|
|
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 (
|
|
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 &&
|
|
2560
|
+
if (envPath && existsSync13(envPath)) {
|
|
2432
2561
|
try {
|
|
2433
2562
|
const indexPath = join7(envPath, "index.js");
|
|
2434
|
-
if (
|
|
2563
|
+
if (existsSync13(indexPath)) {
|
|
2435
2564
|
return loadLibraryFromModule(envPath);
|
|
2436
2565
|
}
|
|
2437
|
-
if (
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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
|
|
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 (!
|
|
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-
|
|
3872
|
+
//# sourceMappingURL=chunk-DT22SZ7X.js.map
|