@cleocode/caamp 2026.5.82 → 2026.5.84
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-OCI4RYI5.js → chunk-H5YXR2DC.js} +31 -2
- package/dist/chunk-H5YXR2DC.js.map +1 -0
- package/dist/{chunk-OPUPNLUJ.js → chunk-PGETUTYZ.js} +2 -2
- package/dist/{chunk-SV33CE5X.js → chunk-QKC2JRSG.js} +2 -2
- package/dist/{chunk-4W35AEYA.js → chunk-QSJSM57K.js} +477 -75
- package/dist/chunk-QSJSM57K.js.map +1 -0
- package/dist/cli.js +442 -245
- package/dist/cli.js.map +1 -1
- package/dist/{hooks-5EXBKPII.js → hooks-ZN3C4WCK.js} +3 -3
- package/dist/index.d.ts +399 -10
- package/dist/index.js +17 -5
- package/dist/index.js.map +1 -1
- package/dist/{injector-F4EHB3CZ.js → injector-QPOIJVOR.js} +3 -3
- package/package.json +5 -5
- package/dist/chunk-4W35AEYA.js.map +0 -1
- package/dist/chunk-OCI4RYI5.js.map +0 -1
- /package/dist/{chunk-OPUPNLUJ.js.map → chunk-PGETUTYZ.js.map} +0 -0
- /package/dist/{chunk-SV33CE5X.js.map → chunk-QKC2JRSG.js.map} +0 -0
- /package/dist/{hooks-5EXBKPII.js.map → hooks-ZN3C4WCK.js.map} +0 -0
- /package/dist/{injector-F4EHB3CZ.js.map → injector-QPOIJVOR.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CANONICAL_SKILLS_DIR,
|
|
4
|
+
ErrorCategories,
|
|
5
|
+
ErrorCodes,
|
|
4
6
|
MarketplaceClient,
|
|
5
7
|
PiHarness,
|
|
6
8
|
RECOMMENDATION_ERROR_CODES,
|
|
9
|
+
buildEnvelope,
|
|
7
10
|
checkSkillUpdate,
|
|
8
11
|
detectAllProviders,
|
|
9
12
|
detectMcpInstallations,
|
|
@@ -12,6 +15,8 @@ import {
|
|
|
12
15
|
discoverSkillsMulti,
|
|
13
16
|
dispatchInstallSkillAcrossProviders,
|
|
14
17
|
dispatchRemoveSkillAcrossProviders,
|
|
18
|
+
emitError,
|
|
19
|
+
emitJsonError,
|
|
15
20
|
fetchWithTimeout,
|
|
16
21
|
formatNetworkError,
|
|
17
22
|
formatSkillRecommendations,
|
|
@@ -20,27 +25,30 @@ import {
|
|
|
20
25
|
getSkill,
|
|
21
26
|
getSkillDir,
|
|
22
27
|
getTrackedSkills,
|
|
28
|
+
handleFormatError,
|
|
23
29
|
installBatchWithRollback,
|
|
24
30
|
installMcpServer,
|
|
25
31
|
isCatalogAvailable,
|
|
26
32
|
isHuman,
|
|
27
33
|
isMarketplaceScoped,
|
|
28
|
-
isQuiet,
|
|
29
34
|
isVerbose,
|
|
30
35
|
listAllMcpServers,
|
|
31
36
|
listCanonicalSkills,
|
|
32
37
|
listMcpServers,
|
|
33
38
|
listProfiles,
|
|
34
39
|
listSkills,
|
|
40
|
+
outputSuccess,
|
|
35
41
|
parseSource,
|
|
36
42
|
readConfig,
|
|
37
43
|
readLockFile,
|
|
38
44
|
recommendSkills,
|
|
39
45
|
recordSkillInstall,
|
|
46
|
+
registerDoctorBridge,
|
|
40
47
|
removeMcpServer,
|
|
41
48
|
removeMcpServerFromAll,
|
|
42
49
|
removeSkillFromLock,
|
|
43
50
|
resolveDefaultTargetProviders,
|
|
51
|
+
resolveFormat,
|
|
44
52
|
resolveProfile,
|
|
45
53
|
scanDirectory,
|
|
46
54
|
scanFile,
|
|
@@ -52,7 +60,7 @@ import {
|
|
|
52
60
|
tokenizeCriteriaValue,
|
|
53
61
|
updateInstructionsSingleOperation,
|
|
54
62
|
validateSkill
|
|
55
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-QSJSM57K.js";
|
|
56
64
|
import {
|
|
57
65
|
buildSkillsMap,
|
|
58
66
|
checkAllInjections,
|
|
@@ -65,7 +73,7 @@ import {
|
|
|
65
73
|
groupByInstructFile,
|
|
66
74
|
injectAll,
|
|
67
75
|
providerSupports
|
|
68
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-PGETUTYZ.js";
|
|
69
77
|
import {
|
|
70
78
|
CANONICAL_HOOK_EVENTS,
|
|
71
79
|
buildHookMatrix,
|
|
@@ -74,12 +82,12 @@ import {
|
|
|
74
82
|
getHookSupport,
|
|
75
83
|
getProviderSummary,
|
|
76
84
|
translateToAll
|
|
77
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-QKC2JRSG.js";
|
|
78
86
|
import {
|
|
79
87
|
buildSkillSubPathCandidates,
|
|
80
88
|
resolveProviderConfigPath,
|
|
81
89
|
resolveProviderSkillsDir
|
|
82
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-H5YXR2DC.js";
|
|
83
91
|
|
|
84
92
|
// src/cli.ts
|
|
85
93
|
import { Command } from "commander";
|
|
@@ -153,7 +161,7 @@ function emitSuccess(operation, result, mvi = "standard") {
|
|
|
153
161
|
};
|
|
154
162
|
console.log(JSON.stringify(envelope, null, 2));
|
|
155
163
|
}
|
|
156
|
-
function
|
|
164
|
+
function emitError2(operation, error, mvi = "standard") {
|
|
157
165
|
let envelope;
|
|
158
166
|
if (error instanceof LAFSCommandError) {
|
|
159
167
|
envelope = {
|
|
@@ -204,7 +212,7 @@ async function runLafsCommand(command, mvi, action) {
|
|
|
204
212
|
const result = await action();
|
|
205
213
|
emitSuccess(command, result, mvi);
|
|
206
214
|
} catch (error) {
|
|
207
|
-
|
|
215
|
+
emitError2(command, error, mvi);
|
|
208
216
|
process.exit(1);
|
|
209
217
|
}
|
|
210
218
|
}
|
|
@@ -499,117 +507,6 @@ function registerAdvancedCommands(program2) {
|
|
|
499
507
|
// src/commands/config.ts
|
|
500
508
|
import { existsSync } from "fs";
|
|
501
509
|
import pc from "picocolors";
|
|
502
|
-
|
|
503
|
-
// src/core/lafs.ts
|
|
504
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
505
|
-
import { resolveOutputFormat } from "@cleocode/lafs";
|
|
506
|
-
function resolveFormat(options) {
|
|
507
|
-
return resolveOutputFormat({
|
|
508
|
-
jsonFlag: options.jsonFlag ?? false,
|
|
509
|
-
humanFlag: (options.humanFlag ?? false) || isHuman(),
|
|
510
|
-
projectDefault: options.projectDefault ?? "json"
|
|
511
|
-
}).format;
|
|
512
|
-
}
|
|
513
|
-
function buildEnvelope(operation, mvi, result, error, page = null, sessionId, warnings) {
|
|
514
|
-
return {
|
|
515
|
-
$schema: "https://lafs.dev/schemas/v1/envelope.schema.json",
|
|
516
|
-
_meta: {
|
|
517
|
-
specVersion: "1.0.0",
|
|
518
|
-
schemaVersion: "1.0.0",
|
|
519
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
520
|
-
operation,
|
|
521
|
-
requestId: randomUUID2(),
|
|
522
|
-
transport: "cli",
|
|
523
|
-
strict: true,
|
|
524
|
-
mvi,
|
|
525
|
-
contextVersion: 0,
|
|
526
|
-
...sessionId && { sessionId },
|
|
527
|
-
...warnings && warnings.length > 0 && { warnings }
|
|
528
|
-
},
|
|
529
|
-
success: error === null,
|
|
530
|
-
result,
|
|
531
|
-
error,
|
|
532
|
-
page
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
function emitError2(operation, mvi, code, message, category, details = {}, exitCode = 1) {
|
|
536
|
-
const envelope = buildEnvelope(operation, mvi, null, {
|
|
537
|
-
code,
|
|
538
|
-
message,
|
|
539
|
-
category,
|
|
540
|
-
retryable: category === "TRANSIENT" || category === "RATE_LIMIT",
|
|
541
|
-
retryAfterMs: null,
|
|
542
|
-
details
|
|
543
|
-
});
|
|
544
|
-
console.error(JSON.stringify(envelope, null, 2));
|
|
545
|
-
process.exit(exitCode);
|
|
546
|
-
}
|
|
547
|
-
function emitJsonError(operation, mvi, code, message, category, details = {}) {
|
|
548
|
-
const envelope = buildEnvelope(operation, mvi, null, {
|
|
549
|
-
code,
|
|
550
|
-
message,
|
|
551
|
-
category,
|
|
552
|
-
retryable: category === "TRANSIENT" || category === "RATE_LIMIT",
|
|
553
|
-
retryAfterMs: null,
|
|
554
|
-
details
|
|
555
|
-
});
|
|
556
|
-
console.error(JSON.stringify(envelope, null, 2));
|
|
557
|
-
}
|
|
558
|
-
function outputSuccess(operation, mvi, result, page, sessionId, warnings) {
|
|
559
|
-
const envelope = buildEnvelope(operation, mvi, result, null, page ?? null, sessionId, warnings);
|
|
560
|
-
if (isQuiet() && !envelope.error) {
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
console.log(JSON.stringify(envelope, null, 2));
|
|
564
|
-
}
|
|
565
|
-
function handleFormatError(error, operation, mvi, jsonFlag) {
|
|
566
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
567
|
-
if (jsonFlag) {
|
|
568
|
-
emitJsonError(operation, mvi, "E_FORMAT_CONFLICT", message, "VALIDATION");
|
|
569
|
-
} else {
|
|
570
|
-
console.error(message);
|
|
571
|
-
}
|
|
572
|
-
process.exit(1);
|
|
573
|
-
}
|
|
574
|
-
var ErrorCategories = {
|
|
575
|
-
VALIDATION: "VALIDATION",
|
|
576
|
-
AUTH: "AUTH",
|
|
577
|
-
PERMISSION: "PERMISSION",
|
|
578
|
-
NOT_FOUND: "NOT_FOUND",
|
|
579
|
-
CONFLICT: "CONFLICT",
|
|
580
|
-
RATE_LIMIT: "RATE_LIMIT",
|
|
581
|
-
TRANSIENT: "TRANSIENT",
|
|
582
|
-
INTERNAL: "INTERNAL",
|
|
583
|
-
CONTRACT: "CONTRACT",
|
|
584
|
-
MIGRATION: "MIGRATION"
|
|
585
|
-
};
|
|
586
|
-
var ErrorCodes = {
|
|
587
|
-
// Format errors
|
|
588
|
-
FORMAT_CONFLICT: "E_FORMAT_CONFLICT",
|
|
589
|
-
INVALID_JSON: "E_INVALID_JSON",
|
|
590
|
-
// Not found errors
|
|
591
|
-
SKILL_NOT_FOUND: "E_SKILL_NOT_FOUND",
|
|
592
|
-
PROVIDER_NOT_FOUND: "E_PROVIDER_NOT_FOUND",
|
|
593
|
-
MCP_SERVER_NOT_FOUND: "E_MCP_SERVER_NOT_FOUND",
|
|
594
|
-
FILE_NOT_FOUND: "E_FILE_NOT_FOUND",
|
|
595
|
-
// Validation errors
|
|
596
|
-
INVALID_INPUT: "E_INVALID_INPUT",
|
|
597
|
-
INVALID_CONSTRAINT: "E_INVALID_CONSTRAINT",
|
|
598
|
-
INVALID_FORMAT: "E_INVALID_FORMAT",
|
|
599
|
-
// Operation errors
|
|
600
|
-
INSTALL_FAILED: "E_INSTALL_FAILED",
|
|
601
|
-
REMOVE_FAILED: "E_REMOVE_FAILED",
|
|
602
|
-
UPDATE_FAILED: "E_UPDATE_FAILED",
|
|
603
|
-
VALIDATION_FAILED: "E_VALIDATION_FAILED",
|
|
604
|
-
AUDIT_FAILED: "E_AUDIT_FAILED",
|
|
605
|
-
// System errors
|
|
606
|
-
NETWORK_ERROR: "E_NETWORK_ERROR",
|
|
607
|
-
FILE_SYSTEM_ERROR: "E_FILE_SYSTEM_ERROR",
|
|
608
|
-
PERMISSION_DENIED: "E_PERMISSION_DENIED",
|
|
609
|
-
INTERNAL_ERROR: "E_INTERNAL_ERROR"
|
|
610
|
-
};
|
|
611
|
-
|
|
612
|
-
// src/commands/config.ts
|
|
613
510
|
function registerConfigCommand(program2) {
|
|
614
511
|
const config = program2.command("config").description("View provider configuration");
|
|
615
512
|
config.command("show").description("Show provider configuration").argument("<provider>", "Provider ID or alias").option("-g, --global", "Show global config").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(
|
|
@@ -2939,8 +2836,8 @@ function registerPiCommands(program2) {
|
|
|
2939
2836
|
}
|
|
2940
2837
|
|
|
2941
2838
|
// src/commands/providers.ts
|
|
2942
|
-
import { randomUUID as
|
|
2943
|
-
import { resolveOutputFormat
|
|
2839
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
2840
|
+
import { resolveOutputFormat } from "@cleocode/lafs";
|
|
2944
2841
|
import pc6 from "picocolors";
|
|
2945
2842
|
function registerProvidersCommand(program2) {
|
|
2946
2843
|
const providers = program2.command("providers").description("Manage AI agent providers");
|
|
@@ -2949,7 +2846,7 @@ function registerProvidersCommand(program2) {
|
|
|
2949
2846
|
const mvi = "standard";
|
|
2950
2847
|
let format;
|
|
2951
2848
|
try {
|
|
2952
|
-
format =
|
|
2849
|
+
format = resolveOutputFormat({
|
|
2953
2850
|
jsonFlag: opts.json ?? false,
|
|
2954
2851
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
2955
2852
|
projectDefault: "json"
|
|
@@ -2999,7 +2896,7 @@ CAMP Provider Registry v${getRegistryVersion()}`));
|
|
|
2999
2896
|
const mvi = "standard";
|
|
3000
2897
|
let format;
|
|
3001
2898
|
try {
|
|
3002
|
-
format =
|
|
2899
|
+
format = resolveOutputFormat({
|
|
3003
2900
|
jsonFlag: opts.json ?? false,
|
|
3004
2901
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3005
2902
|
projectDefault: "json"
|
|
@@ -3055,7 +2952,7 @@ Detected ${installed.length} installed providers:
|
|
|
3055
2952
|
const mvi = "standard";
|
|
3056
2953
|
let format;
|
|
3057
2954
|
try {
|
|
3058
|
-
format =
|
|
2955
|
+
format = resolveOutputFormat({
|
|
3059
2956
|
jsonFlag: opts.json ?? false,
|
|
3060
2957
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3061
2958
|
projectDefault: "json"
|
|
@@ -3128,7 +3025,7 @@ ${provider.toolName}`));
|
|
|
3128
3025
|
const mvi = "standard";
|
|
3129
3026
|
let format;
|
|
3130
3027
|
try {
|
|
3131
|
-
format =
|
|
3028
|
+
format = resolveOutputFormat({
|
|
3132
3029
|
jsonFlag: opts.json ?? false,
|
|
3133
3030
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3134
3031
|
projectDefault: "json"
|
|
@@ -3186,7 +3083,7 @@ ${provider.toolName}`));
|
|
|
3186
3083
|
const mvi = "standard";
|
|
3187
3084
|
let format;
|
|
3188
3085
|
try {
|
|
3189
|
-
format =
|
|
3086
|
+
format = resolveOutputFormat({
|
|
3190
3087
|
jsonFlag: opts.json ?? false,
|
|
3191
3088
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3192
3089
|
projectDefault: "json"
|
|
@@ -3254,7 +3151,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3254
3151
|
const mvi = "standard";
|
|
3255
3152
|
let format;
|
|
3256
3153
|
try {
|
|
3257
|
-
format =
|
|
3154
|
+
format = resolveOutputFormat({
|
|
3258
3155
|
jsonFlag: opts.json ?? false,
|
|
3259
3156
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3260
3157
|
projectDefault: "json"
|
|
@@ -3301,7 +3198,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3301
3198
|
const mvi = "standard";
|
|
3302
3199
|
let format;
|
|
3303
3200
|
try {
|
|
3304
|
-
format =
|
|
3201
|
+
format = resolveOutputFormat({
|
|
3305
3202
|
jsonFlag: opts.json ?? false,
|
|
3306
3203
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3307
3204
|
projectDefault: "json"
|
|
@@ -3349,7 +3246,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3349
3246
|
return;
|
|
3350
3247
|
}
|
|
3351
3248
|
if (opts.from) {
|
|
3352
|
-
const { toCanonical } = await import("./hooks-
|
|
3249
|
+
const { toCanonical } = await import("./hooks-ZN3C4WCK.js");
|
|
3353
3250
|
const canonical2 = toCanonical(event, opts.from);
|
|
3354
3251
|
if (format === "json") {
|
|
3355
3252
|
const envelope = buildEnvelope2(
|
|
@@ -3389,7 +3286,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3389
3286
|
}
|
|
3390
3287
|
process.exit(1);
|
|
3391
3288
|
}
|
|
3392
|
-
const { getMappedProviderIds } = await import("./hooks-
|
|
3289
|
+
const { getMappedProviderIds } = await import("./hooks-ZN3C4WCK.js");
|
|
3393
3290
|
const allIds = getMappedProviderIds();
|
|
3394
3291
|
const translations = translateToAll(canonical, allIds);
|
|
3395
3292
|
if (format === "json") {
|
|
@@ -3432,7 +3329,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3432
3329
|
const mvi = "standard";
|
|
3433
3330
|
let format;
|
|
3434
3331
|
try {
|
|
3435
|
-
format =
|
|
3332
|
+
format = resolveOutputFormat({
|
|
3436
3333
|
jsonFlag: opts.json ?? false,
|
|
3437
3334
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3438
3335
|
projectDefault: "json"
|
|
@@ -3502,7 +3399,7 @@ function buildEnvelope2(operation, mvi, result, error) {
|
|
|
3502
3399
|
schemaVersion: "1.0.0",
|
|
3503
3400
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3504
3401
|
operation,
|
|
3505
|
-
requestId:
|
|
3402
|
+
requestId: randomUUID2(),
|
|
3506
3403
|
transport: "cli",
|
|
3507
3404
|
strict: true,
|
|
3508
3405
|
mvi,
|
|
@@ -3817,10 +3714,308 @@ function registerSkillsCheck(parent) {
|
|
|
3817
3714
|
});
|
|
3818
3715
|
}
|
|
3819
3716
|
|
|
3820
|
-
// src/commands/skills/
|
|
3821
|
-
|
|
3822
|
-
|
|
3717
|
+
// src/commands/skills/doctor.ts
|
|
3718
|
+
function registerSkillsDoctor(parent) {
|
|
3719
|
+
const doctor = parent.command("doctor").description("Diagnose and repair the skill storage topology");
|
|
3720
|
+
registerDoctorBridge(doctor);
|
|
3721
|
+
}
|
|
3722
|
+
|
|
3723
|
+
// src/commands/skills/doctor-migrate.ts
|
|
3823
3724
|
import pc9 from "picocolors";
|
|
3725
|
+
|
|
3726
|
+
// src/core/skills/migration.ts
|
|
3727
|
+
import { execFile } from "child_process";
|
|
3728
|
+
import {
|
|
3729
|
+
cpSync,
|
|
3730
|
+
existsSync as existsSync10,
|
|
3731
|
+
mkdirSync,
|
|
3732
|
+
readdirSync as readdirSync2,
|
|
3733
|
+
rmSync,
|
|
3734
|
+
statSync as statSync3,
|
|
3735
|
+
writeFileSync
|
|
3736
|
+
} from "fs";
|
|
3737
|
+
import { homedir as homedir2 } from "os";
|
|
3738
|
+
import { join as join8 } from "path";
|
|
3739
|
+
import { promisify } from "util";
|
|
3740
|
+
var execFileAsync = promisify(execFile);
|
|
3741
|
+
var LEGACY_MIGRATED_MARKER = ".MIGRATED-TO-CLEO";
|
|
3742
|
+
function defaultMigrationOptions(manifestNames) {
|
|
3743
|
+
const home = homedir2();
|
|
3744
|
+
return {
|
|
3745
|
+
legacyRoot: join8(home, ".local", "share", "agents", "skills"),
|
|
3746
|
+
canonicalRoot: join8(home, ".cleo", "skills"),
|
|
3747
|
+
backupDir: join8(home, ".cleo", "backups", "skills"),
|
|
3748
|
+
manifestNames,
|
|
3749
|
+
now: () => /* @__PURE__ */ new Date(),
|
|
3750
|
+
tarExec: systemTarExec,
|
|
3751
|
+
recordRow: () => void 0
|
|
3752
|
+
};
|
|
3753
|
+
}
|
|
3754
|
+
var systemTarExec = {
|
|
3755
|
+
async create({ archivePath, sourceRoot }) {
|
|
3756
|
+
const parent = join8(sourceRoot, "..");
|
|
3757
|
+
const base = sourceRoot.slice(parent.length + 1);
|
|
3758
|
+
await execFileAsync("tar", ["-czf", archivePath, "-C", parent, base]);
|
|
3759
|
+
},
|
|
3760
|
+
async extract({ archivePath, destinationRoot }) {
|
|
3761
|
+
mkdirSync(destinationRoot, { recursive: true });
|
|
3762
|
+
const parent = join8(destinationRoot, "..");
|
|
3763
|
+
await execFileAsync("tar", ["-xzf", archivePath, "-C", parent]);
|
|
3764
|
+
}
|
|
3765
|
+
};
|
|
3766
|
+
function isAlreadyMigrated(legacyRoot) {
|
|
3767
|
+
if (!existsSync10(legacyRoot)) return true;
|
|
3768
|
+
return existsSync10(join8(legacyRoot, LEGACY_MIGRATED_MARKER));
|
|
3769
|
+
}
|
|
3770
|
+
function listSkillDirs(root) {
|
|
3771
|
+
if (!existsSync10(root)) return [];
|
|
3772
|
+
const entries = readdirSync2(root, { withFileTypes: true });
|
|
3773
|
+
return entries.filter((d) => d.isDirectory() && d.name !== LEGACY_MIGRATED_MARKER).map((d) => d.name).sort();
|
|
3774
|
+
}
|
|
3775
|
+
function planMigration(options) {
|
|
3776
|
+
const start = Date.now();
|
|
3777
|
+
const migrated = [];
|
|
3778
|
+
const skipped = [];
|
|
3779
|
+
if (isAlreadyMigrated(options.legacyRoot)) {
|
|
3780
|
+
return {
|
|
3781
|
+
action: "no-op",
|
|
3782
|
+
migrated,
|
|
3783
|
+
skipped,
|
|
3784
|
+
backupPath: null,
|
|
3785
|
+
legacyRoot: options.legacyRoot,
|
|
3786
|
+
canonicalRoot: options.canonicalRoot,
|
|
3787
|
+
durationMs: Date.now() - start
|
|
3788
|
+
};
|
|
3789
|
+
}
|
|
3790
|
+
const names = listSkillDirs(options.legacyRoot);
|
|
3791
|
+
for (const name of names) {
|
|
3792
|
+
const legacyPath = join8(options.legacyRoot, name);
|
|
3793
|
+
if (!statSync3(legacyPath).isDirectory()) {
|
|
3794
|
+
skipped.push({ name, reason: "not-a-directory", legacyPath });
|
|
3795
|
+
continue;
|
|
3796
|
+
}
|
|
3797
|
+
const destPath = join8(options.canonicalRoot, name);
|
|
3798
|
+
if (existsSync10(destPath)) {
|
|
3799
|
+
skipped.push({ name, reason: "already-present", legacyPath });
|
|
3800
|
+
continue;
|
|
3801
|
+
}
|
|
3802
|
+
migrated.push({
|
|
3803
|
+
name,
|
|
3804
|
+
installPath: destPath,
|
|
3805
|
+
legacyPath,
|
|
3806
|
+
sourceType: options.manifestNames.includes(name) ? "canonical" : "user"
|
|
3807
|
+
});
|
|
3808
|
+
}
|
|
3809
|
+
return {
|
|
3810
|
+
action: "dry-run",
|
|
3811
|
+
migrated,
|
|
3812
|
+
skipped,
|
|
3813
|
+
backupPath: null,
|
|
3814
|
+
legacyRoot: options.legacyRoot,
|
|
3815
|
+
canonicalRoot: options.canonicalRoot,
|
|
3816
|
+
durationMs: Date.now() - start
|
|
3817
|
+
};
|
|
3818
|
+
}
|
|
3819
|
+
function formatBackupTimestamp(now) {
|
|
3820
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
3821
|
+
return `${now.getUTCFullYear()}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}-${pad(now.getUTCHours())}${pad(now.getUTCMinutes())}${pad(now.getUTCSeconds())}`;
|
|
3822
|
+
}
|
|
3823
|
+
function listBackups(backupDir) {
|
|
3824
|
+
if (!existsSync10(backupDir)) return [];
|
|
3825
|
+
const files = readdirSync2(backupDir).filter(
|
|
3826
|
+
(f) => f.startsWith("skills-pre-migrate-") && f.endsWith(".tgz")
|
|
3827
|
+
);
|
|
3828
|
+
files.sort().reverse();
|
|
3829
|
+
return files.map((f) => join8(backupDir, f));
|
|
3830
|
+
}
|
|
3831
|
+
async function runMigration(options) {
|
|
3832
|
+
const start = Date.now();
|
|
3833
|
+
const now = (options.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
3834
|
+
const tar = options.tarExec ?? systemTarExec;
|
|
3835
|
+
const sink = options.recordRow ?? (() => void 0);
|
|
3836
|
+
if (isAlreadyMigrated(options.legacyRoot)) {
|
|
3837
|
+
return {
|
|
3838
|
+
action: "no-op",
|
|
3839
|
+
migrated: [],
|
|
3840
|
+
skipped: [],
|
|
3841
|
+
backupPath: null,
|
|
3842
|
+
legacyRoot: options.legacyRoot,
|
|
3843
|
+
canonicalRoot: options.canonicalRoot,
|
|
3844
|
+
durationMs: Date.now() - start
|
|
3845
|
+
};
|
|
3846
|
+
}
|
|
3847
|
+
const plan = planMigration(options);
|
|
3848
|
+
mkdirSync(options.canonicalRoot, { recursive: true });
|
|
3849
|
+
mkdirSync(options.backupDir, { recursive: true });
|
|
3850
|
+
const backupName = `skills-pre-migrate-${formatBackupTimestamp(now)}.tgz`;
|
|
3851
|
+
const backupPath = join8(options.backupDir, backupName);
|
|
3852
|
+
await tar.create({ archivePath: backupPath, sourceRoot: options.legacyRoot });
|
|
3853
|
+
for (const entry of plan.migrated) {
|
|
3854
|
+
cpSync(entry.legacyPath, entry.installPath, { recursive: true, dereference: false });
|
|
3855
|
+
await sink(entry);
|
|
3856
|
+
}
|
|
3857
|
+
writeFileSync(
|
|
3858
|
+
join8(options.legacyRoot, LEGACY_MIGRATED_MARKER),
|
|
3859
|
+
JSON.stringify(
|
|
3860
|
+
{
|
|
3861
|
+
migratedAt: now.toISOString(),
|
|
3862
|
+
backupPath,
|
|
3863
|
+
canonicalRoot: options.canonicalRoot,
|
|
3864
|
+
entries: plan.migrated.length
|
|
3865
|
+
},
|
|
3866
|
+
null,
|
|
3867
|
+
2
|
|
3868
|
+
),
|
|
3869
|
+
"utf-8"
|
|
3870
|
+
);
|
|
3871
|
+
return {
|
|
3872
|
+
action: "migrate",
|
|
3873
|
+
migrated: plan.migrated,
|
|
3874
|
+
skipped: plan.skipped,
|
|
3875
|
+
backupPath,
|
|
3876
|
+
legacyRoot: options.legacyRoot,
|
|
3877
|
+
canonicalRoot: options.canonicalRoot,
|
|
3878
|
+
durationMs: Date.now() - start
|
|
3879
|
+
};
|
|
3880
|
+
}
|
|
3881
|
+
async function runRollback(options) {
|
|
3882
|
+
const start = Date.now();
|
|
3883
|
+
const tar = options.tarExec ?? systemTarExec;
|
|
3884
|
+
const backups = listBackups(options.backupDir);
|
|
3885
|
+
const newest = backups[0];
|
|
3886
|
+
if (!newest) {
|
|
3887
|
+
throw new Error(
|
|
3888
|
+
`No backup tarballs found under ${options.backupDir}. Run "cleo skills migrate" (without --rollback) first.`
|
|
3889
|
+
);
|
|
3890
|
+
}
|
|
3891
|
+
if (existsSync10(options.legacyRoot)) {
|
|
3892
|
+
rmSync(options.legacyRoot, { recursive: true, force: true });
|
|
3893
|
+
}
|
|
3894
|
+
await tar.extract({ archivePath: newest, destinationRoot: options.legacyRoot });
|
|
3895
|
+
return {
|
|
3896
|
+
action: "rollback",
|
|
3897
|
+
migrated: [],
|
|
3898
|
+
skipped: [],
|
|
3899
|
+
backupPath: newest,
|
|
3900
|
+
legacyRoot: options.legacyRoot,
|
|
3901
|
+
canonicalRoot: options.canonicalRoot,
|
|
3902
|
+
durationMs: Date.now() - start
|
|
3903
|
+
};
|
|
3904
|
+
}
|
|
3905
|
+
|
|
3906
|
+
// src/commands/skills/doctor-migrate.ts
|
|
3907
|
+
function buildOptions(opts) {
|
|
3908
|
+
if (opts.__optionsOverride) return opts.__optionsOverride;
|
|
3909
|
+
const manifestNames = opts.__manifestNamesOverride ?? [];
|
|
3910
|
+
return defaultMigrationOptions(manifestNames);
|
|
3911
|
+
}
|
|
3912
|
+
function renderHuman(outcome) {
|
|
3913
|
+
const lines = [];
|
|
3914
|
+
lines.push(pc9.bold(`
|
|
3915
|
+
skills ${outcome.action}`));
|
|
3916
|
+
lines.push(pc9.dim(` legacy: ${outcome.legacyRoot}`));
|
|
3917
|
+
lines.push(pc9.dim(` canonical: ${outcome.canonicalRoot}`));
|
|
3918
|
+
if (outcome.backupPath) {
|
|
3919
|
+
lines.push(pc9.dim(` backup: ${outcome.backupPath}`));
|
|
3920
|
+
}
|
|
3921
|
+
lines.push(pc9.dim(` duration: ${outcome.durationMs}ms`));
|
|
3922
|
+
if (outcome.migrated.length > 0) {
|
|
3923
|
+
lines.push(pc9.green(`
|
|
3924
|
+
Migrated (${outcome.migrated.length}):`));
|
|
3925
|
+
for (const m of outcome.migrated) {
|
|
3926
|
+
lines.push(` + ${pc9.bold(m.name)} ${pc9.dim(`[${m.sourceType}]`)}`);
|
|
3927
|
+
}
|
|
3928
|
+
}
|
|
3929
|
+
if (outcome.skipped.length > 0) {
|
|
3930
|
+
lines.push(pc9.yellow(`
|
|
3931
|
+
Skipped (${outcome.skipped.length}):`));
|
|
3932
|
+
for (const s of outcome.skipped) {
|
|
3933
|
+
lines.push(` ! ${pc9.bold(s.name)} ${pc9.dim(`(${s.reason})`)}`);
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
if (outcome.action === "no-op") {
|
|
3937
|
+
lines.push(pc9.dim("\nLegacy store is already migrated (sentinel present)."));
|
|
3938
|
+
}
|
|
3939
|
+
if (outcome.action === "dry-run") {
|
|
3940
|
+
lines.push(pc9.dim("\n(dry run \u2014 no filesystem changes were made)"));
|
|
3941
|
+
}
|
|
3942
|
+
return lines.join("\n");
|
|
3943
|
+
}
|
|
3944
|
+
function registerSkillsDoctorMigrate(parent) {
|
|
3945
|
+
parent.command("migrate").description("Migrate legacy skills (~/.local/share/agents/skills) into ~/.cleo/skills").option("--dry-run", "Preview the plan without writing anything", false).option("--rollback", "Restore from the most recent backup tarball", false).option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
|
|
3946
|
+
const operation = "skills.migrate";
|
|
3947
|
+
const mvi = "standard";
|
|
3948
|
+
let format;
|
|
3949
|
+
try {
|
|
3950
|
+
format = resolveFormat({
|
|
3951
|
+
jsonFlag: opts.json ?? false,
|
|
3952
|
+
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3953
|
+
projectDefault: "json"
|
|
3954
|
+
});
|
|
3955
|
+
} catch (error) {
|
|
3956
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3957
|
+
emitJsonError(
|
|
3958
|
+
operation,
|
|
3959
|
+
mvi,
|
|
3960
|
+
ErrorCodes.FORMAT_CONFLICT,
|
|
3961
|
+
message,
|
|
3962
|
+
ErrorCategories.VALIDATION
|
|
3963
|
+
);
|
|
3964
|
+
process.exit(1);
|
|
3965
|
+
}
|
|
3966
|
+
if (opts.dryRun && opts.rollback) {
|
|
3967
|
+
const message = "Cannot combine --dry-run with --rollback";
|
|
3968
|
+
if (format === "json") {
|
|
3969
|
+
emitJsonError(
|
|
3970
|
+
operation,
|
|
3971
|
+
mvi,
|
|
3972
|
+
ErrorCodes.INVALID_INPUT,
|
|
3973
|
+
message,
|
|
3974
|
+
ErrorCategories.VALIDATION
|
|
3975
|
+
);
|
|
3976
|
+
} else {
|
|
3977
|
+
console.error(pc9.red(message));
|
|
3978
|
+
}
|
|
3979
|
+
process.exit(1);
|
|
3980
|
+
}
|
|
3981
|
+
const options = buildOptions(opts);
|
|
3982
|
+
try {
|
|
3983
|
+
let outcome;
|
|
3984
|
+
if (opts.rollback) {
|
|
3985
|
+
outcome = await runRollback(options);
|
|
3986
|
+
} else if (opts.dryRun) {
|
|
3987
|
+
outcome = planMigration(options);
|
|
3988
|
+
} else {
|
|
3989
|
+
outcome = await runMigration(options);
|
|
3990
|
+
}
|
|
3991
|
+
if (format === "json") {
|
|
3992
|
+
outputSuccess(operation, mvi, outcome);
|
|
3993
|
+
} else {
|
|
3994
|
+
console.log(renderHuman(outcome));
|
|
3995
|
+
}
|
|
3996
|
+
} catch (error) {
|
|
3997
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3998
|
+
if (format === "json") {
|
|
3999
|
+
emitJsonError(
|
|
4000
|
+
operation,
|
|
4001
|
+
mvi,
|
|
4002
|
+
ErrorCodes.INTERNAL_ERROR,
|
|
4003
|
+
message,
|
|
4004
|
+
ErrorCategories.MIGRATION,
|
|
4005
|
+
{ legacyRoot: options.legacyRoot, canonicalRoot: options.canonicalRoot }
|
|
4006
|
+
);
|
|
4007
|
+
} else {
|
|
4008
|
+
console.error(pc9.red(`migration failed: ${message}`));
|
|
4009
|
+
}
|
|
4010
|
+
process.exit(1);
|
|
4011
|
+
}
|
|
4012
|
+
});
|
|
4013
|
+
}
|
|
4014
|
+
|
|
4015
|
+
// src/commands/skills/find.ts
|
|
4016
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
4017
|
+
import { resolveOutputFormat as resolveOutputFormat2 } from "@cleocode/lafs";
|
|
4018
|
+
import pc10 from "picocolors";
|
|
3824
4019
|
var SkillsFindValidationError = class extends Error {
|
|
3825
4020
|
code;
|
|
3826
4021
|
constructor(code, message) {
|
|
@@ -3851,7 +4046,7 @@ function registerSkillsFind(parent) {
|
|
|
3851
4046
|
const mvi = details ? "full" : "standard";
|
|
3852
4047
|
let format;
|
|
3853
4048
|
try {
|
|
3854
|
-
format =
|
|
4049
|
+
format = resolveOutputFormat2({
|
|
3855
4050
|
jsonFlag: opts.json ?? false,
|
|
3856
4051
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3857
4052
|
projectDefault: "json"
|
|
@@ -3861,7 +4056,7 @@ function registerSkillsFind(parent) {
|
|
|
3861
4056
|
if (opts.json) {
|
|
3862
4057
|
emitJsonError3(operation, mvi, "E_FORMAT_CONFLICT", message, "VALIDATION");
|
|
3863
4058
|
} else {
|
|
3864
|
-
console.error(
|
|
4059
|
+
console.error(pc10.red(message));
|
|
3865
4060
|
}
|
|
3866
4061
|
process.exit(1);
|
|
3867
4062
|
}
|
|
@@ -3928,19 +4123,19 @@ function registerSkillsFind(parent) {
|
|
|
3928
4123
|
query: query ?? null
|
|
3929
4124
|
});
|
|
3930
4125
|
} else {
|
|
3931
|
-
console.error(
|
|
4126
|
+
console.error(pc10.red(`Recommendation failed: ${message}`));
|
|
3932
4127
|
}
|
|
3933
4128
|
process.exit(1);
|
|
3934
4129
|
}
|
|
3935
4130
|
}
|
|
3936
4131
|
if (!query) {
|
|
3937
|
-
console.log(
|
|
4132
|
+
console.log(pc10.dim("Usage: caamp skills find <query>"));
|
|
3938
4133
|
return;
|
|
3939
4134
|
}
|
|
3940
4135
|
const limit = parseInt(opts.limit, 10);
|
|
3941
4136
|
const client = new MarketplaceClient();
|
|
3942
4137
|
if (format === "human") {
|
|
3943
|
-
console.log(
|
|
4138
|
+
console.log(pc10.dim(`Searching marketplaces for "${query}"...
|
|
3944
4139
|
`));
|
|
3945
4140
|
}
|
|
3946
4141
|
let results;
|
|
@@ -3954,7 +4149,7 @@ function registerSkillsFind(parent) {
|
|
|
3954
4149
|
limit
|
|
3955
4150
|
});
|
|
3956
4151
|
} else {
|
|
3957
|
-
console.error(
|
|
4152
|
+
console.error(pc10.red(`Marketplace search failed: ${message}`));
|
|
3958
4153
|
}
|
|
3959
4154
|
process.exit(1);
|
|
3960
4155
|
}
|
|
@@ -3974,21 +4169,21 @@ function registerSkillsFind(parent) {
|
|
|
3974
4169
|
return;
|
|
3975
4170
|
}
|
|
3976
4171
|
if (results.length === 0) {
|
|
3977
|
-
console.log(
|
|
4172
|
+
console.log(pc10.yellow("No results found."));
|
|
3978
4173
|
return;
|
|
3979
4174
|
}
|
|
3980
|
-
console.log(
|
|
4175
|
+
console.log(pc10.dim(`Found ${results.length} result(s) for "${query}":
|
|
3981
4176
|
`));
|
|
3982
4177
|
results.forEach((skill, index) => {
|
|
3983
4178
|
const num = (index + 1).toString().padStart(2);
|
|
3984
|
-
const stars = skill.stars > 0 ?
|
|
3985
|
-
console.log(` ${
|
|
3986
|
-
console.log(` ${
|
|
3987
|
-
console.log(` ${
|
|
4179
|
+
const stars = skill.stars > 0 ? pc10.yellow(`\u2605 ${formatStars(skill.stars)}`) : "";
|
|
4180
|
+
console.log(` ${pc10.cyan(num)}. ${pc10.bold(skill.scopedName)} ${stars}`);
|
|
4181
|
+
console.log(` ${pc10.dim(skill.description?.slice(0, 80) ?? "")}`);
|
|
4182
|
+
console.log(` ${pc10.dim(`from ${skill.source}`)}`);
|
|
3988
4183
|
console.log();
|
|
3989
4184
|
});
|
|
3990
|
-
console.log(
|
|
3991
|
-
console.log(
|
|
4185
|
+
console.log(pc10.dim("Install with: caamp skills install <name>"));
|
|
4186
|
+
console.log(pc10.dim("Or select by number: caamp skills install <n>"));
|
|
3992
4187
|
});
|
|
3993
4188
|
}
|
|
3994
4189
|
function formatStars(n) {
|
|
@@ -4080,7 +4275,7 @@ function buildEnvelope3(operation, mvi, result, error) {
|
|
|
4080
4275
|
schemaVersion: "1.0.0",
|
|
4081
4276
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4082
4277
|
operation,
|
|
4083
|
-
requestId:
|
|
4278
|
+
requestId: randomUUID3(),
|
|
4084
4279
|
transport: "cli",
|
|
4085
4280
|
strict: true,
|
|
4086
4281
|
mvi,
|
|
@@ -4105,10 +4300,10 @@ function emitJsonError3(operation, mvi, code, message, category, details = {}) {
|
|
|
4105
4300
|
}
|
|
4106
4301
|
|
|
4107
4302
|
// src/commands/skills/init.ts
|
|
4108
|
-
import { existsSync as
|
|
4303
|
+
import { existsSync as existsSync11 } from "fs";
|
|
4109
4304
|
import { mkdir, writeFile as writeFile3 } from "fs/promises";
|
|
4110
|
-
import { join as
|
|
4111
|
-
import
|
|
4305
|
+
import { join as join9 } from "path";
|
|
4306
|
+
import pc11 from "picocolors";
|
|
4112
4307
|
function registerSkillsInit(parent) {
|
|
4113
4308
|
parent.command("init").description("Create a new SKILL.md template").argument("[name]", "Skill name").option("-d, --dir <path>", "Output directory", ".").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(
|
|
4114
4309
|
async (name, opts) => {
|
|
@@ -4133,8 +4328,8 @@ function registerSkillsInit(parent) {
|
|
|
4133
4328
|
process.exit(1);
|
|
4134
4329
|
}
|
|
4135
4330
|
const skillName = name ?? "my-skill";
|
|
4136
|
-
const skillDir =
|
|
4137
|
-
if (
|
|
4331
|
+
const skillDir = join9(opts.dir, skillName);
|
|
4332
|
+
if (existsSync11(skillDir)) {
|
|
4138
4333
|
const message = `Directory already exists: ${skillDir}`;
|
|
4139
4334
|
if (format === "json") {
|
|
4140
4335
|
emitJsonError(
|
|
@@ -4148,7 +4343,7 @@ function registerSkillsInit(parent) {
|
|
|
4148
4343
|
}
|
|
4149
4344
|
);
|
|
4150
4345
|
} else {
|
|
4151
|
-
console.error(
|
|
4346
|
+
console.error(pc11.red(message));
|
|
4152
4347
|
}
|
|
4153
4348
|
process.exit(1);
|
|
4154
4349
|
}
|
|
@@ -4176,7 +4371,7 @@ Provide detailed instructions for the AI agent here.
|
|
|
4176
4371
|
|
|
4177
4372
|
Show example inputs and expected outputs.
|
|
4178
4373
|
`;
|
|
4179
|
-
await writeFile3(
|
|
4374
|
+
await writeFile3(join9(skillDir, "SKILL.md"), template, "utf-8");
|
|
4180
4375
|
const result = {
|
|
4181
4376
|
name: skillName,
|
|
4182
4377
|
directory: skillDir,
|
|
@@ -4187,18 +4382,18 @@ Show example inputs and expected outputs.
|
|
|
4187
4382
|
outputSuccess(operation, mvi, result);
|
|
4188
4383
|
return;
|
|
4189
4384
|
}
|
|
4190
|
-
console.log(
|
|
4191
|
-
console.log(
|
|
4192
|
-
console.log(
|
|
4193
|
-
console.log(
|
|
4194
|
-
console.log(
|
|
4385
|
+
console.log(pc11.green(`\u2713 Created skill template: ${skillDir}/SKILL.md`));
|
|
4386
|
+
console.log(pc11.dim("\nNext steps:"));
|
|
4387
|
+
console.log(pc11.dim(" 1. Edit SKILL.md with your instructions"));
|
|
4388
|
+
console.log(pc11.dim(` 2. Validate: caamp skills validate ${join9(skillDir, "SKILL.md")}`));
|
|
4389
|
+
console.log(pc11.dim(` 3. Install: caamp skills install ${skillDir}`));
|
|
4195
4390
|
}
|
|
4196
4391
|
);
|
|
4197
4392
|
}
|
|
4198
4393
|
|
|
4199
4394
|
// src/commands/skills/install.ts
|
|
4200
|
-
import { existsSync as
|
|
4201
|
-
import
|
|
4395
|
+
import { existsSync as existsSync12 } from "fs";
|
|
4396
|
+
import pc12 from "picocolors";
|
|
4202
4397
|
function registerSkillsInstall(parent) {
|
|
4203
4398
|
parent.command("install").description("Install a skill from GitHub, URL, marketplace, or registered skill library").argument("[source]", "Skill source (GitHub URL, owner/repo, @author/name, skill-name)").option(
|
|
4204
4399
|
"-a, --agent <name>",
|
|
@@ -4241,7 +4436,7 @@ function registerSkillsInstall(parent) {
|
|
|
4241
4436
|
if (providers.length === 0) {
|
|
4242
4437
|
const message = "No target providers found. Use --agent or --all.";
|
|
4243
4438
|
if (format === "json") {
|
|
4244
|
-
|
|
4439
|
+
emitError(
|
|
4245
4440
|
operation,
|
|
4246
4441
|
mvi,
|
|
4247
4442
|
ErrorCodes.PROVIDER_NOT_FOUND,
|
|
@@ -4249,7 +4444,7 @@ function registerSkillsInstall(parent) {
|
|
|
4249
4444
|
ErrorCategories.NOT_FOUND
|
|
4250
4445
|
);
|
|
4251
4446
|
}
|
|
4252
|
-
console.error(
|
|
4447
|
+
console.error(pc12.red(message));
|
|
4253
4448
|
process.exit(1);
|
|
4254
4449
|
}
|
|
4255
4450
|
if (opts.profile) {
|
|
@@ -4266,7 +4461,7 @@ function registerSkillsInstall(parent) {
|
|
|
4266
4461
|
if (!source) {
|
|
4267
4462
|
const message = "Missing required argument: source";
|
|
4268
4463
|
if (format === "json") {
|
|
4269
|
-
|
|
4464
|
+
emitError(
|
|
4270
4465
|
operation,
|
|
4271
4466
|
mvi,
|
|
4272
4467
|
ErrorCodes.INVALID_INPUT,
|
|
@@ -4274,14 +4469,14 @@ function registerSkillsInstall(parent) {
|
|
|
4274
4469
|
ErrorCategories.VALIDATION
|
|
4275
4470
|
);
|
|
4276
4471
|
}
|
|
4277
|
-
console.error(
|
|
4472
|
+
console.error(pc12.red(message));
|
|
4278
4473
|
console.log(
|
|
4279
|
-
|
|
4474
|
+
pc12.dim("Usage: caamp skills install <source> or caamp skills install --profile <name>")
|
|
4280
4475
|
);
|
|
4281
4476
|
process.exit(1);
|
|
4282
4477
|
}
|
|
4283
4478
|
if (format === "human") {
|
|
4284
|
-
console.log(
|
|
4479
|
+
console.log(pc12.dim(`Installing to ${providers.length} provider(s)...`));
|
|
4285
4480
|
}
|
|
4286
4481
|
let localPath;
|
|
4287
4482
|
let cleanup;
|
|
@@ -4327,7 +4522,7 @@ function registerSkillsInstall(parent) {
|
|
|
4327
4522
|
ErrorCategories.TRANSIENT
|
|
4328
4523
|
);
|
|
4329
4524
|
}
|
|
4330
|
-
console.error(
|
|
4525
|
+
console.error(pc12.red(message));
|
|
4331
4526
|
process.exit(1);
|
|
4332
4527
|
}
|
|
4333
4528
|
} else if (parsed.type === "gitlab" && parsed.owner && parsed.repo) {
|
|
@@ -4351,7 +4546,7 @@ function registerSkillsInstall(parent) {
|
|
|
4351
4546
|
ErrorCategories.TRANSIENT
|
|
4352
4547
|
);
|
|
4353
4548
|
}
|
|
4354
|
-
console.error(
|
|
4549
|
+
console.error(pc12.red(message));
|
|
4355
4550
|
process.exit(1);
|
|
4356
4551
|
}
|
|
4357
4552
|
} else if (parsed.type === "local") {
|
|
@@ -4372,7 +4567,7 @@ function registerSkillsInstall(parent) {
|
|
|
4372
4567
|
ErrorCategories.VALIDATION
|
|
4373
4568
|
);
|
|
4374
4569
|
}
|
|
4375
|
-
console.error(
|
|
4570
|
+
console.error(pc12.red(message));
|
|
4376
4571
|
process.exit(1);
|
|
4377
4572
|
}
|
|
4378
4573
|
const catalogSkill = getSkill(parsed.inferredName);
|
|
@@ -4383,7 +4578,7 @@ function registerSkillsInstall(parent) {
|
|
|
4383
4578
|
sourceType = "library";
|
|
4384
4579
|
if (format === "human") {
|
|
4385
4580
|
console.log(
|
|
4386
|
-
` Found in catalog: ${
|
|
4581
|
+
` Found in catalog: ${pc12.bold(catalogSkill.name)} v${catalogSkill.version} (${pc12.dim(catalogSkill.category)})`
|
|
4387
4582
|
);
|
|
4388
4583
|
}
|
|
4389
4584
|
} else {
|
|
@@ -4400,8 +4595,8 @@ function registerSkillsInstall(parent) {
|
|
|
4400
4595
|
}
|
|
4401
4596
|
);
|
|
4402
4597
|
}
|
|
4403
|
-
console.error(
|
|
4404
|
-
console.log(
|
|
4598
|
+
console.error(pc12.red(message));
|
|
4599
|
+
console.log(pc12.dim("Available skills: " + listSkills().join(", ")));
|
|
4405
4600
|
process.exit(1);
|
|
4406
4601
|
}
|
|
4407
4602
|
} else {
|
|
@@ -4415,7 +4610,7 @@ function registerSkillsInstall(parent) {
|
|
|
4415
4610
|
ErrorCategories.VALIDATION
|
|
4416
4611
|
);
|
|
4417
4612
|
}
|
|
4418
|
-
console.error(
|
|
4613
|
+
console.error(pc12.red(message));
|
|
4419
4614
|
process.exit(1);
|
|
4420
4615
|
}
|
|
4421
4616
|
}
|
|
@@ -4431,7 +4626,7 @@ function registerSkillsInstall(parent) {
|
|
|
4431
4626
|
ErrorCategories.INTERNAL
|
|
4432
4627
|
);
|
|
4433
4628
|
}
|
|
4434
|
-
console.error(
|
|
4629
|
+
console.error(pc12.red(message));
|
|
4435
4630
|
process.exit(1);
|
|
4436
4631
|
}
|
|
4437
4632
|
const result = await dispatchInstallSkillAcrossProviders(
|
|
@@ -4469,14 +4664,14 @@ function registerSkillsInstall(parent) {
|
|
|
4469
4664
|
if (format === "json") {
|
|
4470
4665
|
outputSuccess(operation, mvi, summary);
|
|
4471
4666
|
} else {
|
|
4472
|
-
console.log(
|
|
4473
|
-
\u2713 Installed ${
|
|
4474
|
-
console.log(` Canonical: ${
|
|
4667
|
+
console.log(pc12.green(`
|
|
4668
|
+
\u2713 Installed ${pc12.bold(skillName)}`));
|
|
4669
|
+
console.log(` Canonical: ${pc12.dim(result.canonicalPath)}`);
|
|
4475
4670
|
console.log(` Linked to: ${result.linkedAgents.join(", ")}`);
|
|
4476
4671
|
if (result.errors.length > 0) {
|
|
4477
|
-
console.log(
|
|
4672
|
+
console.log(pc12.yellow("\nWarnings:"));
|
|
4478
4673
|
for (const err of result.errors) {
|
|
4479
|
-
console.log(` ${
|
|
4674
|
+
console.log(` ${pc12.yellow("!")} ${err}`);
|
|
4480
4675
|
}
|
|
4481
4676
|
}
|
|
4482
4677
|
}
|
|
@@ -4506,11 +4701,11 @@ function registerSkillsInstall(parent) {
|
|
|
4506
4701
|
});
|
|
4507
4702
|
console.error(JSON.stringify(envelope, null, 2));
|
|
4508
4703
|
} else {
|
|
4509
|
-
console.log(
|
|
4510
|
-
\u2717 Failed to install ${
|
|
4511
|
-
console.log(
|
|
4704
|
+
console.log(pc12.yellow(`
|
|
4705
|
+
\u2717 Failed to install ${pc12.bold(skillName)}`));
|
|
4706
|
+
console.log(pc12.yellow("Errors:"));
|
|
4512
4707
|
for (const err of result.errors) {
|
|
4513
|
-
console.log(` ${
|
|
4708
|
+
console.log(` ${pc12.yellow("!")} ${err}`);
|
|
4514
4709
|
}
|
|
4515
4710
|
}
|
|
4516
4711
|
process.exit(1);
|
|
@@ -4525,9 +4720,9 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4525
4720
|
if (!isCatalogAvailable()) {
|
|
4526
4721
|
const message = "No skill library registered. Register one with registerSkillLibraryFromPath() or set CAAMP_SKILL_LIBRARY env var.";
|
|
4527
4722
|
if (format === "json") {
|
|
4528
|
-
|
|
4723
|
+
emitError(operation, mvi, ErrorCodes.INVALID_INPUT, message, ErrorCategories.VALIDATION);
|
|
4529
4724
|
}
|
|
4530
|
-
console.error(
|
|
4725
|
+
console.error(pc12.red(message));
|
|
4531
4726
|
process.exit(1);
|
|
4532
4727
|
}
|
|
4533
4728
|
const profileSkills = resolveProfile(profileName);
|
|
@@ -4545,16 +4740,16 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4545
4740
|
}
|
|
4546
4741
|
);
|
|
4547
4742
|
}
|
|
4548
|
-
console.error(
|
|
4743
|
+
console.error(pc12.red(message));
|
|
4549
4744
|
const available = listProfiles();
|
|
4550
4745
|
if (available.length > 0) {
|
|
4551
|
-
console.log(
|
|
4746
|
+
console.log(pc12.dim("Available profiles: " + available.join(", ")));
|
|
4552
4747
|
}
|
|
4553
4748
|
process.exit(1);
|
|
4554
4749
|
}
|
|
4555
4750
|
if (format === "human") {
|
|
4556
|
-
console.log(`Installing profile ${
|
|
4557
|
-
console.log(
|
|
4751
|
+
console.log(`Installing profile ${pc12.bold(profileName)} (${profileSkills.length} skill(s))...`);
|
|
4752
|
+
console.log(pc12.dim(`Target: ${providers.length} provider(s)`));
|
|
4558
4753
|
}
|
|
4559
4754
|
const installed = [];
|
|
4560
4755
|
const failed = [];
|
|
@@ -4564,7 +4759,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4564
4759
|
const result = await dispatchInstallSkillAcrossProviders(skillDir, name, providers, isGlobal);
|
|
4565
4760
|
if (result.success) {
|
|
4566
4761
|
if (format === "human") {
|
|
4567
|
-
console.log(
|
|
4762
|
+
console.log(pc12.green(` + ${name}`));
|
|
4568
4763
|
}
|
|
4569
4764
|
await recordSkillInstall(
|
|
4570
4765
|
name,
|
|
@@ -4583,7 +4778,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4583
4778
|
});
|
|
4584
4779
|
} else {
|
|
4585
4780
|
if (format === "human") {
|
|
4586
|
-
console.log(
|
|
4781
|
+
console.log(pc12.yellow(` ! ${name}: ${result.errors.join(", ")}`));
|
|
4587
4782
|
}
|
|
4588
4783
|
failed.push({
|
|
4589
4784
|
name,
|
|
@@ -4593,7 +4788,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4593
4788
|
} catch (err) {
|
|
4594
4789
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
4595
4790
|
if (format === "human") {
|
|
4596
|
-
console.log(
|
|
4791
|
+
console.log(pc12.red(` x ${name}: ${errorMsg}`));
|
|
4597
4792
|
}
|
|
4598
4793
|
failed.push({
|
|
4599
4794
|
name,
|
|
@@ -4628,7 +4823,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4628
4823
|
} else {
|
|
4629
4824
|
console.log(
|
|
4630
4825
|
`
|
|
4631
|
-
${
|
|
4826
|
+
${pc12.green(`${installed.length} installed`)}, ${failed.length > 0 ? pc12.yellow(`${failed.length} failed`) : "0 failed"}`
|
|
4632
4827
|
);
|
|
4633
4828
|
if (failed.length > 0) {
|
|
4634
4829
|
process.exit(1);
|
|
@@ -4637,7 +4832,7 @@ ${pc11.green(`${installed.length} installed`)}, ${failed.length > 0 ? pc11.yello
|
|
|
4637
4832
|
}
|
|
4638
4833
|
async function handleMarketplaceSource(source, _providers, _isGlobal, format, operation, mvi) {
|
|
4639
4834
|
if (format === "human") {
|
|
4640
|
-
console.log(
|
|
4835
|
+
console.log(pc12.dim(`Searching marketplace for ${source}...`));
|
|
4641
4836
|
}
|
|
4642
4837
|
const client = new MarketplaceClient();
|
|
4643
4838
|
let skill;
|
|
@@ -4648,7 +4843,7 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
4648
4843
|
if (format === "json") {
|
|
4649
4844
|
emitJsonError(operation, mvi, ErrorCodes.NETWORK_ERROR, message, ErrorCategories.TRANSIENT);
|
|
4650
4845
|
}
|
|
4651
|
-
console.error(
|
|
4846
|
+
console.error(pc12.red(message));
|
|
4652
4847
|
return { success: false };
|
|
4653
4848
|
}
|
|
4654
4849
|
if (!skill) {
|
|
@@ -4656,12 +4851,12 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
4656
4851
|
if (format === "json") {
|
|
4657
4852
|
emitJsonError(operation, mvi, ErrorCodes.SKILL_NOT_FOUND, message, ErrorCategories.NOT_FOUND);
|
|
4658
4853
|
}
|
|
4659
|
-
console.error(
|
|
4854
|
+
console.error(pc12.red(message));
|
|
4660
4855
|
return { success: false };
|
|
4661
4856
|
}
|
|
4662
4857
|
if (format === "human") {
|
|
4663
4858
|
console.log(
|
|
4664
|
-
` Found: ${
|
|
4859
|
+
` Found: ${pc12.bold(skill.name)} by ${skill.author} (${pc12.dim(skill.repoFullName)})`
|
|
4665
4860
|
);
|
|
4666
4861
|
}
|
|
4667
4862
|
const parsed = parseSource(skill.githubUrl);
|
|
@@ -4670,7 +4865,7 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
4670
4865
|
if (format === "json") {
|
|
4671
4866
|
emitJsonError(operation, mvi, ErrorCodes.INVALID_FORMAT, message, ErrorCategories.VALIDATION);
|
|
4672
4867
|
}
|
|
4673
|
-
console.error(
|
|
4868
|
+
console.error(pc12.red(message));
|
|
4674
4869
|
return { success: false };
|
|
4675
4870
|
}
|
|
4676
4871
|
try {
|
|
@@ -4682,7 +4877,7 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
4682
4877
|
for (const subPath of subPathCandidates) {
|
|
4683
4878
|
try {
|
|
4684
4879
|
const result = await cloneRepo(parsed.owner, parsed.repo, parsed.ref, subPath);
|
|
4685
|
-
if (subPath && !
|
|
4880
|
+
if (subPath && !existsSync12(result.localPath)) {
|
|
4686
4881
|
await result.cleanup();
|
|
4687
4882
|
continue;
|
|
4688
4883
|
}
|
|
@@ -4710,22 +4905,22 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
4710
4905
|
if (format === "json") {
|
|
4711
4906
|
emitJsonError(operation, mvi, ErrorCodes.NETWORK_ERROR, message, ErrorCategories.TRANSIENT);
|
|
4712
4907
|
}
|
|
4713
|
-
console.error(
|
|
4908
|
+
console.error(pc12.red(message));
|
|
4714
4909
|
return { success: false };
|
|
4715
4910
|
}
|
|
4716
4911
|
}
|
|
4717
4912
|
|
|
4718
4913
|
// src/commands/skills/list.ts
|
|
4719
|
-
import { randomUUID as
|
|
4720
|
-
import { resolveOutputFormat as
|
|
4721
|
-
import
|
|
4914
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
4915
|
+
import { resolveOutputFormat as resolveOutputFormat3 } from "@cleocode/lafs";
|
|
4916
|
+
import pc13 from "picocolors";
|
|
4722
4917
|
function registerSkillsList(parent) {
|
|
4723
4918
|
parent.command("list").description("List installed skills").option("-g, --global", "List global skills").option("-a, --agent <name>", "List skills for specific agent").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
|
|
4724
4919
|
const operation = "skills.list";
|
|
4725
4920
|
const mvi = "standard";
|
|
4726
4921
|
let format;
|
|
4727
4922
|
try {
|
|
4728
|
-
format =
|
|
4923
|
+
format = resolveOutputFormat3({
|
|
4729
4924
|
jsonFlag: opts.json ?? false,
|
|
4730
4925
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
4731
4926
|
projectDefault: "json"
|
|
@@ -4745,7 +4940,7 @@ function registerSkillsList(parent) {
|
|
|
4745
4940
|
agent: opts.agent
|
|
4746
4941
|
});
|
|
4747
4942
|
} else {
|
|
4748
|
-
console.error(
|
|
4943
|
+
console.error(pc13.red(message));
|
|
4749
4944
|
}
|
|
4750
4945
|
process.exit(1);
|
|
4751
4946
|
}
|
|
@@ -4773,21 +4968,21 @@ function registerSkillsList(parent) {
|
|
|
4773
4968
|
return;
|
|
4774
4969
|
}
|
|
4775
4970
|
if (skills.length === 0) {
|
|
4776
|
-
console.log(
|
|
4971
|
+
console.log(pc13.dim("No skills found."));
|
|
4777
4972
|
return;
|
|
4778
4973
|
}
|
|
4779
|
-
console.log(
|
|
4974
|
+
console.log(pc13.bold(`
|
|
4780
4975
|
${skills.length} skill(s) found:
|
|
4781
4976
|
`));
|
|
4782
4977
|
skills.forEach((skill, index) => {
|
|
4783
4978
|
const num = (index + 1).toString().padStart(2);
|
|
4784
4979
|
console.log(
|
|
4785
|
-
` ${
|
|
4980
|
+
` ${pc13.cyan(num)}. ${pc13.bold(skill.name.padEnd(30))} ${pc13.dim(skill.metadata?.description ?? "")}`
|
|
4786
4981
|
);
|
|
4787
4982
|
});
|
|
4788
|
-
console.log(
|
|
4983
|
+
console.log(pc13.dim(`
|
|
4789
4984
|
Install with: caamp skills install <name>`));
|
|
4790
|
-
console.log(
|
|
4985
|
+
console.log(pc13.dim(`Remove with: caamp skills remove <name>`));
|
|
4791
4986
|
});
|
|
4792
4987
|
}
|
|
4793
4988
|
function buildEnvelope4(operation, mvi, result, error) {
|
|
@@ -4798,7 +4993,7 @@ function buildEnvelope4(operation, mvi, result, error) {
|
|
|
4798
4993
|
schemaVersion: "1.0.0",
|
|
4799
4994
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4800
4995
|
operation,
|
|
4801
|
-
requestId:
|
|
4996
|
+
requestId: randomUUID4(),
|
|
4802
4997
|
transport: "cli",
|
|
4803
4998
|
strict: true,
|
|
4804
4999
|
mvi,
|
|
@@ -4823,7 +5018,7 @@ function emitJsonError4(operation, mvi, code, message, category, details = {}) {
|
|
|
4823
5018
|
}
|
|
4824
5019
|
|
|
4825
5020
|
// src/commands/skills/remove.ts
|
|
4826
|
-
import
|
|
5021
|
+
import pc14 from "picocolors";
|
|
4827
5022
|
function registerSkillsRemove(parent) {
|
|
4828
5023
|
parent.command("remove").description("Remove installed skill(s)").argument("[name]", "Skill name to remove").option("-g, --global", "Remove from global scope").option("-y, --yes", "Skip confirmation").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(
|
|
4829
5024
|
async (name, opts) => {
|
|
@@ -4873,14 +5068,14 @@ function registerSkillsRemove(parent) {
|
|
|
4873
5068
|
return;
|
|
4874
5069
|
}
|
|
4875
5070
|
if (removed.length > 0) {
|
|
4876
|
-
console.log(
|
|
5071
|
+
console.log(pc14.green(`\u2713 Removed ${pc14.bold(name)} from: ${removed.join(", ")}`));
|
|
4877
5072
|
await removeSkillFromLock(name);
|
|
4878
5073
|
} else {
|
|
4879
|
-
console.log(
|
|
5074
|
+
console.log(pc14.yellow(`Skill ${name} not found in any provider.`));
|
|
4880
5075
|
}
|
|
4881
5076
|
if (result.errors.length > 0) {
|
|
4882
5077
|
for (const err of result.errors) {
|
|
4883
|
-
console.log(
|
|
5078
|
+
console.log(pc14.red(` ${err}`));
|
|
4884
5079
|
}
|
|
4885
5080
|
}
|
|
4886
5081
|
} else {
|
|
@@ -4893,7 +5088,7 @@ function registerSkillsRemove(parent) {
|
|
|
4893
5088
|
count: { removed: 0, total: 0 }
|
|
4894
5089
|
});
|
|
4895
5090
|
} else {
|
|
4896
|
-
console.log(
|
|
5091
|
+
console.log(pc14.dim("No skills installed."));
|
|
4897
5092
|
}
|
|
4898
5093
|
return;
|
|
4899
5094
|
}
|
|
@@ -4906,18 +5101,18 @@ function registerSkillsRemove(parent) {
|
|
|
4906
5101
|
});
|
|
4907
5102
|
return;
|
|
4908
5103
|
}
|
|
4909
|
-
console.log(
|
|
5104
|
+
console.log(pc14.bold("Installed skills:"));
|
|
4910
5105
|
for (const s of skills) {
|
|
4911
5106
|
console.log(` ${s}`);
|
|
4912
5107
|
}
|
|
4913
|
-
console.log(
|
|
5108
|
+
console.log(pc14.dim("\nUse: caamp skills remove <name>"));
|
|
4914
5109
|
}
|
|
4915
5110
|
}
|
|
4916
5111
|
);
|
|
4917
5112
|
}
|
|
4918
5113
|
|
|
4919
5114
|
// src/commands/skills/update.ts
|
|
4920
|
-
import
|
|
5115
|
+
import pc15 from "picocolors";
|
|
4921
5116
|
function registerSkillsUpdate(parent) {
|
|
4922
5117
|
parent.command("update").description("Update all outdated skills").option("-y, --yes", "Skip confirmation").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (opts) => {
|
|
4923
5118
|
const operation = "skills.update";
|
|
@@ -4951,12 +5146,12 @@ function registerSkillsUpdate(parent) {
|
|
|
4951
5146
|
count: { updated: 0, failed: 0, skipped: 0 }
|
|
4952
5147
|
});
|
|
4953
5148
|
} else {
|
|
4954
|
-
console.log(
|
|
5149
|
+
console.log(pc15.dim("No tracked skills to update."));
|
|
4955
5150
|
}
|
|
4956
5151
|
return;
|
|
4957
5152
|
}
|
|
4958
5153
|
if (format === "human") {
|
|
4959
|
-
console.log(
|
|
5154
|
+
console.log(pc15.dim(`Checking ${entries.length} skill(s) for updates...`));
|
|
4960
5155
|
}
|
|
4961
5156
|
const outdated = [];
|
|
4962
5157
|
for (const [name] of entries) {
|
|
@@ -4978,19 +5173,19 @@ function registerSkillsUpdate(parent) {
|
|
|
4978
5173
|
count: { updated: 0, failed: 0, skipped: 0 }
|
|
4979
5174
|
});
|
|
4980
5175
|
} else {
|
|
4981
|
-
console.log(
|
|
5176
|
+
console.log(pc15.green("\nAll skills are up to date."));
|
|
4982
5177
|
}
|
|
4983
5178
|
return;
|
|
4984
5179
|
}
|
|
4985
5180
|
if (format === "human") {
|
|
4986
|
-
console.log(
|
|
5181
|
+
console.log(pc15.yellow(`
|
|
4987
5182
|
${outdated.length} skill(s) have updates available:
|
|
4988
5183
|
`));
|
|
4989
5184
|
for (const skill of outdated) {
|
|
4990
5185
|
const current = skill.currentVersion?.slice(0, 12) ?? "?";
|
|
4991
5186
|
const latest = skill.latestVersion ?? "?";
|
|
4992
5187
|
console.log(
|
|
4993
|
-
` ${
|
|
5188
|
+
` ${pc15.bold(skill.name)} ${pc15.dim(current)} ${pc15.dim("->")} ${pc15.cyan(latest)}`
|
|
4994
5189
|
);
|
|
4995
5190
|
}
|
|
4996
5191
|
}
|
|
@@ -4998,11 +5193,11 @@ ${outdated.length} skill(s) have updates available:
|
|
|
4998
5193
|
const readline = await import("readline");
|
|
4999
5194
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
5000
5195
|
const answer = await new Promise((resolve3) => {
|
|
5001
|
-
rl.question(
|
|
5196
|
+
rl.question(pc15.dim("\nProceed with update? [y/N] "), resolve3);
|
|
5002
5197
|
});
|
|
5003
5198
|
rl.close();
|
|
5004
5199
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
5005
|
-
console.log(
|
|
5200
|
+
console.log(pc15.dim("Update cancelled."));
|
|
5006
5201
|
return;
|
|
5007
5202
|
}
|
|
5008
5203
|
}
|
|
@@ -5016,7 +5211,7 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5016
5211
|
const entry = tracked[skill.name];
|
|
5017
5212
|
if (!entry) continue;
|
|
5018
5213
|
if (format === "human") {
|
|
5019
|
-
console.log(
|
|
5214
|
+
console.log(pc15.dim(`Updating ${pc15.bold(skill.name)}...`));
|
|
5020
5215
|
}
|
|
5021
5216
|
try {
|
|
5022
5217
|
const parsed = parseSource(entry.source);
|
|
@@ -5038,7 +5233,7 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5038
5233
|
} else {
|
|
5039
5234
|
if (format === "human") {
|
|
5040
5235
|
console.log(
|
|
5041
|
-
|
|
5236
|
+
pc15.yellow(
|
|
5042
5237
|
` Skipped ${skill.name}: source type "${parsed.type}" does not support auto-update`
|
|
5043
5238
|
)
|
|
5044
5239
|
);
|
|
@@ -5050,7 +5245,7 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5050
5245
|
const providers = entry.agents.map((a) => getProvider(a)).filter((p) => p !== void 0);
|
|
5051
5246
|
if (providers.length === 0) {
|
|
5052
5247
|
if (format === "human") {
|
|
5053
|
-
console.log(
|
|
5248
|
+
console.log(pc15.yellow(` Skipped ${skill.name}: no valid providers found`));
|
|
5054
5249
|
}
|
|
5055
5250
|
skipped.push(skill.name);
|
|
5056
5251
|
continue;
|
|
@@ -5075,18 +5270,18 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5075
5270
|
skill.latestVersion
|
|
5076
5271
|
);
|
|
5077
5272
|
if (format === "human") {
|
|
5078
|
-
console.log(
|
|
5273
|
+
console.log(pc15.green(` Updated ${pc15.bold(skill.name)}`));
|
|
5079
5274
|
}
|
|
5080
5275
|
updated.push(skill.name);
|
|
5081
5276
|
} else {
|
|
5082
5277
|
if (format === "human") {
|
|
5083
|
-
console.log(
|
|
5278
|
+
console.log(pc15.red(` Failed to update ${skill.name}: no agents linked`));
|
|
5084
5279
|
}
|
|
5085
5280
|
failed.push({ name: skill.name, error: "no agents linked" });
|
|
5086
5281
|
}
|
|
5087
5282
|
if (installResult.errors.length > 0 && format === "human") {
|
|
5088
5283
|
for (const err of installResult.errors) {
|
|
5089
|
-
console.log(
|
|
5284
|
+
console.log(pc15.yellow(` ${err}`));
|
|
5090
5285
|
}
|
|
5091
5286
|
}
|
|
5092
5287
|
} finally {
|
|
@@ -5095,7 +5290,7 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5095
5290
|
} catch (err) {
|
|
5096
5291
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5097
5292
|
if (format === "human") {
|
|
5098
|
-
console.log(
|
|
5293
|
+
console.log(pc15.red(` Failed to update ${skill.name}: ${msg}`));
|
|
5099
5294
|
}
|
|
5100
5295
|
failed.push({ name: skill.name, error: msg });
|
|
5101
5296
|
}
|
|
@@ -5115,24 +5310,24 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5115
5310
|
}
|
|
5116
5311
|
console.log();
|
|
5117
5312
|
if (updated.length > 0) {
|
|
5118
|
-
console.log(
|
|
5313
|
+
console.log(pc15.green(`Updated ${updated.length} skill(s).`));
|
|
5119
5314
|
}
|
|
5120
5315
|
if (failed.length > 0) {
|
|
5121
|
-
console.log(
|
|
5316
|
+
console.log(pc15.red(`Failed to update ${failed.length} skill(s).`));
|
|
5122
5317
|
}
|
|
5123
5318
|
});
|
|
5124
5319
|
}
|
|
5125
5320
|
|
|
5126
5321
|
// src/commands/skills/validate.ts
|
|
5127
|
-
import { resolveOutputFormat as
|
|
5128
|
-
import
|
|
5322
|
+
import { resolveOutputFormat as resolveOutputFormat4 } from "@cleocode/lafs";
|
|
5323
|
+
import pc16 from "picocolors";
|
|
5129
5324
|
function registerSkillsValidate(parent) {
|
|
5130
5325
|
parent.command("validate").description("Validate SKILL.md format").argument("[path]", "Path to SKILL.md", "SKILL.md").option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(async (path, opts) => {
|
|
5131
5326
|
const operation = "skills.validate";
|
|
5132
5327
|
const mvi = "standard";
|
|
5133
5328
|
let format;
|
|
5134
5329
|
try {
|
|
5135
|
-
format =
|
|
5330
|
+
format = resolveOutputFormat4({
|
|
5136
5331
|
jsonFlag: opts.json ?? false,
|
|
5137
5332
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
5138
5333
|
projectDefault: "json"
|
|
@@ -5165,7 +5360,7 @@ function registerSkillsValidate(parent) {
|
|
|
5165
5360
|
}
|
|
5166
5361
|
);
|
|
5167
5362
|
} else {
|
|
5168
|
-
console.error(
|
|
5363
|
+
console.error(pc16.red(message));
|
|
5169
5364
|
}
|
|
5170
5365
|
process.exit(1);
|
|
5171
5366
|
}
|
|
@@ -5187,12 +5382,12 @@ function registerSkillsValidate(parent) {
|
|
|
5187
5382
|
console.log(JSON.stringify(envelope, null, 2));
|
|
5188
5383
|
} else {
|
|
5189
5384
|
if (result.valid) {
|
|
5190
|
-
console.log(
|
|
5385
|
+
console.log(pc16.green(`\u2713 ${path} is valid`));
|
|
5191
5386
|
} else {
|
|
5192
|
-
console.log(
|
|
5387
|
+
console.log(pc16.red(`\u2717 ${path} has validation errors`));
|
|
5193
5388
|
}
|
|
5194
5389
|
for (const issue of result.issues) {
|
|
5195
|
-
const icon = issue.level === "error" ?
|
|
5390
|
+
const icon = issue.level === "error" ? pc16.red("\u2717") : pc16.yellow("!");
|
|
5196
5391
|
console.log(` ${icon} [${issue.field}] ${issue.message}`);
|
|
5197
5392
|
}
|
|
5198
5393
|
}
|
|
@@ -5214,6 +5409,8 @@ function registerSkillsCommands(program2) {
|
|
|
5214
5409
|
registerSkillsInit(skills);
|
|
5215
5410
|
registerSkillsAudit(skills);
|
|
5216
5411
|
registerSkillsValidate(skills);
|
|
5412
|
+
registerSkillsDoctorMigrate(skills);
|
|
5413
|
+
registerSkillsDoctor(skills);
|
|
5217
5414
|
}
|
|
5218
5415
|
|
|
5219
5416
|
// src/cli.ts
|