@cleocode/caamp 0.1.0 → 0.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.
- package/README.md +152 -32
- package/dist/{chunk-63BH7QMR.js → chunk-PCWTRJV2.js} +201 -90
- package/dist/chunk-PCWTRJV2.js.map +1 -0
- package/dist/cli.d.ts +0 -0
- package/dist/cli.js +405 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1491 -60
- package/dist/index.js +9 -1
- package/dist/index.js.map +0 -0
- package/package.json +16 -13
- package/providers/registry.json +455 -5
- package/dist/chunk-63BH7QMR.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
listMcpServers,
|
|
25
25
|
parseSource,
|
|
26
26
|
readConfig,
|
|
27
|
+
readLockFile,
|
|
27
28
|
recordMcpInstall,
|
|
28
29
|
recordSkillInstall,
|
|
29
30
|
removeMcpFromLock,
|
|
@@ -33,9 +34,11 @@ import {
|
|
|
33
34
|
resolveConfigPath,
|
|
34
35
|
scanDirectory,
|
|
35
36
|
scanFile,
|
|
37
|
+
setQuiet,
|
|
38
|
+
setVerbose,
|
|
36
39
|
toSarif,
|
|
37
40
|
validateSkill
|
|
38
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-PCWTRJV2.js";
|
|
39
42
|
|
|
40
43
|
// src/cli.ts
|
|
41
44
|
import { Command } from "commander";
|
|
@@ -208,7 +211,7 @@ function registerSkillsInstall(parent) {
|
|
|
208
211
|
let cleanup;
|
|
209
212
|
let skillName;
|
|
210
213
|
let sourceValue;
|
|
211
|
-
let sourceType
|
|
214
|
+
let sourceType;
|
|
212
215
|
if (isMarketplaceScoped(source)) {
|
|
213
216
|
console.log(pc2.dim(`Searching marketplace for ${source}...`));
|
|
214
217
|
const client = new MarketplaceClient();
|
|
@@ -228,10 +231,12 @@ function registerSkillsInstall(parent) {
|
|
|
228
231
|
cleanup = result.cleanup;
|
|
229
232
|
skillName = skill.name;
|
|
230
233
|
sourceValue = skill.githubUrl;
|
|
234
|
+
sourceType = parsed.type;
|
|
231
235
|
} else {
|
|
232
236
|
const parsed = parseSource(source);
|
|
233
237
|
skillName = parsed.inferredName;
|
|
234
238
|
sourceValue = parsed.value;
|
|
239
|
+
sourceType = parsed.type;
|
|
235
240
|
if (parsed.type === "github" && parsed.owner && parsed.repo) {
|
|
236
241
|
const result = await cloneRepo(parsed.owner, parsed.repo, parsed.ref, parsed.path);
|
|
237
242
|
localPath = result.localPath;
|
|
@@ -399,6 +404,8 @@ function registerSkillsCheck(parent) {
|
|
|
399
404
|
console.log(pc6.dim("No tracked skills."));
|
|
400
405
|
return;
|
|
401
406
|
}
|
|
407
|
+
console.log(pc6.dim(`Checking ${entries.length} skill(s) for updates...
|
|
408
|
+
`));
|
|
402
409
|
const results = [];
|
|
403
410
|
for (const [name, entry] of entries) {
|
|
404
411
|
const update = await checkSkillUpdate(name);
|
|
@@ -408,16 +415,37 @@ function registerSkillsCheck(parent) {
|
|
|
408
415
|
console.log(JSON.stringify(results, null, 2));
|
|
409
416
|
return;
|
|
410
417
|
}
|
|
411
|
-
|
|
412
|
-
${entries.length} tracked skill(s):
|
|
413
|
-
`));
|
|
418
|
+
let updatesAvailable = 0;
|
|
414
419
|
for (const r of results) {
|
|
415
|
-
|
|
416
|
-
|
|
420
|
+
let statusLabel;
|
|
421
|
+
if (r.status === "update-available") {
|
|
422
|
+
statusLabel = pc6.yellow("update available");
|
|
423
|
+
updatesAvailable++;
|
|
424
|
+
} else if (r.status === "up-to-date") {
|
|
425
|
+
statusLabel = pc6.green("up to date");
|
|
426
|
+
} else {
|
|
427
|
+
statusLabel = pc6.dim("unknown");
|
|
428
|
+
}
|
|
429
|
+
console.log(` ${pc6.bold(r.name.padEnd(30))} ${statusLabel}`);
|
|
430
|
+
if (r.currentVersion || r.latestVersion) {
|
|
431
|
+
const current = r.currentVersion ? r.currentVersion.slice(0, 12) : "?";
|
|
432
|
+
const latest = r.latestVersion ?? "?";
|
|
433
|
+
if (r.hasUpdate) {
|
|
434
|
+
console.log(` ${pc6.dim("current:")} ${current} ${pc6.dim("->")} ${pc6.cyan(latest)}`);
|
|
435
|
+
} else {
|
|
436
|
+
console.log(` ${pc6.dim("version:")} ${current}`);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
417
439
|
console.log(` ${pc6.dim(`source: ${r.entry.source}`)}`);
|
|
418
440
|
console.log(` ${pc6.dim(`agents: ${r.entry.agents.join(", ")}`)}`);
|
|
419
441
|
console.log();
|
|
420
442
|
}
|
|
443
|
+
if (updatesAvailable > 0) {
|
|
444
|
+
console.log(pc6.yellow(`${updatesAvailable} update(s) available.`));
|
|
445
|
+
console.log(pc6.dim("Run `caamp skills update` to update all."));
|
|
446
|
+
} else {
|
|
447
|
+
console.log(pc6.green("All skills are up to date."));
|
|
448
|
+
}
|
|
421
449
|
});
|
|
422
450
|
}
|
|
423
451
|
|
|
@@ -432,9 +460,116 @@ function registerSkillsUpdate(parent) {
|
|
|
432
460
|
return;
|
|
433
461
|
}
|
|
434
462
|
console.log(pc7.dim(`Checking ${entries.length} skill(s) for updates...`));
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
463
|
+
const outdated = [];
|
|
464
|
+
for (const [name] of entries) {
|
|
465
|
+
const result = await checkSkillUpdate(name);
|
|
466
|
+
if (result.hasUpdate) {
|
|
467
|
+
outdated.push({
|
|
468
|
+
name,
|
|
469
|
+
currentVersion: result.currentVersion,
|
|
470
|
+
latestVersion: result.latestVersion
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
if (outdated.length === 0) {
|
|
475
|
+
console.log(pc7.green("\nAll skills are up to date."));
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
console.log(pc7.yellow(`
|
|
479
|
+
${outdated.length} skill(s) have updates available:
|
|
480
|
+
`));
|
|
481
|
+
for (const skill of outdated) {
|
|
482
|
+
const current = skill.currentVersion?.slice(0, 12) ?? "?";
|
|
483
|
+
const latest = skill.latestVersion ?? "?";
|
|
484
|
+
console.log(` ${pc7.bold(skill.name)} ${pc7.dim(current)} ${pc7.dim("->")} ${pc7.cyan(latest)}`);
|
|
485
|
+
}
|
|
486
|
+
if (!opts.yes) {
|
|
487
|
+
const readline = await import("readline");
|
|
488
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
489
|
+
const answer = await new Promise((resolve) => {
|
|
490
|
+
rl.question(pc7.dim("\nProceed with update? [y/N] "), resolve);
|
|
491
|
+
});
|
|
492
|
+
rl.close();
|
|
493
|
+
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
494
|
+
console.log(pc7.dim("Update cancelled."));
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
console.log();
|
|
499
|
+
let successCount = 0;
|
|
500
|
+
let failCount = 0;
|
|
501
|
+
for (const skill of outdated) {
|
|
502
|
+
const entry = tracked[skill.name];
|
|
503
|
+
if (!entry) continue;
|
|
504
|
+
console.log(pc7.dim(`Updating ${pc7.bold(skill.name)}...`));
|
|
505
|
+
try {
|
|
506
|
+
const parsed = parseSource(entry.source);
|
|
507
|
+
let localPath;
|
|
508
|
+
let cleanup;
|
|
509
|
+
if (parsed.type === "github" && parsed.owner && parsed.repo) {
|
|
510
|
+
const result = await cloneRepo(parsed.owner, parsed.repo, parsed.ref, parsed.path);
|
|
511
|
+
localPath = result.localPath;
|
|
512
|
+
cleanup = result.cleanup;
|
|
513
|
+
} else if (parsed.type === "gitlab" && parsed.owner && parsed.repo) {
|
|
514
|
+
const result = await cloneGitLabRepo(parsed.owner, parsed.repo, parsed.ref, parsed.path);
|
|
515
|
+
localPath = result.localPath;
|
|
516
|
+
cleanup = result.cleanup;
|
|
517
|
+
} else {
|
|
518
|
+
console.log(pc7.yellow(` Skipped ${skill.name}: source type "${parsed.type}" does not support auto-update`));
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
try {
|
|
522
|
+
const providers = entry.agents.map((a) => getProvider(a)).filter((p) => p !== void 0);
|
|
523
|
+
if (providers.length === 0) {
|
|
524
|
+
console.log(pc7.yellow(` Skipped ${skill.name}: no valid providers found`));
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
const installResult = await installSkill(
|
|
528
|
+
localPath,
|
|
529
|
+
skill.name,
|
|
530
|
+
providers,
|
|
531
|
+
entry.isGlobal,
|
|
532
|
+
entry.projectDir
|
|
533
|
+
);
|
|
534
|
+
if (installResult.success) {
|
|
535
|
+
await recordSkillInstall(
|
|
536
|
+
skill.name,
|
|
537
|
+
entry.scopedName,
|
|
538
|
+
entry.source,
|
|
539
|
+
entry.sourceType,
|
|
540
|
+
installResult.linkedAgents,
|
|
541
|
+
installResult.canonicalPath,
|
|
542
|
+
entry.isGlobal,
|
|
543
|
+
entry.projectDir,
|
|
544
|
+
skill.latestVersion
|
|
545
|
+
);
|
|
546
|
+
console.log(pc7.green(` Updated ${pc7.bold(skill.name)}`));
|
|
547
|
+
successCount++;
|
|
548
|
+
} else {
|
|
549
|
+
console.log(pc7.red(` Failed to update ${skill.name}: no agents linked`));
|
|
550
|
+
failCount++;
|
|
551
|
+
}
|
|
552
|
+
if (installResult.errors.length > 0) {
|
|
553
|
+
for (const err of installResult.errors) {
|
|
554
|
+
console.log(pc7.yellow(` ${err}`));
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
} finally {
|
|
558
|
+
if (cleanup) await cleanup();
|
|
559
|
+
}
|
|
560
|
+
} catch (err) {
|
|
561
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
562
|
+
console.log(pc7.red(` Failed to update ${skill.name}: ${msg}`));
|
|
563
|
+
failCount++;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
console.log();
|
|
567
|
+
if (successCount > 0) {
|
|
568
|
+
console.log(pc7.green(`Updated ${successCount} skill(s).`));
|
|
569
|
+
}
|
|
570
|
+
if (failCount > 0) {
|
|
571
|
+
console.log(pc7.red(`Failed to update ${failCount} skill(s).`));
|
|
572
|
+
}
|
|
438
573
|
});
|
|
439
574
|
}
|
|
440
575
|
|
|
@@ -929,13 +1064,272 @@ ${provider.toolName} config (${configPath}):
|
|
|
929
1064
|
});
|
|
930
1065
|
}
|
|
931
1066
|
|
|
1067
|
+
// src/commands/doctor.ts
|
|
1068
|
+
import pc19 from "picocolors";
|
|
1069
|
+
import { execFileSync } from "child_process";
|
|
1070
|
+
import { existsSync as existsSync5, readdirSync, lstatSync } from "fs";
|
|
1071
|
+
import { homedir } from "os";
|
|
1072
|
+
import { join as join6 } from "path";
|
|
1073
|
+
var CAAMP_VERSION = "0.2.0";
|
|
1074
|
+
function getNodeVersion() {
|
|
1075
|
+
return process.version;
|
|
1076
|
+
}
|
|
1077
|
+
function getNpmVersion() {
|
|
1078
|
+
try {
|
|
1079
|
+
return execFileSync("npm", ["--version"], { stdio: "pipe", encoding: "utf-8" }).trim();
|
|
1080
|
+
} catch {
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
function checkEnvironment() {
|
|
1085
|
+
const checks = [];
|
|
1086
|
+
checks.push({ label: `Node.js ${getNodeVersion()}`, status: "pass" });
|
|
1087
|
+
const npmVersion = getNpmVersion();
|
|
1088
|
+
if (npmVersion) {
|
|
1089
|
+
checks.push({ label: `npm ${npmVersion}`, status: "pass" });
|
|
1090
|
+
} else {
|
|
1091
|
+
checks.push({ label: "npm not found", status: "warn" });
|
|
1092
|
+
}
|
|
1093
|
+
checks.push({ label: `CAAMP v${CAAMP_VERSION}`, status: "pass" });
|
|
1094
|
+
checks.push({ label: `${process.platform} ${process.arch}`, status: "pass" });
|
|
1095
|
+
return { name: "Environment", checks };
|
|
1096
|
+
}
|
|
1097
|
+
function checkRegistry() {
|
|
1098
|
+
const checks = [];
|
|
1099
|
+
try {
|
|
1100
|
+
const providers = getAllProviders();
|
|
1101
|
+
const count = getProviderCount();
|
|
1102
|
+
checks.push({ label: `${count} providers loaded`, status: "pass" });
|
|
1103
|
+
const malformed = [];
|
|
1104
|
+
for (const p of providers) {
|
|
1105
|
+
if (!p.id || !p.toolName || !p.configKey || !p.configFormat) {
|
|
1106
|
+
malformed.push(p.id || "(unknown)");
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
if (malformed.length === 0) {
|
|
1110
|
+
checks.push({ label: "All entries valid", status: "pass" });
|
|
1111
|
+
} else {
|
|
1112
|
+
checks.push({
|
|
1113
|
+
label: `${malformed.length} malformed entries`,
|
|
1114
|
+
status: "fail",
|
|
1115
|
+
detail: malformed.join(", ")
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
} catch (err) {
|
|
1119
|
+
checks.push({
|
|
1120
|
+
label: "Failed to load registry",
|
|
1121
|
+
status: "fail",
|
|
1122
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
return { name: "Registry", checks };
|
|
1126
|
+
}
|
|
1127
|
+
function checkInstalledProviders() {
|
|
1128
|
+
const checks = [];
|
|
1129
|
+
try {
|
|
1130
|
+
const results = detectAllProviders();
|
|
1131
|
+
const installed = results.filter((r) => r.installed);
|
|
1132
|
+
checks.push({ label: `${installed.length} found`, status: "pass" });
|
|
1133
|
+
for (const r of installed) {
|
|
1134
|
+
const methods = r.methods.join(", ");
|
|
1135
|
+
checks.push({ label: `${r.provider.toolName} (${methods})`, status: "pass" });
|
|
1136
|
+
}
|
|
1137
|
+
} catch (err) {
|
|
1138
|
+
checks.push({
|
|
1139
|
+
label: "Detection failed",
|
|
1140
|
+
status: "fail",
|
|
1141
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
return { name: "Installed Providers", checks };
|
|
1145
|
+
}
|
|
1146
|
+
function checkSkillSymlinks() {
|
|
1147
|
+
const checks = [];
|
|
1148
|
+
const canonicalDir = join6(homedir(), ".agents", "skills");
|
|
1149
|
+
if (!existsSync5(canonicalDir)) {
|
|
1150
|
+
checks.push({ label: "0 canonical skills", status: "pass" });
|
|
1151
|
+
checks.push({ label: "No broken symlinks", status: "pass" });
|
|
1152
|
+
return { name: "Skills", checks };
|
|
1153
|
+
}
|
|
1154
|
+
let canonicalCount = 0;
|
|
1155
|
+
try {
|
|
1156
|
+
const entries = readdirSync(canonicalDir);
|
|
1157
|
+
canonicalCount = entries.length;
|
|
1158
|
+
checks.push({ label: `${canonicalCount} canonical skills`, status: "pass" });
|
|
1159
|
+
} catch {
|
|
1160
|
+
checks.push({ label: "Cannot read skills directory", status: "warn" });
|
|
1161
|
+
return { name: "Skills", checks };
|
|
1162
|
+
}
|
|
1163
|
+
const broken = [];
|
|
1164
|
+
const providers = getAllProviders();
|
|
1165
|
+
for (const provider of providers) {
|
|
1166
|
+
const skillDir = provider.pathSkills;
|
|
1167
|
+
if (!existsSync5(skillDir)) continue;
|
|
1168
|
+
try {
|
|
1169
|
+
const entries = readdirSync(skillDir);
|
|
1170
|
+
for (const entry of entries) {
|
|
1171
|
+
const fullPath = join6(skillDir, entry);
|
|
1172
|
+
try {
|
|
1173
|
+
const stat = lstatSync(fullPath);
|
|
1174
|
+
if (stat.isSymbolicLink()) {
|
|
1175
|
+
if (!existsSync5(fullPath)) {
|
|
1176
|
+
broken.push(`${provider.id}/${entry}`);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
} catch {
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
} catch {
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
if (broken.length === 0) {
|
|
1186
|
+
checks.push({ label: "No broken symlinks", status: "pass" });
|
|
1187
|
+
} else {
|
|
1188
|
+
checks.push({
|
|
1189
|
+
label: `${broken.length} broken symlinks`,
|
|
1190
|
+
status: "warn",
|
|
1191
|
+
detail: broken.join(", ")
|
|
1192
|
+
});
|
|
1193
|
+
}
|
|
1194
|
+
return { name: "Skills", checks };
|
|
1195
|
+
}
|
|
1196
|
+
async function checkLockFile() {
|
|
1197
|
+
const checks = [];
|
|
1198
|
+
try {
|
|
1199
|
+
const lock = await readLockFile();
|
|
1200
|
+
checks.push({ label: "Lock file valid", status: "pass" });
|
|
1201
|
+
let orphaned = 0;
|
|
1202
|
+
for (const [name, entry] of Object.entries(lock.skills)) {
|
|
1203
|
+
if (entry.canonicalPath && !existsSync5(entry.canonicalPath)) {
|
|
1204
|
+
orphaned++;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
if (orphaned === 0) {
|
|
1208
|
+
checks.push({ label: `0 orphaned entries`, status: "pass" });
|
|
1209
|
+
} else {
|
|
1210
|
+
checks.push({
|
|
1211
|
+
label: `${orphaned} orphaned skill entries`,
|
|
1212
|
+
status: "warn",
|
|
1213
|
+
detail: "Skills tracked in lock file but missing from disk"
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
} catch (err) {
|
|
1217
|
+
checks.push({
|
|
1218
|
+
label: "Failed to read lock file",
|
|
1219
|
+
status: "fail",
|
|
1220
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
return { name: "Lock File", checks };
|
|
1224
|
+
}
|
|
1225
|
+
async function checkConfigFiles() {
|
|
1226
|
+
const checks = [];
|
|
1227
|
+
const results = detectAllProviders();
|
|
1228
|
+
const installed = results.filter((r) => r.installed);
|
|
1229
|
+
for (const r of installed) {
|
|
1230
|
+
const provider = r.provider;
|
|
1231
|
+
const configPath = provider.configPathGlobal;
|
|
1232
|
+
if (!existsSync5(configPath)) {
|
|
1233
|
+
checks.push({
|
|
1234
|
+
label: `${provider.id}: no config file found`,
|
|
1235
|
+
status: "warn",
|
|
1236
|
+
detail: configPath
|
|
1237
|
+
});
|
|
1238
|
+
continue;
|
|
1239
|
+
}
|
|
1240
|
+
try {
|
|
1241
|
+
await readConfig(configPath, provider.configFormat);
|
|
1242
|
+
const relPath = configPath.replace(homedir(), "~");
|
|
1243
|
+
checks.push({
|
|
1244
|
+
label: `${provider.id}: ${relPath} readable`,
|
|
1245
|
+
status: "pass"
|
|
1246
|
+
});
|
|
1247
|
+
} catch (err) {
|
|
1248
|
+
checks.push({
|
|
1249
|
+
label: `${provider.id}: config parse error`,
|
|
1250
|
+
status: "fail",
|
|
1251
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
if (installed.length === 0) {
|
|
1256
|
+
checks.push({ label: "No installed providers to check", status: "pass" });
|
|
1257
|
+
}
|
|
1258
|
+
return { name: "Config Files", checks };
|
|
1259
|
+
}
|
|
1260
|
+
function formatSection(section) {
|
|
1261
|
+
const lines = [];
|
|
1262
|
+
lines.push(` ${pc19.bold(section.name)}`);
|
|
1263
|
+
for (const check of section.checks) {
|
|
1264
|
+
const icon = check.status === "pass" ? pc19.green("\u2713") : check.status === "warn" ? pc19.yellow("\u26A0") : pc19.red("\u2717");
|
|
1265
|
+
lines.push(` ${icon} ${check.label}`);
|
|
1266
|
+
if (check.detail) {
|
|
1267
|
+
lines.push(` ${pc19.dim(check.detail)}`);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
return lines.join("\n");
|
|
1271
|
+
}
|
|
1272
|
+
function registerDoctorCommand(program2) {
|
|
1273
|
+
program2.command("doctor").description("Diagnose configuration issues and health").option("--json", "Output as JSON").action(async (opts) => {
|
|
1274
|
+
const sections = [];
|
|
1275
|
+
sections.push(checkEnvironment());
|
|
1276
|
+
sections.push(checkRegistry());
|
|
1277
|
+
sections.push(checkInstalledProviders());
|
|
1278
|
+
sections.push(checkSkillSymlinks());
|
|
1279
|
+
sections.push(await checkLockFile());
|
|
1280
|
+
sections.push(await checkConfigFiles());
|
|
1281
|
+
let passed = 0;
|
|
1282
|
+
let warnings = 0;
|
|
1283
|
+
let errors = 0;
|
|
1284
|
+
for (const section of sections) {
|
|
1285
|
+
for (const check of section.checks) {
|
|
1286
|
+
if (check.status === "pass") passed++;
|
|
1287
|
+
else if (check.status === "warn") warnings++;
|
|
1288
|
+
else errors++;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
if (opts.json) {
|
|
1292
|
+
const output = {
|
|
1293
|
+
version: CAAMP_VERSION,
|
|
1294
|
+
sections: sections.map((s) => ({
|
|
1295
|
+
name: s.name,
|
|
1296
|
+
checks: s.checks
|
|
1297
|
+
})),
|
|
1298
|
+
summary: { passed, warnings, errors }
|
|
1299
|
+
};
|
|
1300
|
+
console.log(JSON.stringify(output, null, 2));
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
console.log(pc19.bold("\ncaamp doctor\n"));
|
|
1304
|
+
for (const section of sections) {
|
|
1305
|
+
console.log(formatSection(section));
|
|
1306
|
+
console.log();
|
|
1307
|
+
}
|
|
1308
|
+
const parts = [];
|
|
1309
|
+
parts.push(pc19.green(`${passed} checks passed`));
|
|
1310
|
+
if (warnings > 0) parts.push(pc19.yellow(`${warnings} warning${warnings !== 1 ? "s" : ""}`));
|
|
1311
|
+
if (errors > 0) parts.push(pc19.red(`${errors} error${errors !== 1 ? "s" : ""}`));
|
|
1312
|
+
console.log(` ${pc19.bold("Summary")}: ${parts.join(", ")}`);
|
|
1313
|
+
console.log();
|
|
1314
|
+
if (errors > 0) {
|
|
1315
|
+
process.exit(1);
|
|
1316
|
+
}
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
|
|
932
1320
|
// src/cli.ts
|
|
933
1321
|
var program = new Command();
|
|
934
|
-
program.name("caamp").description("Central AI Agent Managed Packages - unified provider registry and package manager").version("0.
|
|
1322
|
+
program.name("caamp").description("Central AI Agent Managed Packages - unified provider registry and package manager").version("0.3.0").option("-v, --verbose", "Show debug output").option("-q, --quiet", "Suppress non-error output");
|
|
1323
|
+
program.hook("preAction", (thisCommand) => {
|
|
1324
|
+
const opts = thisCommand.optsWithGlobals();
|
|
1325
|
+
if (opts.verbose) setVerbose(true);
|
|
1326
|
+
if (opts.quiet) setQuiet(true);
|
|
1327
|
+
});
|
|
935
1328
|
registerProvidersCommand(program);
|
|
936
1329
|
registerSkillsCommands(program);
|
|
937
1330
|
registerMcpCommands(program);
|
|
938
1331
|
registerInstructionsCommands(program);
|
|
939
1332
|
registerConfigCommand(program);
|
|
1333
|
+
registerDoctorCommand(program);
|
|
940
1334
|
program.parse();
|
|
941
1335
|
//# sourceMappingURL=cli.js.map
|