@cleocode/caamp 2026.4.4 → 2026.4.6

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/cli.js CHANGED
@@ -8,14 +8,16 @@ import {
8
8
  detectProjectProviders,
9
9
  discoverSkill,
10
10
  discoverSkillsMulti,
11
+ dispatchInstallSkillAcrossProviders,
12
+ dispatchRemoveSkillAcrossProviders,
11
13
  formatNetworkError,
12
14
  formatSkillRecommendations,
15
+ getHarnessFor,
13
16
  getInstalledProviders,
14
17
  getSkill,
15
18
  getSkillDir,
16
19
  getTrackedSkills,
17
20
  installBatchWithRollback,
18
- installSkill,
19
21
  isCatalogAvailable,
20
22
  isHuman,
21
23
  isMarketplaceScoped,
@@ -29,8 +31,8 @@ import {
29
31
  readLockFile,
30
32
  recommendSkills,
31
33
  recordSkillInstall,
32
- removeSkill,
33
34
  removeSkillFromLock,
35
+ resolveDefaultTargetProviders,
34
36
  resolveProfile,
35
37
  scanDirectory,
36
38
  scanFile,
@@ -42,7 +44,7 @@ import {
42
44
  tokenizeCriteriaValue,
43
45
  updateInstructionsSingleOperation,
44
46
  validateSkill
45
- } from "./chunk-6NBM4CAF.js";
47
+ } from "./chunk-43GULI6J.js";
46
48
  import {
47
49
  buildSkillsMap,
48
50
  checkAllInjections,
@@ -55,7 +57,7 @@ import {
55
57
  groupByInstructFile,
56
58
  injectAll,
57
59
  providerSupports
58
- } from "./chunk-CRU25LRL.js";
60
+ } from "./chunk-KWYLZ46H.js";
59
61
  import {
60
62
  CANONICAL_HOOK_EVENTS,
61
63
  buildHookMatrix,
@@ -64,12 +66,12 @@ import {
64
66
  getHookSupport,
65
67
  getProviderSummary,
66
68
  translateToAll
67
- } from "./chunk-FLBRAXDW.js";
69
+ } from "./chunk-CU2VX67L.js";
68
70
  import {
69
71
  buildSkillSubPathCandidates,
70
72
  resolveProviderConfigPath,
71
73
  resolveProviderSkillsDir
72
- } from "./chunk-XWQ5WPHC.js";
74
+ } from "./chunk-364OHA2T.js";
73
75
 
74
76
  // src/cli.ts
75
77
  import { Command } from "commander";
@@ -200,13 +202,13 @@ async function runLafsCommand(command, mvi, action) {
200
202
  }
201
203
 
202
204
  // src/commands/advanced/common.ts
203
- var VALID_PRIORITIES = /* @__PURE__ */ new Set(["high", "medium", "low"]);
205
+ var VALID_PRIORITIES = /* @__PURE__ */ new Set(["primary", "high", "medium", "low"]);
204
206
  function parsePriority(value) {
205
207
  if (!VALID_PRIORITIES.has(value)) {
206
208
  throw new LAFSCommandError(
207
209
  "E_ADVANCED_VALIDATION_PRIORITY",
208
210
  `Invalid tier: ${value}`,
209
- "Use one of: high, medium, low."
211
+ "Use one of: primary, high, medium, low."
210
212
  );
211
213
  }
212
214
  return value;
@@ -217,7 +219,7 @@ function resolveProviders(options) {
217
219
  }
218
220
  const targetAgents = options.agent ?? [];
219
221
  if (targetAgents.length === 0) {
220
- return getInstalledProviders();
222
+ return resolveDefaultTargetProviders();
221
223
  }
222
224
  const providers = targetAgents.map((id) => getProvider(id)).filter((provider) => provider !== void 0);
223
225
  if (providers.length !== targetAgents.length) {
@@ -471,7 +473,7 @@ function registerAdvancedProviders(parent) {
471
473
  id: provider.id,
472
474
  priority: provider.priority,
473
475
  status: provider.status,
474
- configFormat: provider.configFormat
476
+ configFormat: provider.capabilities.mcp?.configFormat ?? null
475
477
  }))
476
478
  };
477
479
  })
@@ -644,7 +646,24 @@ function registerConfigCommand(program2) {
644
646
  process.exit(1);
645
647
  }
646
648
  const scope = opts.global ? "global" : "project";
