@cleocode/caamp 1.5.1 → 1.6.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.
- package/README.md +25 -0
- package/dist/{chunk-ZEXRZTQX.js → chunk-N5E7BZM2.js} +267 -80
- package/dist/chunk-N5E7BZM2.js.map +1 -0
- package/dist/cli.js +240 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +273 -52
- package/dist/index.js +23 -1
- package/package.json +2 -1
- package/providers/registry.json +89 -12
- package/dist/chunk-ZEXRZTQX.js.map +0 -1
package/README.md
CHANGED
|
@@ -65,6 +65,31 @@ const installed = getInstalledProviders();
|
|
|
65
65
|
const servers = await listAllMcpServers(installed, "global");
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
+
### Querying Provider Capabilities
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import {
|
|
72
|
+
getProviderCapabilities,
|
|
73
|
+
getSpawnCapableProviders,
|
|
74
|
+
getProvidersByHookEvent,
|
|
75
|
+
buildSkillsMap,
|
|
76
|
+
} from "@cleocode/caamp";
|
|
77
|
+
|
|
78
|
+
// Get capabilities for a specific provider
|
|
79
|
+
const caps = getProviderCapabilities("claude-code");
|
|
80
|
+
console.log(caps?.spawn.supportsSubagents); // true
|
|
81
|
+
console.log(caps?.hooks.supported); // ["onSessionStart", ...]
|
|
82
|
+
|
|
83
|
+
// Find all providers that support spawning subagents
|
|
84
|
+
const spawnCapable = getSpawnCapableProviders();
|
|
85
|
+
|
|
86
|
+
// Find providers supporting a specific hook event
|
|
87
|
+
const hookProviders = getProvidersByHookEvent("onToolComplete");
|
|
88
|
+
|
|
89
|
+
// Get full skills precedence map
|
|
90
|
+
const skillsMap = buildSkillsMap();
|
|
91
|
+
```
|
|
92
|
+
|
|
68
93
|
See [API Reference](https://codluv.gitbook.io/caamp/api-and-reference/api-reference) for full programmatic API documentation.
|
|
69
94
|
|
|
70
95
|
## CLI Commands
|
|
@@ -561,6 +561,42 @@ function resolveProviderSkillsDir(provider, scope, projectDir = process.cwd()) {
|
|
|
561
561
|
}
|
|
562
562
|
return resolveProjectPath(provider.pathProjectSkills, projectDir);
|
|
563
563
|
}
|
|
564
|
+
function resolveProviderSkillsDirs(provider, scope, projectDir = process.cwd()) {
|
|
565
|
+
const vendorPath = resolveProviderSkillsDir(provider, scope, projectDir);
|
|
566
|
+
const precedence = provider.capabilities?.skills?.precedence ?? "vendor-only";
|
|
567
|
+
const resolveAgentsPath = () => {
|
|
568
|
+
if (scope === "global") {
|
|
569
|
+
return provider.capabilities?.skills?.agentsGlobalPath ?? null;
|
|
570
|
+
}
|
|
571
|
+
const projectRelative = provider.capabilities?.skills?.agentsProjectPath ?? null;
|
|
572
|
+
return projectRelative ? join2(projectDir, projectRelative) : null;
|
|
573
|
+
};
|
|
574
|
+
switch (precedence) {
|
|
575
|
+
case "vendor-only":
|
|
576
|
+
return [vendorPath];
|
|
577
|
+
case "agents-canonical": {
|
|
578
|
+
const agentsPath = resolveAgentsPath();
|
|
579
|
+
return agentsPath ? [agentsPath] : [vendorPath];
|
|
580
|
+
}
|
|
581
|
+
case "agents-first": {
|
|
582
|
+
const agentsPath = resolveAgentsPath();
|
|
583
|
+
return agentsPath ? [agentsPath, vendorPath] : [vendorPath];
|
|
584
|
+
}
|
|
585
|
+
case "agents-supported": {
|
|
586
|
+
const agentsPath = resolveAgentsPath();
|
|
587
|
+
return agentsPath ? [vendorPath, agentsPath] : [vendorPath];
|
|
588
|
+
}
|
|
589
|
+
case "vendor-global-agents-project": {
|
|
590
|
+
if (scope === "global") {
|
|
591
|
+
return [vendorPath];
|
|
592
|
+
}
|
|
593
|
+
const agentsPath = resolveAgentsPath();
|
|
594
|
+
return agentsPath ? [agentsPath, vendorPath] : [vendorPath];
|
|
595
|
+
}
|
|
596
|
+
default:
|
|
597
|
+
return [vendorPath];
|
|
598
|
+
}
|
|
599
|
+
}
|
|
564
600
|
function resolveProviderProjectPath(provider, projectDir = process.cwd()) {
|
|
565
601
|
return resolveProjectPath(provider.pathProject, projectDir);
|
|
566
602
|
}
|
|
@@ -860,8 +896,45 @@ function buildServerConfig(source, transport, headers) {
|
|
|
860
896
|
|
|
861
897
|
// src/core/registry/providers.ts
|
|
862
898
|
import { readFileSync } from "fs";
|
|
863
|
-
import { dirname as dirname3 } from "path";
|
|
899
|
+
import { dirname as dirname3, join as join3 } from "path";
|
|
864
900
|
import { fileURLToPath } from "url";
|
|
901
|
+
var DEFAULT_SKILLS_CAPABILITY = {
|
|
902
|
+
agentsGlobalPath: null,
|
|
903
|
+
agentsProjectPath: null,
|
|
904
|
+
precedence: "vendor-only"
|
|
905
|
+
};
|
|
906
|
+
var DEFAULT_HOOKS_CAPABILITY = {
|
|
907
|
+
supported: [],
|
|
908
|
+
hookConfigPath: null,
|
|
909
|
+
hookFormat: null
|
|
910
|
+
};
|
|
911
|
+
var DEFAULT_SPAWN_CAPABILITY = {
|
|
912
|
+
supportsSubagents: false,
|
|
913
|
+
supportsProgrammaticSpawn: false,
|
|
914
|
+
supportsInterAgentComms: false,
|
|
915
|
+
supportsParallelSpawn: false,
|
|
916
|
+
spawnMechanism: null
|
|
917
|
+
};
|
|
918
|
+
function resolveCapabilities(raw) {
|
|
919
|
+
const skills = raw?.skills ? {
|
|
920
|
+
agentsGlobalPath: raw.skills.agentsGlobalPath ? resolveRegistryTemplatePath(raw.skills.agentsGlobalPath) : null,
|
|
921
|
+
agentsProjectPath: raw.skills.agentsProjectPath,
|
|
922
|
+
precedence: raw.skills.precedence
|
|
923
|
+
} : { ...DEFAULT_SKILLS_CAPABILITY };
|
|
924
|
+
const hooks = raw?.hooks ? {
|
|
925
|
+
supported: raw.hooks.supported,
|
|
926
|
+
hookConfigPath: raw.hooks.hookConfigPath ? resolveRegistryTemplatePath(raw.hooks.hookConfigPath) : null,
|
|
927
|
+
hookFormat: raw.hooks.hookFormat
|
|
928
|
+
} : { ...DEFAULT_HOOKS_CAPABILITY, supported: [] };
|
|
929
|
+
const spawn = raw?.spawn ? {
|
|
930
|
+
supportsSubagents: raw.spawn.supportsSubagents,
|
|
931
|
+
supportsProgrammaticSpawn: raw.spawn.supportsProgrammaticSpawn,
|
|
932
|
+
supportsInterAgentComms: raw.spawn.supportsInterAgentComms,
|
|
933
|
+
supportsParallelSpawn: raw.spawn.supportsParallelSpawn,
|
|
934
|
+
spawnMechanism: raw.spawn.spawnMechanism
|
|
935
|
+
} : { ...DEFAULT_SPAWN_CAPABILITY };
|
|
936
|
+
return { skills, hooks, spawn };
|
|
937
|
+
}
|
|
865
938
|
function findRegistryPath() {
|
|
866
939
|
const thisDir = dirname3(fileURLToPath(import.meta.url));
|
|
867
940
|
return resolveProvidersRegistryPath(thisDir);
|
|
@@ -896,7 +969,8 @@ function resolveProvider(raw) {
|
|
|
896
969
|
supportsHeaders: raw.supportsHeaders,
|
|
897
970
|
priority: raw.priority,
|
|
898
971
|
status: raw.status,
|
|
899
|
-
agentSkillsCompatible: raw.agentSkillsCompatible
|
|
972
|
+
agentSkillsCompatible: raw.agentSkillsCompatible,
|
|
973
|
+
capabilities: resolveCapabilities(raw.capabilities)
|
|
900
974
|
};
|
|
901
975
|
}
|
|
902
976
|
function loadRegistry() {
|
|
@@ -956,11 +1030,104 @@ function getProviderCount() {
|
|
|
956
1030
|
function getRegistryVersion() {
|
|
957
1031
|
return loadRegistry().version;
|
|
958
1032
|
}
|
|
1033
|
+
function getProvidersByHookEvent(event) {
|
|
1034
|
+
return getAllProviders().filter((p) => p.capabilities.hooks.supported.includes(event));
|
|
1035
|
+
}
|
|
1036
|
+
function getCommonHookEvents(providerIds) {
|
|
1037
|
+
const providers = providerIds && providerIds.length > 0 ? providerIds.map((id) => getProvider(id)).filter((p) => p !== void 0) : getAllProviders();
|
|
1038
|
+
if (providers.length === 0) return [];
|
|
1039
|
+
const first = providers[0].capabilities.hooks.supported;
|
|
1040
|
+
return first.filter(
|
|
1041
|
+
(event) => providers.every((p) => p.capabilities.hooks.supported.includes(event))
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
function providerSupports(provider, dotPath) {
|
|
1045
|
+
const parts = dotPath.split(".");
|
|
1046
|
+
let current = provider.capabilities;
|
|
1047
|
+
for (const part of parts) {
|
|
1048
|
+
if (current == null || typeof current !== "object") return false;
|
|
1049
|
+
current = current[part];
|
|
1050
|
+
}
|
|
1051
|
+
if (typeof current === "boolean") return current;
|
|
1052
|
+
if (Array.isArray(current)) return current.length > 0;
|
|
1053
|
+
return current != null;
|
|
1054
|
+
}
|
|
1055
|
+
function getSpawnCapableProviders() {
|
|
1056
|
+
return getAllProviders().filter((p) => p.capabilities.spawn.supportsSubagents);
|
|
1057
|
+
}
|
|
1058
|
+
function getProvidersBySpawnCapability(flag) {
|
|
1059
|
+
return getAllProviders().filter((p) => p.capabilities.spawn[flag] === true);
|
|
1060
|
+
}
|
|
1061
|
+
function getProvidersBySkillsPrecedence(precedence) {
|
|
1062
|
+
return getAllProviders().filter((p) => p.capabilities.skills.precedence === precedence);
|
|
1063
|
+
}
|
|
1064
|
+
function getEffectiveSkillsPaths(provider, scope, projectDir) {
|
|
1065
|
+
const vendorPath = resolveProviderSkillsDir(provider, scope, projectDir);
|
|
1066
|
+
const { precedence, agentsGlobalPath, agentsProjectPath } = provider.capabilities.skills;
|
|
1067
|
+
const resolveAgentsPath = () => {
|
|
1068
|
+
if (scope === "global" && agentsGlobalPath) return agentsGlobalPath;
|
|
1069
|
+
if (scope === "project" && agentsProjectPath && projectDir) {
|
|
1070
|
+
return join3(projectDir, agentsProjectPath);
|
|
1071
|
+
}
|
|
1072
|
+
return null;
|
|
1073
|
+
};
|
|
1074
|
+
const agentsPath = resolveAgentsPath();
|
|
1075
|
+
const scopeLabel = scope === "global" ? "global" : "project";
|
|
1076
|
+
switch (precedence) {
|
|
1077
|
+
case "vendor-only":
|
|
1078
|
+
return [{ path: vendorPath, source: "vendor", scope: scopeLabel }];
|
|
1079
|
+
case "agents-canonical":
|
|
1080
|
+
return agentsPath ? [{ path: agentsPath, source: "agents", scope: scopeLabel }] : [];
|
|
1081
|
+
case "agents-first":
|
|
1082
|
+
return [
|
|
1083
|
+
...agentsPath ? [{ path: agentsPath, source: "agents", scope: scopeLabel }] : [],
|
|
1084
|
+
{ path: vendorPath, source: "vendor", scope: scopeLabel }
|
|
1085
|
+
];
|
|
1086
|
+
case "agents-supported":
|
|
1087
|
+
return [
|
|
1088
|
+
{ path: vendorPath, source: "vendor", scope: scopeLabel },
|
|
1089
|
+
...agentsPath ? [{ path: agentsPath, source: "agents", scope: scopeLabel }] : []
|
|
1090
|
+
];
|
|
1091
|
+
case "vendor-global-agents-project":
|
|
1092
|
+
if (scope === "global") {
|
|
1093
|
+
return [{ path: vendorPath, source: "vendor", scope: "global" }];
|
|
1094
|
+
}
|
|
1095
|
+
return [
|
|
1096
|
+
...agentsPath ? [{ path: agentsPath, source: "agents", scope: "project" }] : [],
|
|
1097
|
+
{ path: vendorPath, source: "vendor", scope: "project" }
|
|
1098
|
+
];
|
|
1099
|
+
default:
|
|
1100
|
+
return [{ path: vendorPath, source: "vendor", scope: scopeLabel }];
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
function buildSkillsMap() {
|
|
1104
|
+
return getAllProviders().map((p) => {
|
|
1105
|
+
const { precedence, agentsGlobalPath, agentsProjectPath } = p.capabilities.skills;
|
|
1106
|
+
const isVendorOnly = precedence === "vendor-only";
|
|
1107
|
+
return {
|
|
1108
|
+
providerId: p.id,
|
|
1109
|
+
toolName: p.toolName,
|
|
1110
|
+
precedence,
|
|
1111
|
+
paths: {
|
|
1112
|
+
global: isVendorOnly ? p.pathSkills : agentsGlobalPath ?? null,
|
|
1113
|
+
project: isVendorOnly ? p.pathProjectSkills : agentsProjectPath ?? null
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
function getProviderCapabilities(idOrAlias) {
|
|
1119
|
+
return getProvider(idOrAlias)?.capabilities;
|
|
1120
|
+
}
|
|
1121
|
+
function providerSupportsById(idOrAlias, capabilityPath) {
|
|
1122
|
+
const provider = getProvider(idOrAlias);
|
|
1123
|
+
if (!provider) return false;
|
|
1124
|
+
return providerSupports(provider, capabilityPath);
|
|
1125
|
+
}
|
|
959
1126
|
|
|
960
1127
|
// src/core/registry/detection.ts
|
|
961
1128
|
import { execFileSync } from "child_process";
|
|
962
1129
|
import { existsSync as existsSync7 } from "fs";
|
|
963
|
-
import { join as
|
|
1130
|
+
import { join as join4 } from "path";
|
|
964
1131
|
var DEFAULT_DETECTION_CACHE_TTL_MS = 3e4;
|
|
965
1132
|
var detectionCache = null;
|
|
966
1133
|
function checkBinary(binary) {
|
|
@@ -978,7 +1145,7 @@ function checkDirectory(dir) {
|
|
|
978
1145
|
function checkAppBundle(appName) {
|
|
979
1146
|
if (process.platform !== "darwin") return false;
|
|
980
1147
|
const applications = getPlatformLocations().applications;
|
|
981
|
-
return applications.some((base) => existsSync7(
|
|
1148
|
+
return applications.some((base) => existsSync7(join4(base, appName)));
|
|
982
1149
|
}
|
|
983
1150
|
function checkFlatpak(flatpakId) {
|
|
984
1151
|
if (process.platform !== "linux") return false;
|
|
@@ -1100,13 +1267,13 @@ function resetDetectionCache() {
|
|
|
1100
1267
|
// src/core/skills/installer.ts
|
|
1101
1268
|
import { existsSync as existsSync8, lstatSync } from "fs";
|
|
1102
1269
|
import { cp, mkdir as mkdir2, rm, symlink } from "fs/promises";
|
|
1103
|
-
import { join as
|
|
1270
|
+
import { join as join5 } from "path";
|
|
1104
1271
|
async function ensureCanonicalDir() {
|
|
1105
1272
|
await mkdir2(getCanonicalSkillsDir(), { recursive: true });
|
|
1106
1273
|
}
|
|
1107
1274
|
async function installToCanonical(sourcePath, skillName) {
|
|
1108
1275
|
await ensureCanonicalDir();
|
|
1109
|
-
const targetDir =
|
|
1276
|
+
const targetDir = join5(getCanonicalSkillsDir(), skillName);
|
|
1110
1277
|
await rm(targetDir, { recursive: true, force: true });
|
|
1111
1278
|
try {
|
|
1112
1279
|
await cp(sourcePath, targetDir, { recursive: true });
|
|
@@ -1121,38 +1288,44 @@ async function installToCanonical(sourcePath, skillName) {
|
|
|
1121
1288
|
return targetDir;
|
|
1122
1289
|
}
|
|
1123
1290
|
async function linkToAgent(canonicalPath, provider, skillName, isGlobal, projectDir) {
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
projectDir
|
|
1128
|
-
);
|
|
1129
|
-
if (!targetSkillsDir) {
|
|
1291
|
+
const scope = isGlobal ? "global" : "project";
|
|
1292
|
+
const targetDirs = resolveProviderSkillsDirs(provider, scope, projectDir);
|
|
1293
|
+
if (targetDirs.length === 0) {
|
|
1130
1294
|
return { success: false, error: `Provider ${provider.id} has no skills directory` };
|
|
1131
1295
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
if (
|
|
1136
|
-
const stat2 = lstatSync(linkPath);
|
|
1137
|
-
if (stat2.isSymbolicLink()) {
|
|
1138
|
-
await rm(linkPath);
|
|
1139
|
-
} else {
|
|
1140
|
-
await rm(linkPath, { recursive: true });
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
const symlinkType = process.platform === "win32" ? "junction" : "dir";
|
|
1296
|
+
const errors = [];
|
|
1297
|
+
let anySuccess = false;
|
|
1298
|
+
for (const targetSkillsDir of targetDirs) {
|
|
1299
|
+
if (!targetSkillsDir) continue;
|
|
1144
1300
|
try {
|
|
1145
|
-
await
|
|
1146
|
-
|
|
1147
|
-
|
|
1301
|
+
await mkdir2(targetSkillsDir, { recursive: true });
|
|
1302
|
+
const linkPath = join5(targetSkillsDir, skillName);
|
|
1303
|
+
if (existsSync8(linkPath)) {
|
|
1304
|
+
const stat2 = lstatSync(linkPath);
|
|
1305
|
+
if (stat2.isSymbolicLink()) {
|
|
1306
|
+
await rm(linkPath);
|
|
1307
|
+
} else {
|
|
1308
|
+
await rm(linkPath, { recursive: true });
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
const symlinkType = process.platform === "win32" ? "junction" : "dir";
|
|
1312
|
+
try {
|
|
1313
|
+
await symlink(canonicalPath, linkPath, symlinkType);
|
|
1314
|
+
} catch {
|
|
1315
|
+
await cp(canonicalPath, linkPath, { recursive: true });
|
|
1316
|
+
}
|
|
1317
|
+
anySuccess = true;
|
|
1318
|
+
} catch (err) {
|
|
1319
|
+
errors.push(err instanceof Error ? err.message : String(err));
|
|
1148
1320
|
}
|
|
1321
|
+
}
|
|
1322
|
+
if (anySuccess) {
|
|
1149
1323
|
return { success: true };
|
|
1150
|
-
} catch (err) {
|
|
1151
|
-
return {
|
|
1152
|
-
success: false,
|
|
1153
|
-
error: err instanceof Error ? err.message : String(err)
|
|
1154
|
-
};
|
|
1155
1324
|
}
|
|
1325
|
+
return {
|
|
1326
|
+
success: false,
|
|
1327
|
+
error: errors.join("; ") || `Provider ${provider.id} has no skills directory`
|
|
1328
|
+
};
|
|
1156
1329
|
}
|
|
1157
1330
|
async function installSkill(sourcePath, skillName, providers, isGlobal, projectDir) {
|
|
1158
1331
|
const errors = [];
|
|
@@ -1178,23 +1351,26 @@ async function removeSkill(skillName, providers, isGlobal, projectDir) {
|
|
|
1178
1351
|
const removed = [];
|
|
1179
1352
|
const errors = [];
|
|
1180
1353
|
for (const provider of providers) {
|
|
1181
|
-
const
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1354
|
+
const scope = isGlobal ? "global" : "project";
|
|
1355
|
+
const targetDirs = resolveProviderSkillsDirs(provider, scope, projectDir);
|
|
1356
|
+
let providerRemoved = false;
|
|
1357
|
+
for (const skillsDir of targetDirs) {
|
|
1358
|
+
if (!skillsDir) continue;
|
|
1359
|
+
const linkPath = join5(skillsDir, skillName);
|
|
1360
|
+
if (existsSync8(linkPath)) {
|
|
1361
|
+
try {
|
|
1362
|
+
await rm(linkPath, { recursive: true });
|
|
1363
|
+
providerRemoved = true;
|
|
1364
|
+
} catch (err) {
|
|
1365
|
+
errors.push(`${provider.id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1366
|
+
}
|
|
1194
1367
|
}
|
|
1195
1368
|
}
|
|
1369
|
+
if (providerRemoved) {
|
|
1370
|
+
removed.push(provider.id);
|
|
1371
|
+
}
|
|
1196
1372
|
}
|
|
1197
|
-
const canonicalPath =
|
|
1373
|
+
const canonicalPath = join5(getCanonicalSkillsDir(), skillName);
|
|
1198
1374
|
if (existsSync8(canonicalPath)) {
|
|
1199
1375
|
try {
|
|
1200
1376
|
await rm(canonicalPath, { recursive: true });
|
|
@@ -1223,7 +1399,7 @@ import {
|
|
|
1223
1399
|
writeFile as writeFile5
|
|
1224
1400
|
} from "fs/promises";
|
|
1225
1401
|
import { tmpdir } from "os";
|
|
1226
|
-
import { basename, dirname as dirname4, join as
|
|
1402
|
+
import { basename, dirname as dirname4, join as join6 } from "path";
|
|
1227
1403
|
|
|
1228
1404
|
// src/core/paths/agents.ts
|
|
1229
1405
|
var AGENTS_HOME = getAgentsHome();
|
|
@@ -1244,8 +1420,8 @@ function selectProvidersByMinimumPriority(providers, minimumPriority = "low") {
|
|
|
1244
1420
|
return [...providers].filter((provider) => PRIORITY_ORDER[provider.priority] <= maxRank).sort((a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]);
|
|
1245
1421
|
}
|
|
1246
1422
|
function resolveSkillLinkPath(provider, skillName, isGlobal, projectDir) {
|
|
1247
|
-
const skillDir = isGlobal ? provider.pathSkills :
|
|
1248
|
-
return
|
|
1423
|
+
const skillDir = isGlobal ? provider.pathSkills : join6(projectDir, provider.pathProjectSkills);
|
|
1424
|
+
return join6(skillDir, skillName);
|
|
1249
1425
|
}
|
|
1250
1426
|
async function snapshotConfigs(paths) {
|
|
1251
1427
|
const snapshots = /* @__PURE__ */ new Map();
|
|
@@ -1272,9 +1448,9 @@ async function restoreConfigSnapshots(snapshots) {
|
|
|
1272
1448
|
async function snapshotSkillState(providerTargets, operation, projectDir, backupRoot) {
|
|
1273
1449
|
const skillName = operation.skillName;
|
|
1274
1450
|
const isGlobal = operation.isGlobal ?? true;
|
|
1275
|
-
const canonicalPath =
|
|
1451
|
+
const canonicalPath = join6(CANONICAL_SKILLS_DIR, skillName);
|
|
1276
1452
|
const canonicalExisted = existsSync9(canonicalPath);
|
|
1277
|
-
const canonicalBackupPath =
|
|
1453
|
+
const canonicalBackupPath = join6(backupRoot, "canonical", skillName);
|
|
1278
1454
|
if (canonicalExisted) {
|
|
1279
1455
|
await mkdir3(dirname4(canonicalBackupPath), { recursive: true });
|
|
1280
1456
|
await cp2(canonicalPath, canonicalBackupPath, { recursive: true });
|
|
@@ -1295,7 +1471,7 @@ async function snapshotSkillState(providerTargets, operation, projectDir, backup
|
|
|
1295
1471
|
});
|
|
1296
1472
|
continue;
|
|
1297
1473
|
}
|
|
1298
|
-
const backupPath =
|
|
1474
|
+
const backupPath = join6(backupRoot, "links", provider.id, `${skillName}-${basename(linkPath)}`);
|
|
1299
1475
|
await mkdir3(dirname4(backupPath), { recursive: true });
|
|
1300
1476
|
if (stat2.isDirectory()) {
|
|
1301
1477
|
await cp2(linkPath, backupPath, { recursive: true });
|
|
@@ -1356,7 +1532,7 @@ async function installBatchWithRollback(options) {
|
|
|
1356
1532
|
return paths;
|
|
1357
1533
|
});
|
|
1358
1534
|
const configSnapshots = await snapshotConfigs(configPaths);
|
|
1359
|
-
const backupRoot =
|
|
1535
|
+
const backupRoot = join6(
|
|
1360
1536
|
tmpdir(),
|
|
1361
1537
|
`caamp-skill-backup-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
|
|
1362
1538
|
);
|
|
@@ -1547,7 +1723,7 @@ async function updateInstructionsSingleOperation(providers, content, scope = "pr
|
|
|
1547
1723
|
};
|
|
1548
1724
|
for (const [filePath, action] of actions.entries()) {
|
|
1549
1725
|
const providersForFile = providers.filter((provider) => {
|
|
1550
|
-
const expectedPath = scope === "global" ?
|
|
1726
|
+
const expectedPath = scope === "global" ? join6(provider.pathGlobal, provider.instructFile) : join6(projectDir, provider.instructFile);
|
|
1551
1727
|
return expectedPath === filePath;
|
|
1552
1728
|
});
|
|
1553
1729
|
const fallback = groupedByFile.get(basename(filePath)) ?? [];
|
|
@@ -2415,7 +2591,7 @@ var MarketplaceClient = class {
|
|
|
2415
2591
|
// src/core/skills/library-loader.ts
|
|
2416
2592
|
import { createRequire } from "module";
|
|
2417
2593
|
import { existsSync as existsSync12, readdirSync, readFileSync as readFileSync2 } from "fs";
|
|
2418
|
-
import { basename as basename2, dirname as dirname5, join as
|
|
2594
|
+
import { basename as basename2, dirname as dirname5, join as join7 } from "path";
|
|
2419
2595
|
var require2 = createRequire(import.meta.url);
|
|
2420
2596
|
function loadLibraryFromModule(root) {
|
|
2421
2597
|
let mod;
|
|
@@ -2463,14 +2639,14 @@ function loadLibraryFromModule(root) {
|
|
|
2463
2639
|
return mod;
|
|
2464
2640
|
}
|
|
2465
2641
|
function buildLibraryFromFiles(root) {
|
|
2466
|
-
const catalogPath =
|
|
2642
|
+
const catalogPath = join7(root, "skills.json");
|
|
2467
2643
|
if (!existsSync12(catalogPath)) {
|
|
2468
2644
|
throw new Error(`No skills.json found at ${root}`);
|
|
2469
2645
|
}
|
|
2470
2646
|
const catalogData = JSON.parse(readFileSync2(catalogPath, "utf-8"));
|
|
2471
2647
|
const entries = catalogData.skills ?? [];
|
|
2472
2648
|
const version = catalogData.version ?? "0.0.0";
|
|
2473
|
-
const manifestPath =
|
|
2649
|
+
const manifestPath = join7(root, "skills", "manifest.json");
|
|
2474
2650
|
let manifest;
|
|
2475
2651
|
if (existsSync12(manifestPath)) {
|
|
2476
2652
|
manifest = JSON.parse(readFileSync2(manifestPath, "utf-8"));
|
|
@@ -2482,14 +2658,14 @@ function buildLibraryFromFiles(root) {
|
|
|
2482
2658
|
skills: []
|
|
2483
2659
|
};
|
|
2484
2660
|
}
|
|
2485
|
-
const profilesDir =
|
|
2661
|
+
const profilesDir = join7(root, "profiles");
|
|
2486
2662
|
const profiles = /* @__PURE__ */ new Map();
|
|
2487
2663
|
if (existsSync12(profilesDir)) {
|
|
2488
2664
|
for (const file of readdirSync(profilesDir)) {
|
|
2489
2665
|
if (!file.endsWith(".json")) continue;
|
|
2490
2666
|
try {
|
|
2491
2667
|
const profile = JSON.parse(
|
|
2492
|
-
readFileSync2(
|
|
2668
|
+
readFileSync2(join7(profilesDir, file), "utf-8")
|
|
2493
2669
|
);
|
|
2494
2670
|
profiles.set(profile.name, profile);
|
|
2495
2671
|
} catch {
|
|
@@ -2503,9 +2679,9 @@ function buildLibraryFromFiles(root) {
|
|
|
2503
2679
|
function getSkillDir2(name) {
|
|
2504
2680
|
const entry = skillMap.get(name);
|
|
2505
2681
|
if (entry) {
|
|
2506
|
-
return dirname5(
|
|
2682
|
+
return dirname5(join7(root, entry.path));
|
|
2507
2683
|
}
|
|
2508
|
-
return
|
|
2684
|
+
return join7(root, "skills", name);
|
|
2509
2685
|
}
|
|
2510
2686
|
function resolveDeps(names, visited = /* @__PURE__ */ new Set()) {
|
|
2511
2687
|
const result = [];
|
|
@@ -2550,9 +2726,9 @@ function buildLibraryFromFiles(root) {
|
|
|
2550
2726
|
getSkillPath(name) {
|
|
2551
2727
|
const entry = skillMap.get(name);
|
|
2552
2728
|
if (entry) {
|
|
2553
|
-
return
|
|
2729
|
+
return join7(root, entry.path);
|
|
2554
2730
|
}
|
|
2555
|
-
return
|
|
2731
|
+
return join7(root, "skills", name, "SKILL.md");
|
|
2556
2732
|
},
|
|
2557
2733
|
getSkillDir: getSkillDir2,
|
|
2558
2734
|
readSkillContent(name) {
|
|
@@ -2584,10 +2760,10 @@ function buildLibraryFromFiles(root) {
|
|
|
2584
2760
|
return resolveProfileByName(name);
|
|
2585
2761
|
},
|
|
2586
2762
|
listSharedResources() {
|
|
2587
|
-
return discoverFiles(
|
|
2763
|
+
return discoverFiles(join7(root, "skills", "_shared"), ".md");
|
|
2588
2764
|
},
|
|
2589
2765
|
getSharedResourcePath(name) {
|
|
2590
|
-
const resourcePath =
|
|
2766
|
+
const resourcePath = join7(root, "skills", "_shared", `${name}.md`);
|
|
2591
2767
|
return existsSync12(resourcePath) ? resourcePath : void 0;
|
|
2592
2768
|
},
|
|
2593
2769
|
readSharedResource(name) {
|
|
@@ -2596,14 +2772,14 @@ function buildLibraryFromFiles(root) {
|
|
|
2596
2772
|
return readFileSync2(resourcePath, "utf-8");
|
|
2597
2773
|
},
|
|
2598
2774
|
listProtocols() {
|
|
2599
|
-
const rootProtocols = discoverFiles(
|
|
2775
|
+
const rootProtocols = discoverFiles(join7(root, "protocols"), ".md");
|
|
2600
2776
|
if (rootProtocols.length > 0) return rootProtocols;
|
|
2601
|
-
return discoverFiles(
|
|
2777
|
+
return discoverFiles(join7(root, "skills", "protocols"), ".md");
|
|
2602
2778
|
},
|
|
2603
2779
|
getProtocolPath(name) {
|
|
2604
|
-
const rootPath =
|
|
2780
|
+
const rootPath = join7(root, "protocols", `${name}.md`);
|
|
2605
2781
|
if (existsSync12(rootPath)) return rootPath;
|
|
2606
|
-
const skillsPath =
|
|
2782
|
+
const skillsPath = join7(root, "skills", "protocols", `${name}.md`);
|
|
2607
2783
|
return existsSync12(skillsPath) ? skillsPath : void 0;
|
|
2608
2784
|
},
|
|
2609
2785
|
readProtocol(name) {
|
|
@@ -2629,7 +2805,7 @@ function buildLibraryFromFiles(root) {
|
|
|
2629
2805
|
if (!entry.version) {
|
|
2630
2806
|
issues.push({ level: "warn", field: "version", message: "Missing version" });
|
|
2631
2807
|
}
|
|
2632
|
-
const skillPath =
|
|
2808
|
+
const skillPath = join7(root, entry.path);
|
|
2633
2809
|
if (!existsSync12(skillPath)) {
|
|
2634
2810
|
issues.push({ level: "error", field: "path", message: `SKILL.md not found at ${entry.path}` });
|
|
2635
2811
|
}
|
|
@@ -2686,13 +2862,13 @@ __export(catalog_exports, {
|
|
|
2686
2862
|
validateSkillFrontmatter: () => validateSkillFrontmatter
|
|
2687
2863
|
});
|
|
2688
2864
|
import { existsSync as existsSync13 } from "fs";
|
|
2689
|
-
import { join as
|
|
2865
|
+
import { join as join8 } from "path";
|
|
2690
2866
|
var _library = null;
|
|
2691
2867
|
function registerSkillLibrary(library) {
|
|
2692
2868
|
_library = library;
|
|
2693
2869
|
}
|
|
2694
2870
|
function registerSkillLibraryFromPath(root) {
|
|
2695
|
-
const indexPath =
|
|
2871
|
+
const indexPath = join8(root, "index.js");
|
|
2696
2872
|
if (existsSync13(indexPath)) {
|
|
2697
2873
|
_library = loadLibraryFromModule(root);
|
|
2698
2874
|
return;
|
|
@@ -2706,11 +2882,11 @@ function discoverLibrary() {
|
|
|
2706
2882
|
const envPath = process.env["CAAMP_SKILL_LIBRARY"];
|
|
2707
2883
|
if (envPath && existsSync13(envPath)) {
|
|
2708
2884
|
try {
|
|
2709
|
-
const indexPath =
|
|
2885
|
+
const indexPath = join8(envPath, "index.js");
|
|
2710
2886
|
if (existsSync13(indexPath)) {
|
|
2711
2887
|
return loadLibraryFromModule(envPath);
|
|
2712
2888
|
}
|
|
2713
|
-
if (existsSync13(
|
|
2889
|
+
if (existsSync13(join8(envPath, "skills.json"))) {
|
|
2714
2890
|
return buildLibraryFromFiles(envPath);
|
|
2715
2891
|
}
|
|
2716
2892
|
} catch {
|
|
@@ -2819,7 +2995,7 @@ function getLibraryRoot() {
|
|
|
2819
2995
|
// src/core/skills/discovery.ts
|
|
2820
2996
|
import { readFile as readFile7, readdir } from "fs/promises";
|
|
2821
2997
|
import { existsSync as existsSync14 } from "fs";
|
|
2822
|
-
import { join as
|
|
2998
|
+
import { join as join9 } from "path";
|
|
2823
2999
|
import matter from "gray-matter";
|
|
2824
3000
|
async function parseSkillFile(filePath) {
|
|
2825
3001
|
try {
|
|
@@ -2843,7 +3019,7 @@ async function parseSkillFile(filePath) {
|
|
|
2843
3019
|
}
|
|
2844
3020
|
}
|
|
2845
3021
|
async function discoverSkill(skillDir) {
|
|
2846
|
-
const skillFile =
|
|
3022
|
+
const skillFile = join9(skillDir, "SKILL.md");
|
|
2847
3023
|
if (!existsSync14(skillFile)) return null;
|
|
2848
3024
|
const metadata = await parseSkillFile(skillFile);
|
|
2849
3025
|
if (!metadata) return null;
|
|
@@ -2860,7 +3036,7 @@ async function discoverSkills(rootDir) {
|
|
|
2860
3036
|
const skills = [];
|
|
2861
3037
|
for (const entry of entries) {
|
|
2862
3038
|
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
2863
|
-
const skillDir =
|
|
3039
|
+
const skillDir = join9(rootDir, entry.name);
|
|
2864
3040
|
const skill = await discoverSkill(skillDir);
|
|
2865
3041
|
if (skill) {
|
|
2866
3042
|
skills.push(skill);
|
|
@@ -3698,13 +3874,13 @@ async function scanFile(filePath, rules) {
|
|
|
3698
3874
|
}
|
|
3699
3875
|
async function scanDirectory(dirPath) {
|
|
3700
3876
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
3701
|
-
const { join:
|
|
3877
|
+
const { join: join10 } = await import("path");
|
|
3702
3878
|
if (!existsSync15(dirPath)) return [];
|
|
3703
3879
|
const entries = await readdir2(dirPath, { withFileTypes: true });
|
|
3704
3880
|
const results = [];
|
|
3705
3881
|
for (const entry of entries) {
|
|
3706
3882
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
3707
|
-
const skillFile =
|
|
3883
|
+
const skillFile = join10(dirPath, entry.name, "SKILL.md");
|
|
3708
3884
|
if (existsSync15(skillFile)) {
|
|
3709
3885
|
results.push(await scanFile(skillFile));
|
|
3710
3886
|
}
|
|
@@ -3930,6 +4106,7 @@ export {
|
|
|
3930
4106
|
resolveProviderConfigPath,
|
|
3931
4107
|
resolvePreferredConfigScope,
|
|
3932
4108
|
resolveProviderSkillsDir,
|
|
4109
|
+
resolveProviderSkillsDirs,
|
|
3933
4110
|
buildSkillSubPathCandidates,
|
|
3934
4111
|
resolveConfigPath,
|
|
3935
4112
|
listMcpServers,
|
|
@@ -3950,6 +4127,16 @@ export {
|
|
|
3950
4127
|
getInstructionFiles,
|
|
3951
4128
|
getProviderCount,
|
|
3952
4129
|
getRegistryVersion,
|
|
4130
|
+
getProvidersByHookEvent,
|
|
4131
|
+
getCommonHookEvents,
|
|
4132
|
+
providerSupports,
|
|
4133
|
+
getSpawnCapableProviders,
|
|
4134
|
+
getProvidersBySpawnCapability,
|
|
4135
|
+
getProvidersBySkillsPrecedence,
|
|
4136
|
+
getEffectiveSkillsPaths,
|
|
4137
|
+
buildSkillsMap,
|
|
4138
|
+
getProviderCapabilities,
|
|
4139
|
+
providerSupportsById,
|
|
3953
4140
|
detectProvider,
|
|
3954
4141
|
detectAllProviders,
|
|
3955
4142
|
getInstalledProviders,
|
|
@@ -4019,4 +4206,4 @@ export {
|
|
|
4019
4206
|
toSarif,
|
|
4020
4207
|
validateSkill
|
|
4021
4208
|
};
|
|
4022
|
-
//# sourceMappingURL=chunk-
|
|
4209
|
+
//# sourceMappingURL=chunk-N5E7BZM2.js.map
|