647
- const configPath = resolveProviderConfigPath(provider, scope) ?? provider.configPathGlobal;
649
+ const mcp = provider.capabilities.mcp;
650
+ if (!mcp) {
651
+ const message = `${provider.toolName} has no MCP config integration (extension-based harness)`;
652
+ if (format === "json") {
653
+ emitJsonError(
654
+ operation,
655
+ mvi,
656
+ ErrorCodes.PROVIDER_NOT_FOUND,
657
+ message,
658
+ ErrorCategories.VALIDATION,
659
+ { providerId }
660
+ );
661
+ } else {
662
+ console.log(pc.dim(message));
663
+ }
664
+ process.exit(1);
665
+ }
666
+ const configPath = resolveProviderConfigPath(provider, scope) ?? mcp.configPathGlobal;
648
667
  if (!existsSync(configPath)) {
649
668
  const message = `No config file at: ${configPath}`;
650
669
  if (format === "json") {
@@ -665,12 +684,12 @@ function registerConfigCommand(program2) {
665
684
  process.exit(1);
666
685
  }
667
686
  try {
668
- const data = await readConfig(configPath, provider.configFormat);
687
+ const data = await readConfig(configPath, mcp.configFormat);
669
688
  if (format === "json") {
670
689
  outputSuccess(operation, mvi, {
671
690
  provider: provider.id,
672
691
  config: data,
673
- format: provider.configFormat,
692
+ format: mcp.configFormat,
674
693
  scope
675
694
  });
676
695
  return;
@@ -702,15 +721,22 @@ ${provider.toolName} config (${configPath}):
702
721
  console.error(pc.red(`Provider not found: ${providerId}`));
703
722
  process.exit(1);
704
723
  }
724
+ const mcp = provider.capabilities.mcp;
725
+ if (!mcp) {
726
+ console.error(
727
+ pc.red(`${provider.toolName} has no MCP config integration (extension-based harness)`)
728
+ );
729
+ process.exit(1);
730
+ }
705
731
  if (scope === "global") {
706
- console.log(provider.configPathGlobal);
732
+ console.log(mcp.configPathGlobal);
707
733
  } else {
708
734
  const projectPath = resolveProviderConfigPath(provider, "project");
709
735
  if (projectPath) {
710
736
  console.log(projectPath);
711
737
  } else {
712
738
  console.log(pc.dim(`${provider.toolName} has no project-level config`));
713
- console.log(provider.configPathGlobal);
739
+ console.log(mcp.configPathGlobal);
714
740
  }
715
741
  }
716
742
  });
@@ -773,8 +799,13 @@ function checkRegistry() {
773
799
  checks.push({ label: `${count} providers loaded`, status: "pass" });
774
800
  const malformed = [];
775
801
  for (const p of providers) {
776
- if (!p.id || !p.toolName || !p.configKey || !p.configFormat) {
802
+ if (!p.id || !p.toolName) {
777
803
  malformed.push(p.id || "(unknown)");
804
+ continue;
805
+ }
806
+ const mcp = p.capabilities.mcp;
807
+ if (mcp && (!mcp.configKey || !mcp.configFormat)) {
808
+ malformed.push(p.id);
778
809
  }
779
810
  }
780
811
  if (malformed.length === 0) {
@@ -971,7 +1002,15 @@ async function checkConfigFiles() {
971
1002
  const installed = results.filter((r) => r.installed);
972
1003
  for (const r of installed) {
973
1004
  const provider = r.provider;
974
- const configPath = provider.configPathGlobal;
1005
+ const mcp = provider.capabilities.mcp;
1006
+ if (!mcp) {
1007
+ checks.push({
1008
+ label: `${provider.id}: no MCP integration (extension-based harness)`,
1009
+ status: "pass"
1010
+ });
1011
+ continue;
1012
+ }
1013
+ const configPath = mcp.configPathGlobal;
975
1014
  if (!existsSync2(configPath)) {
976
1015
  checks.push({
977
1016
  label: `${provider.id}: no config file found`,
@@ -981,7 +1020,7 @@ async function checkConfigFiles() {
981
1020
  continue;
982
1021
  }
983
1022
  try {
984
- await readConfig(configPath, provider.configFormat);
1023
+ await readConfig(configPath, mcp.configFormat);
985
1024
  const relPath = configPath.replace(homedir(), "~");
986
1025
  checks.push({
987
1026
  label: `${provider.id}: ${relPath} readable`,
@@ -1046,9 +1085,11 @@ function registerDoctorCommand(program2) {
1046
1085
  }
1047
1086
  const npmVersion = getNpmVersion() ?? "not found";
1048
1087
  const allProviders = getAllProviders();
1049
- const malformedCount = allProviders.filter(
1050
- (p) => !p.id || !p.toolName || !p.configKey || !p.configFormat
1051
- ).length;
1088
+ const malformedCount = allProviders.filter((p) => {
1089
+ if (!p.id || !p.toolName) return true;
1090
+ const mcp = p.capabilities.mcp;
1091
+ return mcp !== null && (!mcp.configKey || !mcp.configFormat);
1092
+ }).length;
1052
1093
  const detectionResults = detectAllProviders();
1053
1094
  const installedProviders = detectionResults.filter((r) => r.installed);
1054
1095
  const { canonicalCount, brokenCount, staleCount } = countSkillIssues();
@@ -1206,7 +1247,7 @@ function registerInstructionsCheck(parent) {
1206
1247
  } else if (opts.agent.length > 0) {
1207
1248
  providers = opts.agent.map((a) => getProvider(a)).filter((p) => p !== void 0);
1208
1249
  } else {
1209
- providers = getInstalledProviders();
1250
+ providers = resolveDefaultTargetProviders();
1210
1251
  }
1211
1252
  const scope = opts.global ? "global" : "project";
1212
1253
  const results = await checkAllInjections(providers, process.cwd(), scope);
@@ -1292,7 +1333,7 @@ function registerInstructionsInject(parent) {
1292
1333
  } else if (opts.agent.length > 0) {
1293
1334
  providers = opts.agent.map((a) => getProvider(a)).filter((p) => p !== void 0);
1294
1335
  } else {
1295
- providers = getInstalledProviders();
1336
+ providers = resolveDefaultTargetProviders();
1296
1337
  }
1297
1338
  if (providers.length === 0) {
1298
1339
  const message = "No providers found.";
@@ -1335,7 +1376,37 @@ function registerInstructionsInject(parent) {
1335
1376
  }
1336
1377
  return;
1337
1378
  }
1338
- const results = await injectAll(providers, process.cwd(), scope, content);
1379
+ const harnessProviders = [];
1380
+ const genericProviders = [];
1381
+ for (const p of providers) {
1382
+ if (getHarnessFor(p) !== null) {
1383
+ harnessProviders.push(p);
1384
+ } else {
1385
+ genericProviders.push(p);
1386
+ }
1387
+ }
1388
+ const results = /* @__PURE__ */ new Map();
1389
+ const harnessScope = scope === "global" ? { kind: "global" } : { kind: "project", projectDir: process.cwd() };
1390
+ for (const provider of harnessProviders) {
1391
+ const harness = getHarnessFor(provider);
1392
+ if (harness === null) continue;
1393
+ try {
1394
+ await harness.injectInstructions(content, harnessScope);
1395
+ results.set(`${provider.id}:AGENTS.md`, "updated");
1396
+ } catch (err) {
1397
+ if (format === "human") {
1398
+ console.log(
1399
+ pc4.red(` x ${provider.id}: ${err instanceof Error ? err.message : String(err)}`)
1400
+ );
1401
+ }
1402
+ }
1403
+ }
1404
+ if (genericProviders.length > 0) {
1405
+ const genericResults = await injectAll(genericProviders, process.cwd(), scope, content);
1406
+ for (const [file, action] of genericResults) {
1407
+ results.set(file, action);
1408
+ }
1409
+ }
1339
1410
  const injected = [];
1340
1411
  for (const [file] of results) {
1341
1412
  injected.push(file);
@@ -1382,12 +1453,21 @@ function registerInstructionsUpdate(parent) {
1382
1453
  );
1383
1454
  process.exit(1);
1384
1455
  }
1385
- const providers = getInstalledProviders();
1456
+ const providers = resolveDefaultTargetProviders();
1386
1457
  const scope = opts.global ? "global" : "project";
1387
1458
  const content = generateInjectionContent();
1388
- const checks = await checkAllInjections(providers, process.cwd(), scope, content);
1459
+ const harnessProviders = [];
1460
+ const genericProviders = [];
1461
+ for (const provider of providers) {
1462
+ if (getHarnessFor(provider) !== null) {
1463
+ harnessProviders.push(provider);
1464
+ } else {
1465
+ genericProviders.push(provider);
1466
+ }
1467
+ }
1468
+ const checks = await checkAllInjections(genericProviders, process.cwd(), scope, content);
1389
1469
  const needsUpdate = checks.filter((c) => c.status !== "current");
1390
- if (needsUpdate.length === 0) {
1470
+ if (harnessProviders.length === 0 && needsUpdate.length === 0) {
1391
1471
  if (format === "json") {
1392
1472
  outputSuccess(operation, mvi, {
1393
1473
  updated: [],
@@ -1399,7 +1479,7 @@ function registerInstructionsUpdate(parent) {
1399
1479
  }
1400
1480
  return;
1401
1481
  }
1402
- if (format === "human") {
1482
+ if (format === "human" && needsUpdate.length > 0) {
1403
1483
  console.log(pc5.bold(`${needsUpdate.length} file(s) need updating:
1404
1484
  `));
1405
1485
  for (const c of needsUpdate) {
@@ -1407,8 +1487,23 @@ function registerInstructionsUpdate(parent) {
1407
1487
  }
1408
1488
  }
1409
1489
  const providerIds = new Set(needsUpdate.map((c) => c.provider));
1410
- const toUpdate = providers.filter((p) => providerIds.has(p.id));
1490
+ const toUpdate = genericProviders.filter((p) => providerIds.has(p.id));
1411
1491
  const results = await injectAll(toUpdate, process.cwd(), scope, content);
1492
+ const harnessScope = scope === "global" ? { kind: "global" } : { kind: "project", projectDir: process.cwd() };
1493
+ const harnessFailures = [];
1494
+ for (const provider of harnessProviders) {
1495
+ const harness = getHarnessFor(provider);
1496
+ if (harness === null) continue;
1497
+ try {
1498
+ await harness.injectInstructions(content, harnessScope);
1499
+ results.set(`${provider.id}:AGENTS.md`, "updated");
1500
+ } catch (err) {
1501
+ harnessFailures.push({
1502
+ provider: provider.id,
1503
+ error: err instanceof Error ? err.message : String(err)
1504
+ });
1505
+ }
1506
+ }
1412
1507
  const updated = [];
1413
1508
  for (const [file] of results) {
1414
1509
  updated.push(file);
@@ -1418,14 +1513,17 @@ function registerInstructionsUpdate(parent) {
1418
1513
  for (const [file, action] of results) {
1419
1514
  console.log(` ${pc5.green("\u2713")} ${file} (${action})`);
1420
1515
  }
1516
+ for (const failure of harnessFailures) {
1517
+ console.log(` ${pc5.red("x")} ${failure.provider}: ${failure.error}`);
1518
+ }
1421
1519
  console.log(pc5.bold(`
1422
1520
  ${results.size} file(s) updated.`));
1423
1521
  }
1424
1522
  if (format === "json") {
1425
1523
  outputSuccess(operation, mvi, {
1426
1524
  updated,
1427
- failed: [],
1428
- count: { updated: updated.length, failed: 0 }
1525
+ failed: harnessFailures,
1526
+ count: { updated: updated.length, failed: harnessFailures.length }
1429
1527
  });
1430
1528
  }
1431
1529
  });
@@ -1603,16 +1701,23 @@ ${provider.toolName}`));
1603
1701
  console.log(` Priority: ${provider.priority}`);
1604
1702
  console.log();
1605
1703
  console.log(` Instruction: ${provider.instructFile}`);
1606
- console.log(` Config format: ${provider.configFormat}`);
1607
- console.log(` Config key: ${provider.configKey}`);
1608
- console.log(` Transports: ${provider.supportedTransports.join(", ")}`);
1609
- console.log(` Headers: ${provider.supportsHeaders ? "yes" : "no"}`);
1704
+ const mcp = provider.capabilities.mcp;
1705
+ if (mcp) {
1706
+ console.log(` Config format: ${mcp.configFormat}`);
1707
+ console.log(` Config key: ${mcp.configKey}`);
1708
+ console.log(` Transports: ${mcp.supportedTransports.join(", ")}`);
1709
+ console.log(` Headers: ${mcp.supportsHeaders ? "yes" : "no"}`);
1710
+ } else {
1711
+ console.log(` MCP integration: ${pc6.dim("(none \u2014 extension-based harness)")}`);
1712
+ }
1610
1713
  console.log();
1611
1714
  console.log(pc6.dim(" Paths:"));
1612
1715
  console.log(` Global dir: ${provider.pathGlobal}`);
1613
1716
  console.log(` Project dir: ${provider.pathProject || "(none)"}`);
1614
- console.log(` Global config: ${provider.configPathGlobal}`);
1615
- console.log(` Project config: ${provider.configPathProject || "(none)"}`);
1717
+ if (mcp) {
1718
+ console.log(` Global config: ${mcp.configPathGlobal}`);
1719
+ console.log(` Project config: ${mcp.configPathProject || "(none)"}`);
1720
+ }
1616
1721
  console.log(` Global skills: ${provider.pathSkills}`);
1617
1722
  console.log(` Project skills: ${provider.pathProjectSkills || "(none)"}`);
1618
1723
  console.log();
@@ -1843,7 +1948,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
1843
1948
  return;
1844
1949
  }
1845
1950
  if (opts.from) {
1846
- const { toCanonical } = await import("./hooks-VLIP52LY.js");
1951
+ const { toCanonical } = await import("./hooks-M2DMKNHI.js");
1847
1952
  const canonical2 = toCanonical(event, opts.from);
1848
1953
  if (format === "json") {
1849
1954
  const envelope = buildEnvelope2(
@@ -1883,7 +1988,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
1883
1988
  }
1884
1989
  process.exit(1);
1885
1990
  }
1886
- const { getMappedProviderIds } = await import("./hooks-VLIP52LY.js");
1991
+ const { getMappedProviderIds } = await import("./hooks-M2DMKNHI.js");
1887
1992
  const allIds = getMappedProviderIds();
1888
1993
  const translations = translateToAll(canonical, allIds);
1889
1994
  if (format === "json") {
@@ -2784,7 +2889,7 @@ function registerSkillsInstall(parent) {
2784
2889
  } else if (opts.agent.length > 0) {
2785
2890
  providers = opts.agent.map((a) => getProvider(a)).filter((p) => p !== void 0);
2786
2891
  } else {
2787
- providers = getInstalledProviders();
2892
+ providers = resolveDefaultTargetProviders();
2788
2893
  }
2789
2894
  if (providers.length === 0) {
2790
2895
  const message = "No target providers found. Use --agent or --all.";
@@ -2982,7 +3087,12 @@ function registerSkillsInstall(parent) {
2982
3087
  console.error(pc11.red(message));
2983
3088
  process.exit(1);
2984
3089
  }
2985
- const result = await installSkill(localPath, skillName, providers, opts.global ?? false);
3090
+ const result = await dispatchInstallSkillAcrossProviders(
3091
+ localPath,
3092
+ skillName,
3093
+ providers,
3094
+ opts.global ?? false
3095
+ );
2986
3096
  if (result.success) {
2987
3097
  const isGlobal = sourceType === "library" || sourceType === "package" ? true : opts.global ?? false;
2988
3098
  await recordSkillInstall(
@@ -3104,7 +3214,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
3104
3214
  for (const name of profileSkills) {
3105
3215
  const skillDir = getSkillDir(name);
3106
3216
  try {
3107
- const result = await installSkill(skillDir, name, providers, isGlobal);
3217
+ const result = await dispatchInstallSkillAcrossProviders(skillDir, name, providers, isGlobal);
3108
3218
  if (result.success) {
3109
3219
  if (format === "human") {
3110
3220
  console.log(pc11.green(` + ${name}`));
@@ -3294,10 +3404,10 @@ function registerSkillsList(parent) {
3294
3404
  }
3295
3405
  dirs = opts.global ? [resolveProviderSkillsDir(provider, "global")] : [resolveProviderSkillsDir(provider, "project")];
3296
3406
  } else if (opts.global) {
3297
- const providers = getInstalledProviders();
3407
+ const providers = resolveDefaultTargetProviders();
3298
3408
  dirs = providers.map((p) => resolveProviderSkillsDir(p, "global")).filter(Boolean);
3299
3409
  } else {
3300
- const providers = getInstalledProviders();
3410
+ const providers = resolveDefaultTargetProviders();
3301
3411
  dirs = providers.map((p) => resolveProviderSkillsDir(p, "project")).filter(Boolean);
3302
3412
  }
3303
3413
  const skills = await discoverSkillsMulti(dirs);
@@ -3390,9 +3500,13 @@ function registerSkillsRemove(parent) {
3390
3500
  );
3391
3501
  process.exit(1);
3392
3502
  }
3393
- const providers = getInstalledProviders();
3503
+ const providers = resolveDefaultTargetProviders();
3394
3504
  if (name) {
3395
- const result = await removeSkill(name, providers, opts.global ?? false);
3505
+ const result = await dispatchRemoveSkillAcrossProviders(
3506
+ name,
3507
+ providers,
3508
+ opts.global ?? false
3509
+ );
3396
3510
  const removed = result.removed;
3397
3511
  const count = {
3398
3512
  removed: removed.length,
@@ -3594,7 +3708,7 @@ ${outdated.length} skill(s) have updates available:
3594
3708
  skipped.push(skill.name);
3595
3709
  continue;
3596
3710
  }
3597
- const installResult = await installSkill(
3711
+ const installResult = await dispatchInstallSkillAcrossProviders(
3598
3712
  localPath,
3599
3713
  skill.name,
3600
3714
  providers,