@cleocode/caamp 2026.5.87 → 2026.5.89
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-PGETUTYZ.js → chunk-EH5U4PRC.js} +2 -2
- package/dist/{chunk-H5YXR2DC.js → chunk-HDZYZTR2.js} +1 -34
- package/dist/chunk-HDZYZTR2.js.map +1 -0
- package/dist/{chunk-WXL7RPS4.js → chunk-RTK4A3WY.js} +90 -862
- package/dist/chunk-RTK4A3WY.js.map +1 -0
- package/dist/{chunk-QKC2JRSG.js → chunk-YCAANESR.js} +2 -2
- package/dist/cli.js +259 -458
- package/dist/cli.js.map +1 -1
- package/dist/{hooks-ZN3C4WCK.js → hooks-FHFZZENR.js} +3 -3
- package/dist/index.d.ts +13 -616
- package/dist/index.js +7 -30
- package/dist/index.js.map +1 -1
- package/dist/{injector-QPOIJVOR.js → injector-3TOVIDBO.js} +3 -3
- package/package.json +6 -5
- package/dist/chunk-H5YXR2DC.js.map +0 -1
- package/dist/chunk-WXL7RPS4.js.map +0 -1
- /package/dist/{chunk-PGETUTYZ.js.map → chunk-EH5U4PRC.js.map} +0 -0
- /package/dist/{chunk-QKC2JRSG.js.map → chunk-YCAANESR.js.map} +0 -0
- /package/dist/{hooks-ZN3C4WCK.js.map → hooks-FHFZZENR.js.map} +0 -0
- /package/dist/{injector-QPOIJVOR.js.map → injector-3TOVIDBO.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
CANONICAL_SKILLS_DIR,
|
|
4
|
-
ErrorCategories,
|
|
5
|
-
ErrorCodes,
|
|
6
3
|
MarketplaceClient,
|
|
7
4
|
PiHarness,
|
|
8
5
|
RECOMMENDATION_ERROR_CODES,
|
|
9
|
-
buildEnvelope,
|
|
10
6
|
checkSkillUpdate,
|
|
11
7
|
detectAllProviders,
|
|
12
8
|
detectMcpInstallations,
|
|
@@ -15,8 +11,6 @@ import {
|
|
|
15
11
|
discoverSkillsMulti,
|
|
16
12
|
dispatchInstallSkillAcrossProviders,
|
|
17
13
|
dispatchRemoveSkillAcrossProviders,
|
|
18
|
-
emitError,
|
|
19
|
-
emitJsonError,
|
|
20
14
|
fetchWithTimeout,
|
|
21
15
|
formatNetworkError,
|
|
22
16
|
formatSkillRecommendations,
|
|
@@ -25,31 +19,27 @@ import {
|
|
|
25
19
|
getSkill,
|
|
26
20
|
getSkillDir,
|
|
27
21
|
getTrackedSkills,
|
|
28
|
-
handleFormatError,
|
|
29
22
|
installBatchWithRollback,
|
|
30
23
|
installMcpServer,
|
|
31
24
|
isCatalogAvailable,
|
|
32
25
|
isHuman,
|
|
33
26
|
isMarketplaceScoped,
|
|
27
|
+
isQuiet,
|
|
34
28
|
isVerbose,
|
|
35
29
|
listAllMcpServers,
|
|
36
30
|
listCanonicalSkills,
|
|
37
31
|
listMcpServers,
|
|
38
32
|
listProfiles,
|
|
39
33
|
listSkills,
|
|
40
|
-
outputSuccess,
|
|
41
34
|
parseSource,
|
|
42
35
|
readConfig,
|
|
43
36
|
readLockFile,
|
|
44
37
|
recommendSkills,
|
|
45
38
|
recordSkillInstall,
|
|
46
|
-
registerDoctorBridge,
|
|
47
|
-
registerSkillsDoctorAdopt,
|
|
48
39
|
removeMcpServer,
|
|
49
40
|
removeMcpServerFromAll,
|
|
50
41
|
removeSkillFromLock,
|
|
51
42
|
resolveDefaultTargetProviders,
|
|
52
|
-
resolveFormat,
|
|
53
43
|
resolveProfile,
|
|
54
44
|
scanDirectory,
|
|
55
45
|
scanFile,
|
|
@@ -61,7 +51,7 @@ import {
|
|
|
61
51
|
tokenizeCriteriaValue,
|
|
62
52
|
updateInstructionsSingleOperation,
|
|
63
53
|
validateSkill
|
|
64
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-RTK4A3WY.js";
|
|
65
55
|
import {
|
|
66
56
|
buildSkillsMap,
|
|
67
57
|
checkAllInjections,
|
|
@@ -74,7 +64,7 @@ import {
|
|
|
74
64
|
groupByInstructFile,
|
|
75
65
|
injectAll,
|
|
76
66
|
providerSupports
|
|
77
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-EH5U4PRC.js";
|
|
78
68
|
import {
|
|
79
69
|
CANONICAL_HOOK_EVENTS,
|
|
80
70
|
buildHookMatrix,
|
|
@@ -83,12 +73,12 @@ import {
|
|
|
83
73
|
getHookSupport,
|
|
84
74
|
getProviderSummary,
|
|
85
75
|
translateToAll
|
|
86
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-YCAANESR.js";
|
|
87
77
|
import {
|
|
88
78
|
buildSkillSubPathCandidates,
|
|
89
79
|
resolveProviderConfigPath,
|
|
90
80
|
resolveProviderSkillsDir
|
|
91
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-HDZYZTR2.js";
|
|
92
82
|
|
|
93
83
|
// src/cli.ts
|
|
94
84
|
import { Command } from "commander";
|
|
@@ -162,7 +152,7 @@ function emitSuccess(operation, result, mvi = "standard") {
|
|
|
162
152
|
};
|
|
163
153
|
console.log(JSON.stringify(envelope, null, 2));
|
|
164
154
|
}
|
|
165
|
-
function
|
|
155
|
+
function emitError(operation, error, mvi = "standard") {
|
|
166
156
|
let envelope;
|
|
167
157
|
if (error instanceof LAFSCommandError) {
|
|
168
158
|
envelope = {
|
|
@@ -213,7 +203,7 @@ async function runLafsCommand(command, mvi, action) {
|
|
|
213
203
|
const result = await action();
|
|
214
204
|
emitSuccess(command, result, mvi);
|
|
215
205
|
} catch (error) {
|
|
216
|
-
|
|
206
|
+
emitError(command, error, mvi);
|
|
217
207
|
process.exit(1);
|
|
218
208
|
}
|
|
219
209
|
}
|
|
@@ -508,6 +498,121 @@ function registerAdvancedCommands(program2) {
|
|
|
508
498
|
// src/commands/config.ts
|
|
509
499
|
import { existsSync } from "fs";
|
|
510
500
|
import pc from "picocolors";
|
|
501
|
+
|
|
502
|
+
// src/core/lafs.ts
|
|
503
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
504
|
+
import { resolveOutputFormat } from "@cleocode/lafs";
|
|
505
|
+
function resolveFormat(options) {
|
|
506
|
+
return resolveOutputFormat({
|
|
507
|
+
jsonFlag: options.jsonFlag ?? false,
|
|
508
|
+
humanFlag: (options.humanFlag ?? false) || isHuman(),
|
|
509
|
+
projectDefault: options.projectDefault ?? "json"
|
|
510
|
+
}).format;
|
|
511
|
+
}
|
|
512
|
+
function buildEnvelope(operation, mvi, result, error, page = null, sessionId, warnings) {
|
|
513
|
+
return {
|
|
514
|
+
$schema: "https://lafs.dev/schemas/v1/envelope.schema.json",
|
|
515
|
+
_meta: {
|
|
516
|
+
specVersion: "1.0.0",
|
|
517
|
+
schemaVersion: "1.0.0",
|
|
518
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
519
|
+
operation,
|
|
520
|
+
requestId: randomUUID2(),
|
|
521
|
+
transport: "cli",
|
|
522
|
+
strict: true,
|
|
523
|
+
mvi,
|
|
524
|
+
contextVersion: 0,
|
|
525
|
+
...sessionId && { sessionId },
|
|
526
|
+
...warnings && warnings.length > 0 && { warnings }
|
|
527
|
+
},
|
|
528
|
+
success: error === null,
|
|
529
|
+
result,
|
|
530
|
+
error,
|
|
531
|
+
page
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function emitError2(operation, mvi, code, message, category, details = {}, exitCode = 1) {
|
|
535
|
+
const envelope = buildEnvelope(operation, mvi, null, {
|
|
536
|
+
code,
|
|
537
|
+
message,
|
|
538
|
+
category,
|
|
539
|
+
retryable: category === "TRANSIENT" || category === "RATE_LIMIT",
|
|
540
|
+
retryAfterMs: null,
|
|
541
|
+
details
|
|
542
|
+
});
|
|
543
|
+
console.error(JSON.stringify(envelope, null, 2));
|
|
544
|
+
process.exit(exitCode);
|
|
545
|
+
}
|
|
546
|
+
function emitJsonError(operation, mvi, code, message, category, details = {}) {
|
|
547
|
+
const envelope = buildEnvelope(operation, mvi, null, {
|
|
548
|
+
code,
|
|
549
|
+
message,
|
|
550
|
+
category,
|
|
551
|
+
retryable: category === "TRANSIENT" || category === "RATE_LIMIT",
|
|
552
|
+
retryAfterMs: null,
|
|
553
|
+
details
|
|
554
|
+
});
|
|
555
|
+
console.error(JSON.stringify(envelope, null, 2));
|
|
556
|
+
}
|
|
557
|
+
function outputSuccess(operation, mvi, result, page, sessionId, warnings) {
|
|
558
|
+
const envelope = buildEnvelope(operation, mvi, result, null, page ?? null, sessionId, warnings);
|
|
559
|
+
if (isQuiet() && !envelope.error) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
563
|
+
}
|
|
564
|
+
function handleFormatError(error, operation, mvi, jsonFlag) {
|
|
565
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
566
|
+
if (jsonFlag) {
|
|
567
|
+
emitJsonError(operation, mvi, "E_FORMAT_CONFLICT", message, "VALIDATION");
|
|
568
|
+
} else {
|
|
569
|
+
console.error(message);
|
|
570
|
+
}
|
|
571
|
+
process.exit(1);
|
|
572
|
+
}
|
|
573
|
+
var ErrorCategories = {
|
|
574
|
+
VALIDATION: "VALIDATION",
|
|
575
|
+
AUTH: "AUTH",
|
|
576
|
+
PERMISSION: "PERMISSION",
|
|
577
|
+
NOT_FOUND: "NOT_FOUND",
|
|
578
|
+
CONFLICT: "CONFLICT",
|
|
579
|
+
RATE_LIMIT: "RATE_LIMIT",
|
|
580
|
+
TRANSIENT: "TRANSIENT",
|
|
581
|
+
INTERNAL: "INTERNAL",
|
|
582
|
+
CONTRACT: "CONTRACT",
|
|
583
|
+
MIGRATION: "MIGRATION"
|
|
584
|
+
};
|
|
585
|
+
var ErrorCodes = {
|
|
586
|
+
// Format errors
|
|
587
|
+
FORMAT_CONFLICT: "E_FORMAT_CONFLICT",
|
|
588
|
+
INVALID_JSON: "E_INVALID_JSON",
|
|
589
|
+
// Not found errors
|
|
590
|
+
SKILL_NOT_FOUND: "E_SKILL_NOT_FOUND",
|
|
591
|
+
PROVIDER_NOT_FOUND: "E_PROVIDER_NOT_FOUND",
|
|
592
|
+
MCP_SERVER_NOT_FOUND: "E_MCP_SERVER_NOT_FOUND",
|
|
593
|
+
FILE_NOT_FOUND: "E_FILE_NOT_FOUND",
|
|
594
|
+
// Validation errors
|
|
595
|
+
INVALID_INPUT: "E_INVALID_INPUT",
|
|
596
|
+
INVALID_CONSTRAINT: "E_INVALID_CONSTRAINT",
|
|
597
|
+
INVALID_FORMAT: "E_INVALID_FORMAT",
|
|
598
|
+
// Operation errors
|
|
599
|
+
INSTALL_FAILED: "E_INSTALL_FAILED",
|
|
600
|
+
// Skills federation gates (T9564 — Sphere B)
|
|
601
|
+
SKILL_TRUST_GATE_BLOCKED: "E_SKILL_TRUST_GATE_BLOCKED",
|
|
602
|
+
FEDERATION_UNKNOWN_SOURCE_INTERACTIVE_REQUIRED: "E_FEDERATION_UNKNOWN_SOURCE_INTERACTIVE_REQUIRED",
|
|
603
|
+
FEDERATION_CHECKSUM_MISMATCH: "E_FEDERATION_CHECKSUM_MISMATCH",
|
|
604
|
+
REMOVE_FAILED: "E_REMOVE_FAILED",
|
|
605
|
+
UPDATE_FAILED: "E_UPDATE_FAILED",
|
|
606
|
+
VALIDATION_FAILED: "E_VALIDATION_FAILED",
|
|
607
|
+
AUDIT_FAILED: "E_AUDIT_FAILED",
|
|
608
|
+
// System errors
|
|
609
|
+
NETWORK_ERROR: "E_NETWORK_ERROR",
|
|
610
|
+
FILE_SYSTEM_ERROR: "E_FILE_SYSTEM_ERROR",
|
|
611
|
+
PERMISSION_DENIED: "E_PERMISSION_DENIED",
|
|
612
|
+
INTERNAL_ERROR: "E_INTERNAL_ERROR"
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
// src/commands/config.ts
|
|
511
616
|
function registerConfigCommand(program2) {
|
|
512
617
|
const config = program2.command("config").description("View provider configuration");
|
|
513
618
|
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(
|
|
@@ -653,6 +758,7 @@ import { execFileSync } from "child_process";
|
|
|
653
758
|
import { existsSync as existsSync2, lstatSync, readdirSync, readlinkSync } from "fs";
|
|
654
759
|
import { homedir } from "os";
|
|
655
760
|
import { join as join2 } from "path";
|
|
761
|
+
import { resolveSkillsRoot } from "@cleocode/core/skills/skill-root.js";
|
|
656
762
|
import pc2 from "picocolors";
|
|
657
763
|
|
|
658
764
|
// src/core/version.ts
|
|
@@ -753,7 +859,7 @@ function checkInstalledProviders() {
|
|
|
753
859
|
}
|
|
754
860
|
function checkSkillSymlinks() {
|
|
755
861
|
const checks = [];
|
|
756
|
-
const canonicalDir =
|
|
862
|
+
const canonicalDir = resolveSkillsRoot();
|
|
757
863
|
if (!existsSync2(canonicalDir)) {
|
|
758
864
|
checks.push({ label: "0 canonical skills", status: "pass" });
|
|
759
865
|
checks.push({ label: "No broken symlinks", status: "pass" });
|
|
@@ -849,7 +955,7 @@ async function checkLockFile() {
|
|
|
849
955
|
detail: orphaned.join(", ")
|
|
850
956
|
});
|
|
851
957
|
}
|
|
852
|
-
const canonicalDir =
|
|
958
|
+
const canonicalDir = resolveSkillsRoot();
|
|
853
959
|
if (existsSync2(canonicalDir)) {
|
|
854
960
|
const onDisk = readdirSync(canonicalDir).filter((name) => {
|
|
855
961
|
try {
|
|
@@ -1067,7 +1173,7 @@ function registerDoctorCommand(program2) {
|
|
|
1067
1173
|
});
|
|
1068
1174
|
}
|
|
1069
1175
|
function countSkillIssues() {
|
|
1070
|
-
const canonicalDir =
|
|
1176
|
+
const canonicalDir = resolveSkillsRoot();
|
|
1071
1177
|
let canonicalCount = 0;
|
|
1072
1178
|
if (existsSync2(canonicalDir)) {
|
|
1073
1179
|
try {
|
|
@@ -2837,8 +2943,8 @@ function registerPiCommands(program2) {
|
|
|
2837
2943
|
}
|
|
2838
2944
|
|
|
2839
2945
|
// src/commands/providers.ts
|
|
2840
|
-
import { randomUUID as
|
|
2841
|
-
import { resolveOutputFormat } from "@cleocode/lafs";
|
|
2946
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
2947
|
+
import { resolveOutputFormat as resolveOutputFormat2 } from "@cleocode/lafs";
|
|
2842
2948
|
import pc6 from "picocolors";
|
|
2843
2949
|
function registerProvidersCommand(program2) {
|
|
2844
2950
|
const providers = program2.command("providers").description("Manage AI agent providers");
|
|
@@ -2847,7 +2953,7 @@ function registerProvidersCommand(program2) {
|
|
|
2847
2953
|
const mvi = "standard";
|
|
2848
2954
|
let format;
|
|
2849
2955
|
try {
|
|
2850
|
-
format =
|
|
2956
|
+
format = resolveOutputFormat2({
|
|
2851
2957
|
jsonFlag: opts.json ?? false,
|
|
2852
2958
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
2853
2959
|
projectDefault: "json"
|
|
@@ -2897,7 +3003,7 @@ CAMP Provider Registry v${getRegistryVersion()}`));
|
|
|
2897
3003
|
const mvi = "standard";
|
|
2898
3004
|
let format;
|
|
2899
3005
|
try {
|
|
2900
|
-
format =
|
|
3006
|
+
format = resolveOutputFormat2({
|
|
2901
3007
|
jsonFlag: opts.json ?? false,
|
|
2902
3008
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
2903
3009
|
projectDefault: "json"
|
|
@@ -2953,7 +3059,7 @@ Detected ${installed.length} installed providers:
|
|
|
2953
3059
|
const mvi = "standard";
|
|
2954
3060
|
let format;
|
|
2955
3061
|
try {
|
|
2956
|
-
format =
|
|
3062
|
+
format = resolveOutputFormat2({
|
|
2957
3063
|
jsonFlag: opts.json ?? false,
|
|
2958
3064
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
2959
3065
|
projectDefault: "json"
|
|
@@ -3026,7 +3132,7 @@ ${provider.toolName}`));
|
|
|
3026
3132
|
const mvi = "standard";
|
|
3027
3133
|
let format;
|
|
3028
3134
|
try {
|
|
3029
|
-
format =
|
|
3135
|
+
format = resolveOutputFormat2({
|
|
3030
3136
|
jsonFlag: opts.json ?? false,
|
|
3031
3137
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3032
3138
|
projectDefault: "json"
|
|
@@ -3084,7 +3190,7 @@ ${provider.toolName}`));
|
|
|
3084
3190
|
const mvi = "standard";
|
|
3085
3191
|
let format;
|
|
3086
3192
|
try {
|
|
3087
|
-
format =
|
|
3193
|
+
format = resolveOutputFormat2({
|
|
3088
3194
|
jsonFlag: opts.json ?? false,
|
|
3089
3195
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3090
3196
|
projectDefault: "json"
|
|
@@ -3152,7 +3258,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3152
3258
|
const mvi = "standard";
|
|
3153
3259
|
let format;
|
|
3154
3260
|
try {
|
|
3155
|
-
format =
|
|
3261
|
+
format = resolveOutputFormat2({
|
|
3156
3262
|
jsonFlag: opts.json ?? false,
|
|
3157
3263
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3158
3264
|
projectDefault: "json"
|
|
@@ -3199,7 +3305,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3199
3305
|
const mvi = "standard";
|
|
3200
3306
|
let format;
|
|
3201
3307
|
try {
|
|
3202
|
-
format =
|
|
3308
|
+
format = resolveOutputFormat2({
|
|
3203
3309
|
jsonFlag: opts.json ?? false,
|
|
3204
3310
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3205
3311
|
projectDefault: "json"
|
|
@@ -3247,7 +3353,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3247
3353
|
return;
|
|
3248
3354
|
}
|
|
3249
3355
|
if (opts.from) {
|
|
3250
|
-
const { toCanonical } = await import("./hooks-
|
|
3356
|
+
const { toCanonical } = await import("./hooks-FHFZZENR.js");
|
|
3251
3357
|
const canonical2 = toCanonical(event, opts.from);
|
|
3252
3358
|
if (format === "json") {
|
|
3253
3359
|
const envelope = buildEnvelope2(
|
|
@@ -3287,7 +3393,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3287
3393
|
}
|
|
3288
3394
|
process.exit(1);
|
|
3289
3395
|
}
|
|
3290
|
-
const { getMappedProviderIds } = await import("./hooks-
|
|
3396
|
+
const { getMappedProviderIds } = await import("./hooks-FHFZZENR.js");
|
|
3291
3397
|
const allIds = getMappedProviderIds();
|
|
3292
3398
|
const translations = translateToAll(canonical, allIds);
|
|
3293
3399
|
if (format === "json") {
|
|
@@ -3330,7 +3436,7 @@ CAMP Hook Support (mappings v${getHookMappingsVersion()})
|
|
|
3330
3436
|
const mvi = "standard";
|
|
3331
3437
|
let format;
|
|
3332
3438
|
try {
|
|
3333
|
-
format =
|
|
3439
|
+
format = resolveOutputFormat2({
|
|
3334
3440
|
jsonFlag: opts.json ?? false,
|
|
3335
3441
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3336
3442
|
projectDefault: "json"
|
|
@@ -3400,7 +3506,7 @@ function buildEnvelope2(operation, mvi, result, error) {
|
|
|
3400
3506
|
schemaVersion: "1.0.0",
|
|
3401
3507
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3402
3508
|
operation,
|
|
3403
|
-
requestId:
|
|
3509
|
+
requestId: randomUUID3(),
|
|
3404
3510
|
transport: "cli",
|
|
3405
3511
|
strict: true,
|
|
3406
3512
|
mvi,
|
|
@@ -3715,308 +3821,10 @@ function registerSkillsCheck(parent) {
|
|
|
3715
3821
|
});
|
|
3716
3822
|
}
|
|
3717
3823
|
|
|
3718
|
-
// src/commands/skills/doctor.ts
|
|
3719
|
-
function registerSkillsDoctor(parent) {
|
|
3720
|
-
const doctor = parent.command("doctor").description("Diagnose and repair the skill storage topology");
|
|
3721
|
-
registerDoctorBridge(doctor);
|
|
3722
|
-
}
|
|
3723
|
-
|
|
3724
|
-
// src/commands/skills/doctor-migrate.ts
|
|
3725
|
-
import pc9 from "picocolors";
|
|
3726
|
-
|
|
3727
|
-
// src/core/skills/migration.ts
|
|
3728
|
-
import { execFile } from "child_process";
|
|
3729
|
-
import {
|
|
3730
|
-
cpSync,
|
|
3731
|
-
existsSync as existsSync10,
|
|
3732
|
-
mkdirSync,
|
|
3733
|
-
readdirSync as readdirSync2,
|
|
3734
|
-
rmSync,
|
|
3735
|
-
statSync as statSync3,
|
|
3736
|
-
writeFileSync
|
|
3737
|
-
} from "fs";
|
|
3738
|
-
import { homedir as homedir2 } from "os";
|
|
3739
|
-
import { join as join8 } from "path";
|
|
3740
|
-
import { promisify } from "util";
|
|
3741
|
-
var execFileAsync = promisify(execFile);
|
|
3742
|
-
var LEGACY_MIGRATED_MARKER = ".MIGRATED-TO-CLEO";
|
|
3743
|
-
function defaultMigrationOptions(manifestNames) {
|
|
3744
|
-
const home = homedir2();
|
|
3745
|
-
return {
|
|
3746
|
-
legacyRoot: join8(home, ".local", "share", "agents", "skills"),
|
|
3747
|
-
canonicalRoot: join8(home, ".cleo", "skills"),
|
|
3748
|
-
backupDir: join8(home, ".cleo", "backups", "skills"),
|
|
3749
|
-
manifestNames,
|
|
3750
|
-
now: () => /* @__PURE__ */ new Date(),
|
|
3751
|
-
tarExec: systemTarExec,
|
|
3752
|
-
recordRow: () => void 0
|
|
3753
|
-
};
|
|
3754
|
-
}
|
|
3755
|
-
var systemTarExec = {
|
|
3756
|
-
async create({ archivePath, sourceRoot }) {
|
|
3757
|
-
const parent = join8(sourceRoot, "..");
|
|
3758
|
-
const base = sourceRoot.slice(parent.length + 1);
|
|
3759
|
-
await execFileAsync("tar", ["-czf", archivePath, "-C", parent, base]);
|
|
3760
|
-
},
|
|
3761
|
-
async extract({ archivePath, destinationRoot }) {
|
|
3762
|
-
mkdirSync(destinationRoot, { recursive: true });
|
|
3763
|
-
const parent = join8(destinationRoot, "..");
|
|
3764
|
-
await execFileAsync("tar", ["-xzf", archivePath, "-C", parent]);
|
|
3765
|
-
}
|
|
3766
|
-
};
|
|
3767
|
-
function isAlreadyMigrated(legacyRoot) {
|
|
3768
|
-
if (!existsSync10(legacyRoot)) return true;
|
|
3769
|
-
return existsSync10(join8(legacyRoot, LEGACY_MIGRATED_MARKER));
|
|
3770
|
-
}
|
|
3771
|
-
function listSkillDirs(root) {
|
|
3772
|
-
if (!existsSync10(root)) return [];
|
|
3773
|
-
const entries = readdirSync2(root, { withFileTypes: true });
|
|
3774
|
-
return entries.filter((d) => d.isDirectory() && d.name !== LEGACY_MIGRATED_MARKER).map((d) => d.name).sort();
|
|
3775
|
-
}
|
|
3776
|
-
function planMigration(options) {
|
|
3777
|
-
const start = Date.now();
|
|
3778
|
-
const migrated = [];
|
|
3779
|
-
const skipped = [];
|
|
3780
|
-
if (isAlreadyMigrated(options.legacyRoot)) {
|
|
3781
|
-
return {
|
|
3782
|
-
action: "no-op",
|
|
3783
|
-
migrated,
|
|
3784
|
-
skipped,
|
|
3785
|
-
backupPath: null,
|
|
3786
|
-
legacyRoot: options.legacyRoot,
|
|
3787
|
-
canonicalRoot: options.canonicalRoot,
|
|
3788
|
-
durationMs: Date.now() - start
|
|
3789
|
-
};
|
|
3790
|
-
}
|
|
3791
|
-
const names = listSkillDirs(options.legacyRoot);
|
|
3792
|
-
for (const name of names) {
|
|
3793
|
-
const legacyPath = join8(options.legacyRoot, name);
|
|
3794
|
-
if (!statSync3(legacyPath).isDirectory()) {
|
|
3795
|
-
skipped.push({ name, reason: "not-a-directory", legacyPath });
|
|
3796
|
-
continue;
|
|
3797
|
-
}
|
|
3798
|
-
const destPath = join8(options.canonicalRoot, name);
|
|
3799
|
-
if (existsSync10(destPath)) {
|
|
3800
|
-
skipped.push({ name, reason: "already-present", legacyPath });
|
|
3801
|
-
continue;
|
|
3802
|
-
}
|
|
3803
|
-
migrated.push({
|
|
3804
|
-
name,
|
|
3805
|
-
installPath: destPath,
|
|
3806
|
-
legacyPath,
|
|
3807
|
-
sourceType: options.manifestNames.includes(name) ? "canonical" : "user"
|
|
3808
|
-
});
|
|
3809
|
-
}
|
|
3810
|
-
return {
|
|
3811
|
-
action: "dry-run",
|
|
3812
|
-
migrated,
|
|
3813
|
-
skipped,
|
|
3814
|
-
backupPath: null,
|
|
3815
|
-
legacyRoot: options.legacyRoot,
|
|
3816
|
-
canonicalRoot: options.canonicalRoot,
|
|
3817
|
-
durationMs: Date.now() - start
|
|
3818
|
-
};
|
|
3819
|
-
}
|
|
3820
|
-
function formatBackupTimestamp(now) {
|
|
3821
|
-
const pad = (n) => n.toString().padStart(2, "0");
|
|
3822
|
-
return `${now.getUTCFullYear()}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}-${pad(now.getUTCHours())}${pad(now.getUTCMinutes())}${pad(now.getUTCSeconds())}`;
|
|
3823
|
-
}
|
|
3824
|
-
function listBackups(backupDir) {
|
|
3825
|
-
if (!existsSync10(backupDir)) return [];
|
|
3826
|
-
const files = readdirSync2(backupDir).filter(
|
|
3827
|
-
(f) => f.startsWith("skills-pre-migrate-") && f.endsWith(".tgz")
|
|
3828
|
-
);
|
|
3829
|
-
files.sort().reverse();
|
|
3830
|
-
return files.map((f) => join8(backupDir, f));
|
|
3831
|
-
}
|
|
3832
|
-
async function runMigration(options) {
|
|
3833
|
-
const start = Date.now();
|
|
3834
|
-
const now = (options.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
3835
|
-
const tar = options.tarExec ?? systemTarExec;
|
|
3836
|
-
const sink = options.recordRow ?? (() => void 0);
|
|
3837
|
-
if (isAlreadyMigrated(options.legacyRoot)) {
|
|
3838
|
-
return {
|
|
3839
|
-
action: "no-op",
|
|
3840
|
-
migrated: [],
|
|
3841
|
-
skipped: [],
|
|
3842
|
-
backupPath: null,
|
|
3843
|
-
legacyRoot: options.legacyRoot,
|
|
3844
|
-
canonicalRoot: options.canonicalRoot,
|
|
3845
|
-
durationMs: Date.now() - start
|
|
3846
|
-
};
|
|
3847
|
-
}
|
|
3848
|
-
const plan = planMigration(options);
|
|
3849
|
-
mkdirSync(options.canonicalRoot, { recursive: true });
|
|
3850
|
-
mkdirSync(options.backupDir, { recursive: true });
|
|
3851
|
-
const backupName = `skills-pre-migrate-${formatBackupTimestamp(now)}.tgz`;
|
|
3852
|
-
const backupPath = join8(options.backupDir, backupName);
|
|
3853
|
-
await tar.create({ archivePath: backupPath, sourceRoot: options.legacyRoot });
|
|
3854
|
-
for (const entry of plan.migrated) {
|
|
3855
|
-
cpSync(entry.legacyPath, entry.installPath, { recursive: true, dereference: false });
|
|
3856
|
-
await sink(entry);
|
|
3857
|
-
}
|
|
3858
|
-
writeFileSync(
|
|
3859
|
-
join8(options.legacyRoot, LEGACY_MIGRATED_MARKER),
|
|
3860
|
-
JSON.stringify(
|
|
3861
|
-
{
|
|
3862
|
-
migratedAt: now.toISOString(),
|
|
3863
|
-
backupPath,
|
|
3864
|
-
canonicalRoot: options.canonicalRoot,
|
|
3865
|
-
entries: plan.migrated.length
|
|
3866
|
-
},
|
|
3867
|
-
null,
|
|
3868
|
-
2
|
|
3869
|
-
),
|
|
3870
|
-
"utf-8"
|
|
3871
|
-
);
|
|
3872
|
-
return {
|
|
3873
|
-
action: "migrate",
|
|
3874
|
-
migrated: plan.migrated,
|
|
3875
|
-
skipped: plan.skipped,
|
|
3876
|
-
backupPath,
|
|
3877
|
-
legacyRoot: options.legacyRoot,
|
|
3878
|
-
canonicalRoot: options.canonicalRoot,
|
|
3879
|
-
durationMs: Date.now() - start
|
|
3880
|
-
};
|
|
3881
|
-
}
|
|
3882
|
-
async function runRollback(options) {
|
|
3883
|
-
const start = Date.now();
|
|
3884
|
-
const tar = options.tarExec ?? systemTarExec;
|
|
3885
|
-
const backups = listBackups(options.backupDir);
|
|
3886
|
-
const newest = backups[0];
|
|
3887
|
-
if (!newest) {
|
|
3888
|
-
throw new Error(
|
|
3889
|
-
`No backup tarballs found under ${options.backupDir}. Run "cleo skills migrate" (without --rollback) first.`
|
|
3890
|
-
);
|
|
3891
|
-
}
|
|
3892
|
-
if (existsSync10(options.legacyRoot)) {
|
|
3893
|
-
rmSync(options.legacyRoot, { recursive: true, force: true });
|
|
3894
|
-
}
|
|
3895
|
-
await tar.extract({ archivePath: newest, destinationRoot: options.legacyRoot });
|
|
3896
|
-
return {
|
|
3897
|
-
action: "rollback",
|
|
3898
|
-
migrated: [],
|
|
3899
|
-
skipped: [],
|
|
3900
|
-
backupPath: newest,
|
|
3901
|
-
legacyRoot: options.legacyRoot,
|
|
3902
|
-
canonicalRoot: options.canonicalRoot,
|
|
3903
|
-
durationMs: Date.now() - start
|
|
3904
|
-
};
|
|
3905
|
-
}
|
|
3906
|
-
|
|
3907
|
-
// src/commands/skills/doctor-migrate.ts
|
|
3908
|
-
function buildOptions(opts) {
|
|
3909
|
-
if (opts.__optionsOverride) return opts.__optionsOverride;
|
|
3910
|
-
const manifestNames = opts.__manifestNamesOverride ?? [];
|
|
3911
|
-
return defaultMigrationOptions(manifestNames);
|
|
3912
|
-
}
|
|
3913
|
-
function renderHuman(outcome) {
|
|
3914
|
-
const lines = [];
|
|
3915
|
-
lines.push(pc9.bold(`
|
|
3916
|
-
skills ${outcome.action}`));
|
|
3917
|
-
lines.push(pc9.dim(` legacy: ${outcome.legacyRoot}`));
|
|
3918
|
-
lines.push(pc9.dim(` canonical: ${outcome.canonicalRoot}`));
|
|
3919
|
-
if (outcome.backupPath) {
|
|
3920
|
-
lines.push(pc9.dim(` backup: ${outcome.backupPath}`));
|
|
3921
|
-
}
|
|
3922
|
-
lines.push(pc9.dim(` duration: ${outcome.durationMs}ms`));
|
|
3923
|
-
if (outcome.migrated.length > 0) {
|
|
3924
|
-
lines.push(pc9.green(`
|
|
3925
|
-
Migrated (${outcome.migrated.length}):`));
|
|
3926
|
-
for (const m of outcome.migrated) {
|
|
3927
|
-
lines.push(` + ${pc9.bold(m.name)} ${pc9.dim(`[${m.sourceType}]`)}`);
|
|
3928
|
-
}
|
|
3929
|
-
}
|
|
3930
|
-
if (outcome.skipped.length > 0) {
|
|
3931
|
-
lines.push(pc9.yellow(`
|
|
3932
|
-
Skipped (${outcome.skipped.length}):`));
|
|
3933
|
-
for (const s of outcome.skipped) {
|
|
3934
|
-
lines.push(` ! ${pc9.bold(s.name)} ${pc9.dim(`(${s.reason})`)}`);
|
|
3935
|
-
}
|
|
3936
|
-
}
|
|
3937
|
-
if (outcome.action === "no-op") {
|
|
3938
|
-
lines.push(pc9.dim("\nLegacy store is already migrated (sentinel present)."));
|
|
3939
|
-
}
|
|
3940
|
-
if (outcome.action === "dry-run") {
|
|
3941
|
-
lines.push(pc9.dim("\n(dry run \u2014 no filesystem changes were made)"));
|
|
3942
|
-
}
|
|
3943
|
-
return lines.join("\n");
|
|
3944
|
-
}
|
|
3945
|
-
function registerSkillsDoctorMigrate(parent) {
|
|
3946
|
-
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) => {
|
|
3947
|
-
const operation = "skills.migrate";
|
|
3948
|
-
const mvi = "standard";
|
|
3949
|
-
let format;
|
|
3950
|
-
try {
|
|
3951
|
-
format = resolveFormat({
|
|
3952
|
-
jsonFlag: opts.json ?? false,
|
|
3953
|
-
humanFlag: (opts.human ?? false) || isHuman(),
|
|
3954
|
-
projectDefault: "json"
|
|
3955
|
-
});
|
|
3956
|
-
} catch (error) {
|
|
3957
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3958
|
-
emitJsonError(
|
|
3959
|
-
operation,
|
|
3960
|
-
mvi,
|
|
3961
|
-
ErrorCodes.FORMAT_CONFLICT,
|
|
3962
|
-
message,
|
|
3963
|
-
ErrorCategories.VALIDATION
|
|
3964
|
-
);
|
|
3965
|
-
process.exit(1);
|
|
3966
|
-
}
|
|
3967
|
-
if (opts.dryRun && opts.rollback) {
|
|
3968
|
-
const message = "Cannot combine --dry-run with --rollback";
|
|
3969
|
-
if (format === "json") {
|
|
3970
|
-
emitJsonError(
|
|
3971
|
-
operation,
|
|
3972
|
-
mvi,
|
|
3973
|
-
ErrorCodes.INVALID_INPUT,
|
|
3974
|
-
message,
|
|
3975
|
-
ErrorCategories.VALIDATION
|
|
3976
|
-
);
|
|
3977
|
-
} else {
|
|
3978
|
-
console.error(pc9.red(message));
|
|
3979
|
-
}
|
|
3980
|
-
process.exit(1);
|
|
3981
|
-
}
|
|
3982
|
-
const options = buildOptions(opts);
|
|
3983
|
-
try {
|
|
3984
|
-
let outcome;
|
|
3985
|
-
if (opts.rollback) {
|
|
3986
|
-
outcome = await runRollback(options);
|
|
3987
|
-
} else if (opts.dryRun) {
|
|
3988
|
-
outcome = planMigration(options);
|
|
3989
|
-
} else {
|
|
3990
|
-
outcome = await runMigration(options);
|
|
3991
|
-
}
|
|
3992
|
-
if (format === "json") {
|
|
3993
|
-
outputSuccess(operation, mvi, outcome);
|
|
3994
|
-
} else {
|
|
3995
|
-
console.log(renderHuman(outcome));
|
|
3996
|
-
}
|
|
3997
|
-
} catch (error) {
|
|
3998
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3999
|
-
if (format === "json") {
|
|
4000
|
-
emitJsonError(
|
|
4001
|
-
operation,
|
|
4002
|
-
mvi,
|
|
4003
|
-
ErrorCodes.INTERNAL_ERROR,
|
|
4004
|
-
message,
|
|
4005
|
-
ErrorCategories.MIGRATION,
|
|
4006
|
-
{ legacyRoot: options.legacyRoot, canonicalRoot: options.canonicalRoot }
|
|
4007
|
-
);
|
|
4008
|
-
} else {
|
|
4009
|
-
console.error(pc9.red(`migration failed: ${message}`));
|
|
4010
|
-
}
|
|
4011
|
-
process.exit(1);
|
|
4012
|
-
}
|
|
4013
|
-
});
|
|
4014
|
-
}
|
|
4015
|
-
|
|
4016
3824
|
// src/commands/skills/find.ts
|
|
4017
|
-
import { randomUUID as
|
|
4018
|
-
import { resolveOutputFormat as
|
|
4019
|
-
import
|
|
3825
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
3826
|
+
import { resolveOutputFormat as resolveOutputFormat3 } from "@cleocode/lafs";
|
|
3827
|
+
import pc9 from "picocolors";
|
|
4020
3828
|
var SkillsFindValidationError = class extends Error {
|
|
4021
3829
|
code;
|
|
4022
3830
|
constructor(code, message) {
|
|
@@ -4047,7 +3855,7 @@ function registerSkillsFind(parent) {
|
|
|
4047
3855
|
const mvi = details ? "full" : "standard";
|
|
4048
3856
|
let format;
|
|
4049
3857
|
try {
|
|
4050
|
-
format =
|
|
3858
|
+
format = resolveOutputFormat3({
|
|
4051
3859
|
jsonFlag: opts.json ?? false,
|
|
4052
3860
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
4053
3861
|
projectDefault: "json"
|
|
@@ -4057,7 +3865,7 @@ function registerSkillsFind(parent) {
|
|
|
4057
3865
|
if (opts.json) {
|
|
4058
3866
|
emitJsonError3(operation, mvi, "E_FORMAT_CONFLICT", message, "VALIDATION");
|
|
4059
3867
|
} else {
|
|
4060
|
-
console.error(
|
|
3868
|
+
console.error(pc9.red(message));
|
|
4061
3869
|
}
|
|
4062
3870
|
process.exit(1);
|
|
4063
3871
|
}
|
|
@@ -4124,19 +3932,19 @@ function registerSkillsFind(parent) {
|
|
|
4124
3932
|
query: query ?? null
|
|
4125
3933
|
});
|
|
4126
3934
|
} else {
|
|
4127
|
-
console.error(
|
|
3935
|
+
console.error(pc9.red(`Recommendation failed: ${message}`));
|
|
4128
3936
|
}
|
|
4129
3937
|
process.exit(1);
|
|
4130
3938
|
}
|
|
4131
3939
|
}
|
|
4132
3940
|
if (!query) {
|
|
4133
|
-
console.log(
|
|
3941
|
+
console.log(pc9.dim("Usage: caamp skills find <query>"));
|
|
4134
3942
|
return;
|
|
4135
3943
|
}
|
|
4136
3944
|
const limit = parseInt(opts.limit, 10);
|
|
4137
3945
|
const client = new MarketplaceClient();
|
|
4138
3946
|
if (format === "human") {
|
|
4139
|
-
console.log(
|
|
3947
|
+
console.log(pc9.dim(`Searching marketplaces for "${query}"...
|
|
4140
3948
|
`));
|
|
4141
3949
|
}
|
|
4142
3950
|
let results;
|
|
@@ -4150,7 +3958,7 @@ function registerSkillsFind(parent) {
|
|
|
4150
3958
|
limit
|
|
4151
3959
|
});
|
|
4152
3960
|
} else {
|
|
4153
|
-
console.error(
|
|
3961
|
+
console.error(pc9.red(`Marketplace search failed: ${message}`));
|
|
4154
3962
|
}
|
|
4155
3963
|
process.exit(1);
|
|
4156
3964
|
}
|
|
@@ -4170,21 +3978,21 @@ function registerSkillsFind(parent) {
|
|
|
4170
3978
|
return;
|
|
4171
3979
|
}
|
|
4172
3980
|
if (results.length === 0) {
|
|
4173
|
-
console.log(
|
|
3981
|
+
console.log(pc9.yellow("No results found."));
|
|
4174
3982
|
return;
|
|
4175
3983
|
}
|
|
4176
|
-
console.log(
|
|
3984
|
+
console.log(pc9.dim(`Found ${results.length} result(s) for "${query}":
|
|
4177
3985
|
`));
|
|
4178
3986
|
results.forEach((skill, index) => {
|
|
4179
3987
|
const num = (index + 1).toString().padStart(2);
|
|
4180
|
-
const stars = skill.stars > 0 ?
|
|
4181
|
-
console.log(` ${
|
|
4182
|
-
console.log(` ${
|
|
4183
|
-
console.log(` ${
|
|
3988
|
+
const stars = skill.stars > 0 ? pc9.yellow(`\u2605 ${formatStars(skill.stars)}`) : "";
|
|
3989
|
+
console.log(` ${pc9.cyan(num)}. ${pc9.bold(skill.scopedName)} ${stars}`);
|
|
3990
|
+
console.log(` ${pc9.dim(skill.description?.slice(0, 80) ?? "")}`);
|
|
3991
|
+
console.log(` ${pc9.dim(`from ${skill.source}`)}`);
|
|
4184
3992
|
console.log();
|
|
4185
3993
|
});
|
|
4186
|
-
console.log(
|
|
4187
|
-
console.log(
|
|
3994
|
+
console.log(pc9.dim("Install with: caamp skills install <name>"));
|
|
3995
|
+
console.log(pc9.dim("Or select by number: caamp skills install <n>"));
|
|
4188
3996
|
});
|
|
4189
3997
|
}
|
|
4190
3998
|
function formatStars(n) {
|
|
@@ -4276,7 +4084,7 @@ function buildEnvelope3(operation, mvi, result, error) {
|
|
|
4276
4084
|
schemaVersion: "1.0.0",
|
|
4277
4085
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4278
4086
|
operation,
|
|
4279
|
-
requestId:
|
|
4087
|
+
requestId: randomUUID4(),
|
|
4280
4088
|
transport: "cli",
|
|
4281
4089
|
strict: true,
|
|
4282
4090
|
mvi,
|
|
@@ -4301,10 +4109,10 @@ function emitJsonError3(operation, mvi, code, message, category, details = {}) {
|
|
|
4301
4109
|
}
|
|
4302
4110
|
|
|
4303
4111
|
// src/commands/skills/init.ts
|
|
4304
|
-
import { existsSync as
|
|
4112
|
+
import { existsSync as existsSync10 } from "fs";
|
|
4305
4113
|
import { mkdir, writeFile as writeFile3 } from "fs/promises";
|
|
4306
|
-
import { join as
|
|
4307
|
-
import
|
|
4114
|
+
import { join as join8 } from "path";
|
|
4115
|
+
import pc10 from "picocolors";
|
|
4308
4116
|
function registerSkillsInit(parent) {
|
|
4309
4117
|
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(
|
|
4310
4118
|
async (name, opts) => {
|
|
@@ -4329,8 +4137,8 @@ function registerSkillsInit(parent) {
|
|
|
4329
4137
|
process.exit(1);
|
|
4330
4138
|
}
|
|
4331
4139
|
const skillName = name ?? "my-skill";
|
|
4332
|
-
const skillDir =
|
|
4333
|
-
if (
|
|
4140
|
+
const skillDir = join8(opts.dir, skillName);
|
|
4141
|
+
if (existsSync10(skillDir)) {
|
|
4334
4142
|
const message = `Directory already exists: ${skillDir}`;
|
|
4335
4143
|
if (format === "json") {
|
|
4336
4144
|
emitJsonError(
|
|
@@ -4344,7 +4152,7 @@ function registerSkillsInit(parent) {
|
|
|
4344
4152
|
}
|
|
4345
4153
|
);
|
|
4346
4154
|
} else {
|
|
4347
|
-
console.error(
|
|
4155
|
+
console.error(pc10.red(message));
|
|
4348
4156
|
}
|
|
4349
4157
|
process.exit(1);
|
|
4350
4158
|
}
|
|
@@ -4372,7 +4180,7 @@ Provide detailed instructions for the AI agent here.
|
|
|
4372
4180
|
|
|
4373
4181
|
Show example inputs and expected outputs.
|
|
4374
4182
|
`;
|
|
4375
|
-
await writeFile3(
|
|
4183
|
+
await writeFile3(join8(skillDir, "SKILL.md"), template, "utf-8");
|
|
4376
4184
|
const result = {
|
|
4377
4185
|
name: skillName,
|
|
4378
4186
|
directory: skillDir,
|
|
@@ -4383,20 +4191,18 @@ Show example inputs and expected outputs.
|
|
|
4383
4191
|
outputSuccess(operation, mvi, result);
|
|
4384
4192
|
return;
|
|
4385
4193
|
}
|
|
4386
|
-
console.log(
|
|
4387
|
-
console.log(
|
|
4388
|
-
console.log(
|
|
4389
|
-
console.log(
|
|
4390
|
-
console.log(
|
|
4194
|
+
console.log(pc10.green(`\u2713 Created skill template: ${skillDir}/SKILL.md`));
|
|
4195
|
+
console.log(pc10.dim("\nNext steps:"));
|
|
4196
|
+
console.log(pc10.dim(" 1. Edit SKILL.md with your instructions"));
|
|
4197
|
+
console.log(pc10.dim(` 2. Validate: caamp skills validate ${join8(skillDir, "SKILL.md")}`));
|
|
4198
|
+
console.log(pc10.dim(` 3. Install: caamp skills install ${skillDir}`));
|
|
4391
4199
|
}
|
|
4392
4200
|
);
|
|
4393
4201
|
}
|
|
4394
4202
|
|
|
4395
4203
|
// src/commands/skills/install.ts
|
|
4396
|
-
import { existsSync as
|
|
4397
|
-
import
|
|
4398
|
-
|
|
4399
|
-
// src/core/skills/trust-gate-adapter.ts
|
|
4204
|
+
import { existsSync as existsSync11 } from "fs";
|
|
4205
|
+
import pc11 from "picocolors";
|
|
4400
4206
|
var cachedCore;
|
|
4401
4207
|
async function resolveCore() {
|
|
4402
4208
|
if (cachedCore !== void 0) return cachedCore;
|
|
@@ -4463,8 +4269,6 @@ async function recordSkillTrustBypass(scan, reason = null) {
|
|
|
4463
4269
|
);
|
|
4464
4270
|
}
|
|
4465
4271
|
}
|
|
4466
|
-
|
|
4467
|
-
// src/commands/skills/install.ts
|
|
4468
4272
|
function registerSkillsInstall(parent) {
|
|
4469
4273
|
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(
|
|
4470
4274
|
"-a, --agent <name>",
|
|
@@ -4513,7 +4317,7 @@ function registerSkillsInstall(parent) {
|
|
|
4513
4317
|
if (providers.length === 0) {
|
|
4514
4318
|
const message = "No target providers found. Use --agent or --all.";
|
|
4515
4319
|
if (format === "json") {
|
|
4516
|
-
|
|
4320
|
+
emitError2(
|
|
4517
4321
|
operation,
|
|
4518
4322
|
mvi,
|
|
4519
4323
|
ErrorCodes.PROVIDER_NOT_FOUND,
|
|
@@ -4521,7 +4325,7 @@ function registerSkillsInstall(parent) {
|
|
|
4521
4325
|
ErrorCategories.NOT_FOUND
|
|
4522
4326
|
);
|
|
4523
4327
|
}
|
|
4524
|
-
console.error(
|
|
4328
|
+
console.error(pc11.red(message));
|
|
4525
4329
|
process.exit(1);
|
|
4526
4330
|
}
|
|
4527
4331
|
if (opts.profile) {
|
|
@@ -4538,7 +4342,7 @@ function registerSkillsInstall(parent) {
|
|
|
4538
4342
|
if (!source) {
|
|
4539
4343
|
const message = "Missing required argument: source";
|
|
4540
4344
|
if (format === "json") {
|
|
4541
|
-
|
|
4345
|
+
emitError2(
|
|
4542
4346
|
operation,
|
|
4543
4347
|
mvi,
|
|
4544
4348
|
ErrorCodes.INVALID_INPUT,
|
|
@@ -4546,14 +4350,14 @@ function registerSkillsInstall(parent) {
|
|
|
4546
4350
|
ErrorCategories.VALIDATION
|
|
4547
4351
|
);
|
|
4548
4352
|
}
|
|
4549
|
-
console.error(
|
|
4353
|
+
console.error(pc11.red(message));
|
|
4550
4354
|
console.log(
|
|
4551
|
-
|
|
4355
|
+
pc11.dim("Usage: caamp skills install <source> or caamp skills install --profile <name>")
|
|
4552
4356
|
);
|
|
4553
4357
|
process.exit(1);
|
|
4554
4358
|
}
|
|
4555
4359
|
if (format === "human") {
|
|
4556
|
-
console.log(
|
|
4360
|
+
console.log(pc11.dim(`Installing to ${providers.length} provider(s)...`));
|
|
4557
4361
|
}
|
|
4558
4362
|
let localPath;
|
|
4559
4363
|
let cleanup;
|
|
@@ -4599,7 +4403,7 @@ function registerSkillsInstall(parent) {
|
|
|
4599
4403
|
ErrorCategories.TRANSIENT
|
|
4600
4404
|
);
|
|
4601
4405
|
}
|
|
4602
|
-
console.error(
|
|
4406
|
+
console.error(pc11.red(message));
|
|
4603
4407
|
process.exit(1);
|
|
4604
4408
|
}
|
|
4605
4409
|
} else if (parsed.type === "gitlab" && parsed.owner && parsed.repo) {
|
|
@@ -4623,7 +4427,7 @@ function registerSkillsInstall(parent) {
|
|
|
4623
4427
|
ErrorCategories.TRANSIENT
|
|
4624
4428
|
);
|
|
4625
4429
|
}
|
|
4626
|
-
console.error(
|
|
4430
|
+
console.error(pc11.red(message));
|
|
4627
4431
|
process.exit(1);
|
|
4628
4432
|
}
|
|
4629
4433
|
} else if (parsed.type === "local") {
|
|
@@ -4644,7 +4448,7 @@ function registerSkillsInstall(parent) {
|
|
|
4644
4448
|
ErrorCategories.VALIDATION
|
|
4645
4449
|
);
|
|
4646
4450
|
}
|
|
4647
|
-
console.error(
|
|
4451
|
+
console.error(pc11.red(message));
|
|
4648
4452
|
process.exit(1);
|
|
4649
4453
|
}
|
|
4650
4454
|
const catalogSkill = getSkill(parsed.inferredName);
|
|
@@ -4655,7 +4459,7 @@ function registerSkillsInstall(parent) {
|
|
|
4655
4459
|
sourceType = "library";
|
|
4656
4460
|
if (format === "human") {
|
|
4657
4461
|
console.log(
|
|
4658
|
-
` Found in catalog: ${
|
|
4462
|
+
` Found in catalog: ${pc11.bold(catalogSkill.name)} v${catalogSkill.version} (${pc11.dim(catalogSkill.category)})`
|
|
4659
4463
|
);
|
|
4660
4464
|
}
|
|
4661
4465
|
} else {
|
|
@@ -4672,8 +4476,8 @@ function registerSkillsInstall(parent) {
|
|
|
4672
4476
|
}
|
|
4673
4477
|
);
|
|
4674
4478
|
}
|
|
4675
|
-
console.error(
|
|
4676
|
-
console.log(
|
|
4479
|
+
console.error(pc11.red(message));
|
|
4480
|
+
console.log(pc11.dim("Available skills: " + listSkills().join(", ")));
|
|
4677
4481
|
process.exit(1);
|
|
4678
4482
|
}
|
|
4679
4483
|
} else {
|
|
@@ -4687,7 +4491,7 @@ function registerSkillsInstall(parent) {
|
|
|
4687
4491
|
ErrorCategories.VALIDATION
|
|
4688
4492
|
);
|
|
4689
4493
|
}
|
|
4690
|
-
console.error(
|
|
4494
|
+
console.error(pc11.red(message));
|
|
4691
4495
|
process.exit(1);
|
|
4692
4496
|
}
|
|
4693
4497
|
}
|
|
@@ -4703,7 +4507,7 @@ function registerSkillsInstall(parent) {
|
|
|
4703
4507
|
ErrorCategories.INTERNAL
|
|
4704
4508
|
);
|
|
4705
4509
|
}
|
|
4706
|
-
console.error(
|
|
4510
|
+
console.error(pc11.red(message));
|
|
4707
4511
|
process.exit(1);
|
|
4708
4512
|
}
|
|
4709
4513
|
if (sourceType !== "library" && sourceType !== "package") {
|
|
@@ -4726,7 +4530,7 @@ function registerSkillsInstall(parent) {
|
|
|
4726
4530
|
}
|
|
4727
4531
|
);
|
|
4728
4532
|
}
|
|
4729
|
-
console.error(
|
|
4533
|
+
console.error(pc11.red(message));
|
|
4730
4534
|
process.exit(1);
|
|
4731
4535
|
}
|
|
4732
4536
|
if (fedGate.decision === "prompt-first-install") {
|
|
@@ -4741,7 +4545,7 @@ function registerSkillsInstall(parent) {
|
|
|
4741
4545
|
{ peer: fedGate.peer?.url ?? null }
|
|
4742
4546
|
);
|
|
4743
4547
|
}
|
|
4744
|
-
console.error(
|
|
4548
|
+
console.error(pc11.yellow(message));
|
|
4745
4549
|
process.exit(1);
|
|
4746
4550
|
}
|
|
4747
4551
|
}
|
|
@@ -4769,16 +4573,16 @@ function registerSkillsInstall(parent) {
|
|
|
4769
4573
|
);
|
|
4770
4574
|
console.error(JSON.stringify(envelope, null, 2));
|
|
4771
4575
|
} else {
|
|
4772
|
-
console.error(
|
|
4576
|
+
console.error(pc11.red(`
|
|
4773
4577
|
${message}`));
|
|
4774
4578
|
for (const f of gate.scan.findings.slice(0, 5)) {
|
|
4775
4579
|
console.error(
|
|
4776
|
-
|
|
4580
|
+
pc11.dim(
|
|
4777
4581
|
` [${f.severity}] ${f.category} ${f.file}:${f.line} \u2014 ${f.description}`
|
|
4778
4582
|
)
|
|
4779
4583
|
);
|
|
4780
4584
|
}
|
|
4781
|
-
console.error(
|
|
4585
|
+
console.error(pc11.yellow(" Use --force to override (audited)."));
|
|
4782
4586
|
}
|
|
4783
4587
|
process.exit(1);
|
|
4784
4588
|
}
|
|
@@ -4793,7 +4597,7 @@ ${message}`));
|
|
|
4793
4597
|
ErrorCategories.VALIDATION
|
|
4794
4598
|
);
|
|
4795
4599
|
}
|
|
4796
|
-
console.error(
|
|
4600
|
+
console.error(pc11.red(message));
|
|
4797
4601
|
process.exit(1);
|
|
4798
4602
|
}
|
|
4799
4603
|
if (opts.force === true && gate.scan.verdict !== "safe") {
|
|
@@ -4835,14 +4639,14 @@ ${message}`));
|
|
|
4835
4639
|
if (format === "json") {
|
|
4836
4640
|
outputSuccess(operation, mvi, summary);
|
|
4837
4641
|
} else {
|
|
4838
|
-
console.log(
|
|
4839
|
-
\u2713 Installed ${
|
|
4840
|
-
console.log(` Canonical: ${
|
|
4642
|
+
console.log(pc11.green(`
|
|
4643
|
+
\u2713 Installed ${pc11.bold(skillName)}`));
|
|
4644
|
+
console.log(` Canonical: ${pc11.dim(result.canonicalPath)}`);
|
|
4841
4645
|
console.log(` Linked to: ${result.linkedAgents.join(", ")}`);
|
|
4842
4646
|
if (result.errors.length > 0) {
|
|
4843
|
-
console.log(
|
|
4647
|
+
console.log(pc11.yellow("\nWarnings:"));
|
|
4844
4648
|
for (const err of result.errors) {
|
|
4845
|
-
console.log(` ${
|
|
4649
|
+
console.log(` ${pc11.yellow("!")} ${err}`);
|
|
4846
4650
|
}
|
|
4847
4651
|
}
|
|
4848
4652
|
}
|
|
@@ -4872,11 +4676,11 @@ ${message}`));
|
|
|
4872
4676
|
});
|
|
4873
4677
|
console.error(JSON.stringify(envelope, null, 2));
|
|
4874
4678
|
} else {
|
|
4875
|
-
console.log(
|
|
4876
|
-
\u2717 Failed to install ${
|
|
4877
|
-
console.log(
|
|
4679
|
+
console.log(pc11.yellow(`
|
|
4680
|
+
\u2717 Failed to install ${pc11.bold(skillName)}`));
|
|
4681
|
+
console.log(pc11.yellow("Errors:"));
|
|
4878
4682
|
for (const err of result.errors) {
|
|
4879
|
-
console.log(` ${
|
|
4683
|
+
console.log(` ${pc11.yellow("!")} ${err}`);
|
|
4880
4684
|
}
|
|
4881
4685
|
}
|
|
4882
4686
|
process.exit(1);
|
|
@@ -4891,9 +4695,9 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4891
4695
|
if (!isCatalogAvailable()) {
|
|
4892
4696
|
const message = "No skill library registered. Register one with registerSkillLibraryFromPath() or set CAAMP_SKILL_LIBRARY env var.";
|
|
4893
4697
|
if (format === "json") {
|
|
4894
|
-
|
|
4698
|
+
emitError2(operation, mvi, ErrorCodes.INVALID_INPUT, message, ErrorCategories.VALIDATION);
|
|
4895
4699
|
}
|
|
4896
|
-
console.error(
|
|
4700
|
+
console.error(pc11.red(message));
|
|
4897
4701
|
process.exit(1);
|
|
4898
4702
|
}
|
|
4899
4703
|
const profileSkills = resolveProfile(profileName);
|
|
@@ -4911,16 +4715,16 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4911
4715
|
}
|
|
4912
4716
|
);
|
|
4913
4717
|
}
|
|
4914
|
-
console.error(
|
|
4718
|
+
console.error(pc11.red(message));
|
|
4915
4719
|
const available = listProfiles();
|
|
4916
4720
|
if (available.length > 0) {
|
|
4917
|
-
console.log(
|
|
4721
|
+
console.log(pc11.dim("Available profiles: " + available.join(", ")));
|
|
4918
4722
|
}
|
|
4919
4723
|
process.exit(1);
|
|
4920
4724
|
}
|
|
4921
4725
|
if (format === "human") {
|
|
4922
|
-
console.log(`Installing profile ${
|
|
4923
|
-
console.log(
|
|
4726
|
+
console.log(`Installing profile ${pc11.bold(profileName)} (${profileSkills.length} skill(s))...`);
|
|
4727
|
+
console.log(pc11.dim(`Target: ${providers.length} provider(s)`));
|
|
4924
4728
|
}
|
|
4925
4729
|
const installed = [];
|
|
4926
4730
|
const failed = [];
|
|
@@ -4930,7 +4734,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4930
4734
|
const result = await dispatchInstallSkillAcrossProviders(skillDir, name, providers, isGlobal);
|
|
4931
4735
|
if (result.success) {
|
|
4932
4736
|
if (format === "human") {
|
|
4933
|
-
console.log(
|
|
4737
|
+
console.log(pc11.green(` + ${name}`));
|
|
4934
4738
|
}
|
|
4935
4739
|
await recordSkillInstall(
|
|
4936
4740
|
name,
|
|
@@ -4949,7 +4753,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4949
4753
|
});
|
|
4950
4754
|
} else {
|
|
4951
4755
|
if (format === "human") {
|
|
4952
|
-
console.log(
|
|
4756
|
+
console.log(pc11.yellow(` ! ${name}: ${result.errors.join(", ")}`));
|
|
4953
4757
|
}
|
|
4954
4758
|
failed.push({
|
|
4955
4759
|
name,
|
|
@@ -4959,7 +4763,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4959
4763
|
} catch (err) {
|
|
4960
4764
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
4961
4765
|
if (format === "human") {
|
|
4962
|
-
console.log(
|
|
4766
|
+
console.log(pc11.red(` x ${name}: ${errorMsg}`));
|
|
4963
4767
|
}
|
|
4964
4768
|
failed.push({
|
|
4965
4769
|
name,
|
|
@@ -4994,7 +4798,7 @@ async function handleProfileInstall(profileName, providers, isGlobal, format, op
|
|
|
4994
4798
|
} else {
|
|
4995
4799
|
console.log(
|
|
4996
4800
|
`
|
|
4997
|
-
${
|
|
4801
|
+
${pc11.green(`${installed.length} installed`)}, ${failed.length > 0 ? pc11.yellow(`${failed.length} failed`) : "0 failed"}`
|
|
4998
4802
|
);
|
|
4999
4803
|
if (failed.length > 0) {
|
|
5000
4804
|
process.exit(1);
|
|
@@ -5003,7 +4807,7 @@ ${pc12.green(`${installed.length} installed`)}, ${failed.length > 0 ? pc12.yello
|
|
|
5003
4807
|
}
|
|
5004
4808
|
async function handleMarketplaceSource(source, _providers, _isGlobal, format, operation, mvi) {
|
|
5005
4809
|
if (format === "human") {
|
|
5006
|
-
console.log(
|
|
4810
|
+
console.log(pc11.dim(`Searching marketplace for ${source}...`));
|
|
5007
4811
|
}
|
|
5008
4812
|
const client = new MarketplaceClient();
|
|
5009
4813
|
let skill;
|
|
@@ -5014,7 +4818,7 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
5014
4818
|
if (format === "json") {
|
|
5015
4819
|
emitJsonError(operation, mvi, ErrorCodes.NETWORK_ERROR, message, ErrorCategories.TRANSIENT);
|
|
5016
4820
|
}
|
|
5017
|
-
console.error(
|
|
4821
|
+
console.error(pc11.red(message));
|
|
5018
4822
|
return { success: false };
|
|
5019
4823
|
}
|
|
5020
4824
|
if (!skill) {
|
|
@@ -5022,12 +4826,12 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
5022
4826
|
if (format === "json") {
|
|
5023
4827
|
emitJsonError(operation, mvi, ErrorCodes.SKILL_NOT_FOUND, message, ErrorCategories.NOT_FOUND);
|
|
5024
4828
|
}
|
|
5025
|
-
console.error(
|
|
4829
|
+
console.error(pc11.red(message));
|
|
5026
4830
|
return { success: false };
|
|
5027
4831
|
}
|
|
5028
4832
|
if (format === "human") {
|
|
5029
4833
|
console.log(
|
|
5030
|
-
` Found: ${
|
|
4834
|
+
` Found: ${pc11.bold(skill.name)} by ${skill.author} (${pc11.dim(skill.repoFullName)})`
|
|
5031
4835
|
);
|
|
5032
4836
|
}
|
|
5033
4837
|
const parsed = parseSource(skill.githubUrl);
|
|
@@ -5036,7 +4840,7 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
5036
4840
|
if (format === "json") {
|
|
5037
4841
|
emitJsonError(operation, mvi, ErrorCodes.INVALID_FORMAT, message, ErrorCategories.VALIDATION);
|
|
5038
4842
|
}
|
|
5039
|
-
console.error(
|
|
4843
|
+
console.error(pc11.red(message));
|
|
5040
4844
|
return { success: false };
|
|
5041
4845
|
}
|
|
5042
4846
|
try {
|
|
@@ -5048,7 +4852,7 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
5048
4852
|
for (const subPath of subPathCandidates) {
|
|
5049
4853
|
try {
|
|
5050
4854
|
const result = await cloneRepo(parsed.owner, parsed.repo, parsed.ref, subPath);
|
|
5051
|
-
if (subPath && !
|
|
4855
|
+
if (subPath && !existsSync11(result.localPath)) {
|
|
5052
4856
|
await result.cleanup();
|
|
5053
4857
|
continue;
|
|
5054
4858
|
}
|
|
@@ -5076,22 +4880,22 @@ async function handleMarketplaceSource(source, _providers, _isGlobal, format, op
|
|
|
5076
4880
|
if (format === "json") {
|
|
5077
4881
|
emitJsonError(operation, mvi, ErrorCodes.NETWORK_ERROR, message, ErrorCategories.TRANSIENT);
|
|
5078
4882
|
}
|
|
5079
|
-
console.error(
|
|
4883
|
+
console.error(pc11.red(message));
|
|
5080
4884
|
return { success: false };
|
|
5081
4885
|
}
|
|
5082
4886
|
}
|
|
5083
4887
|
|
|
5084
4888
|
// src/commands/skills/list.ts
|
|
5085
|
-
import { randomUUID as
|
|
5086
|
-
import { resolveOutputFormat as
|
|
5087
|
-
import
|
|
4889
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
4890
|
+
import { resolveOutputFormat as resolveOutputFormat4 } from "@cleocode/lafs";
|
|
4891
|
+
import pc12 from "picocolors";
|
|
5088
4892
|
function registerSkillsList(parent) {
|
|
5089
4893
|
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) => {
|
|
5090
4894
|
const operation = "skills.list";
|
|
5091
4895
|
const mvi = "standard";
|
|
5092
4896
|
let format;
|
|
5093
4897
|
try {
|
|
5094
|
-
format =
|
|
4898
|
+
format = resolveOutputFormat4({
|
|
5095
4899
|
jsonFlag: opts.json ?? false,
|
|
5096
4900
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
5097
4901
|
projectDefault: "json"
|
|
@@ -5111,7 +4915,7 @@ function registerSkillsList(parent) {
|
|
|
5111
4915
|
agent: opts.agent
|
|
5112
4916
|
});
|
|
5113
4917
|
} else {
|
|
5114
|
-
console.error(
|
|
4918
|
+
console.error(pc12.red(message));
|
|
5115
4919
|
}
|
|
5116
4920
|
process.exit(1);
|
|
5117
4921
|
}
|
|
@@ -5139,21 +4943,21 @@ function registerSkillsList(parent) {
|
|
|
5139
4943
|
return;
|
|
5140
4944
|
}
|
|
5141
4945
|
if (skills.length === 0) {
|
|
5142
|
-
console.log(
|
|
4946
|
+
console.log(pc12.dim("No skills found."));
|
|
5143
4947
|
return;
|
|
5144
4948
|
}
|
|
5145
|
-
console.log(
|
|
4949
|
+
console.log(pc12.bold(`
|
|
5146
4950
|
${skills.length} skill(s) found:
|
|
5147
4951
|
`));
|
|
5148
4952
|
skills.forEach((skill, index) => {
|
|
5149
4953
|
const num = (index + 1).toString().padStart(2);
|
|
5150
4954
|
console.log(
|
|
5151
|
-
` ${
|
|
4955
|
+
` ${pc12.cyan(num)}. ${pc12.bold(skill.name.padEnd(30))} ${pc12.dim(skill.metadata?.description ?? "")}`
|
|
5152
4956
|
);
|
|
5153
4957
|
});
|
|
5154
|
-
console.log(
|
|
4958
|
+
console.log(pc12.dim(`
|
|
5155
4959
|
Install with: caamp skills install <name>`));
|
|
5156
|
-
console.log(
|
|
4960
|
+
console.log(pc12.dim(`Remove with: caamp skills remove <name>`));
|
|
5157
4961
|
});
|
|
5158
4962
|
}
|
|
5159
4963
|
function buildEnvelope4(operation, mvi, result, error) {
|
|
@@ -5164,7 +4968,7 @@ function buildEnvelope4(operation, mvi, result, error) {
|
|
|
5164
4968
|
schemaVersion: "1.0.0",
|
|
5165
4969
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5166
4970
|
operation,
|
|
5167
|
-
requestId:
|
|
4971
|
+
requestId: randomUUID5(),
|
|
5168
4972
|
transport: "cli",
|
|
5169
4973
|
strict: true,
|
|
5170
4974
|
mvi,
|
|
@@ -5189,7 +4993,7 @@ function emitJsonError4(operation, mvi, code, message, category, details = {}) {
|
|
|
5189
4993
|
}
|
|
5190
4994
|
|
|
5191
4995
|
// src/commands/skills/remove.ts
|
|
5192
|
-
import
|
|
4996
|
+
import pc13 from "picocolors";
|
|
5193
4997
|
function registerSkillsRemove(parent) {
|
|
5194
4998
|
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(
|
|
5195
4999
|
async (name, opts) => {
|
|
@@ -5239,14 +5043,14 @@ function registerSkillsRemove(parent) {
|
|
|
5239
5043
|
return;
|
|
5240
5044
|
}
|
|
5241
5045
|
if (removed.length > 0) {
|
|
5242
|
-
console.log(
|
|
5046
|
+
console.log(pc13.green(`\u2713 Removed ${pc13.bold(name)} from: ${removed.join(", ")}`));
|
|
5243
5047
|
await removeSkillFromLock(name);
|
|
5244
5048
|
} else {
|
|
5245
|
-
console.log(
|
|
5049
|
+
console.log(pc13.yellow(`Skill ${name} not found in any provider.`));
|
|
5246
5050
|
}
|
|
5247
5051
|
if (result.errors.length > 0) {
|
|
5248
5052
|
for (const err of result.errors) {
|
|
5249
|
-
console.log(
|
|
5053
|
+
console.log(pc13.red(` ${err}`));
|
|
5250
5054
|
}
|
|
5251
5055
|
}
|
|
5252
5056
|
} else {
|
|
@@ -5259,7 +5063,7 @@ function registerSkillsRemove(parent) {
|
|
|
5259
5063
|
count: { removed: 0, total: 0 }
|
|
5260
5064
|
});
|
|
5261
5065
|
} else {
|
|
5262
|
-
console.log(
|
|
5066
|
+
console.log(pc13.dim("No skills installed."));
|
|
5263
5067
|
}
|
|
5264
5068
|
return;
|
|
5265
5069
|
}
|
|
@@ -5272,18 +5076,18 @@ function registerSkillsRemove(parent) {
|
|
|
5272
5076
|
});
|
|
5273
5077
|
return;
|
|
5274
5078
|
}
|
|
5275
|
-
console.log(
|
|
5079
|
+
console.log(pc13.bold("Installed skills:"));
|
|
5276
5080
|
for (const s of skills) {
|
|
5277
5081
|
console.log(` ${s}`);
|
|
5278
5082
|
}
|
|
5279
|
-
console.log(
|
|
5083
|
+
console.log(pc13.dim("\nUse: caamp skills remove <name>"));
|
|
5280
5084
|
}
|
|
5281
5085
|
}
|
|
5282
5086
|
);
|
|
5283
5087
|
}
|
|
5284
5088
|
|
|
5285
5089
|
// src/commands/skills/update.ts
|
|
5286
|
-
import
|
|
5090
|
+
import pc14 from "picocolors";
|
|
5287
5091
|
function registerSkillsUpdate(parent) {
|
|
5288
5092
|
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) => {
|
|
5289
5093
|
const operation = "skills.update";
|
|
@@ -5317,12 +5121,12 @@ function registerSkillsUpdate(parent) {
|
|
|
5317
5121
|
count: { updated: 0, failed: 0, skipped: 0 }
|
|
5318
5122
|
});
|
|
5319
5123
|
} else {
|
|
5320
|
-
console.log(
|
|
5124
|
+
console.log(pc14.dim("No tracked skills to update."));
|
|
5321
5125
|
}
|
|
5322
5126
|
return;
|
|
5323
5127
|
}
|
|
5324
5128
|
if (format === "human") {
|
|
5325
|
-
console.log(
|
|
5129
|
+
console.log(pc14.dim(`Checking ${entries.length} skill(s) for updates...`));
|
|
5326
5130
|
}
|
|
5327
5131
|
const outdated = [];
|
|
5328
5132
|
for (const [name] of entries) {
|
|
@@ -5344,19 +5148,19 @@ function registerSkillsUpdate(parent) {
|
|
|
5344
5148
|
count: { updated: 0, failed: 0, skipped: 0 }
|
|
5345
5149
|
});
|
|
5346
5150
|
} else {
|
|
5347
|
-
console.log(
|
|
5151
|
+
console.log(pc14.green("\nAll skills are up to date."));
|
|
5348
5152
|
}
|
|
5349
5153
|
return;
|
|
5350
5154
|
}
|
|
5351
5155
|
if (format === "human") {
|
|
5352
|
-
console.log(
|
|
5156
|
+
console.log(pc14.yellow(`
|
|
5353
5157
|
${outdated.length} skill(s) have updates available:
|
|
5354
5158
|
`));
|
|
5355
5159
|
for (const skill of outdated) {
|
|
5356
5160
|
const current = skill.currentVersion?.slice(0, 12) ?? "?";
|
|
5357
5161
|
const latest = skill.latestVersion ?? "?";
|
|
5358
5162
|
console.log(
|
|
5359
|
-
` ${
|
|
5163
|
+
` ${pc14.bold(skill.name)} ${pc14.dim(current)} ${pc14.dim("->")} ${pc14.cyan(latest)}`
|
|
5360
5164
|
);
|
|
5361
5165
|
}
|
|
5362
5166
|
}
|
|
@@ -5364,11 +5168,11 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5364
5168
|
const readline = await import("readline");
|
|
5365
5169
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
5366
5170
|
const answer = await new Promise((resolve3) => {
|
|
5367
|
-
rl.question(
|
|
5171
|
+
rl.question(pc14.dim("\nProceed with update? [y/N] "), resolve3);
|
|
5368
5172
|
});
|
|
5369
5173
|
rl.close();
|
|
5370
5174
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
5371
|
-
console.log(
|
|
5175
|
+
console.log(pc14.dim("Update cancelled."));
|
|
5372
5176
|
return;
|
|
5373
5177
|
}
|
|
5374
5178
|
}
|
|
@@ -5382,7 +5186,7 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5382
5186
|
const entry = tracked[skill.name];
|
|
5383
5187
|
if (!entry) continue;
|
|
5384
5188
|
if (format === "human") {
|
|
5385
|
-
console.log(
|
|
5189
|
+
console.log(pc14.dim(`Updating ${pc14.bold(skill.name)}...`));
|
|
5386
5190
|
}
|
|
5387
5191
|
try {
|
|
5388
5192
|
const parsed = parseSource(entry.source);
|
|
@@ -5404,7 +5208,7 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5404
5208
|
} else {
|
|
5405
5209
|
if (format === "human") {
|
|
5406
5210
|
console.log(
|
|
5407
|
-
|
|
5211
|
+
pc14.yellow(
|
|
5408
5212
|
` Skipped ${skill.name}: source type "${parsed.type}" does not support auto-update`
|
|
5409
5213
|
)
|
|
5410
5214
|
);
|
|
@@ -5416,7 +5220,7 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5416
5220
|
const providers = entry.agents.map((a) => getProvider(a)).filter((p) => p !== void 0);
|
|
5417
5221
|
if (providers.length === 0) {
|
|
5418
5222
|
if (format === "human") {
|
|
5419
|
-
console.log(
|
|
5223
|
+
console.log(pc14.yellow(` Skipped ${skill.name}: no valid providers found`));
|
|
5420
5224
|
}
|
|
5421
5225
|
skipped.push(skill.name);
|
|
5422
5226
|
continue;
|
|
@@ -5441,18 +5245,18 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5441
5245
|
skill.latestVersion
|
|
5442
5246
|
);
|
|
5443
5247
|
if (format === "human") {
|
|
5444
|
-
console.log(
|
|
5248
|
+
console.log(pc14.green(` Updated ${pc14.bold(skill.name)}`));
|
|
5445
5249
|
}
|
|
5446
5250
|
updated.push(skill.name);
|
|
5447
5251
|
} else {
|
|
5448
5252
|
if (format === "human") {
|
|
5449
|
-
console.log(
|
|
5253
|
+
console.log(pc14.red(` Failed to update ${skill.name}: no agents linked`));
|
|
5450
5254
|
}
|
|
5451
5255
|
failed.push({ name: skill.name, error: "no agents linked" });
|
|
5452
5256
|
}
|
|
5453
5257
|
if (installResult.errors.length > 0 && format === "human") {
|
|
5454
5258
|
for (const err of installResult.errors) {
|
|
5455
|
-
console.log(
|
|
5259
|
+
console.log(pc14.yellow(` ${err}`));
|
|
5456
5260
|
}
|
|
5457
5261
|
}
|
|
5458
5262
|
} finally {
|
|
@@ -5461,7 +5265,7 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5461
5265
|
} catch (err) {
|
|
5462
5266
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5463
5267
|
if (format === "human") {
|
|
5464
|
-
console.log(
|
|
5268
|
+
console.log(pc14.red(` Failed to update ${skill.name}: ${msg}`));
|
|
5465
5269
|
}
|
|
5466
5270
|
failed.push({ name: skill.name, error: msg });
|
|
5467
5271
|
}
|
|
@@ -5481,24 +5285,24 @@ ${outdated.length} skill(s) have updates available:
|
|
|
5481
5285
|
}
|
|
5482
5286
|
console.log();
|
|
5483
5287
|
if (updated.length > 0) {
|
|
5484
|
-
console.log(
|
|
5288
|
+
console.log(pc14.green(`Updated ${updated.length} skill(s).`));
|
|
5485
5289
|
}
|
|
5486
5290
|
if (failed.length > 0) {
|
|
5487
|
-
console.log(
|
|
5291
|
+
console.log(pc14.red(`Failed to update ${failed.length} skill(s).`));
|
|
5488
5292
|
}
|
|
5489
5293
|
});
|
|
5490
5294
|
}
|
|
5491
5295
|
|
|
5492
5296
|
// src/commands/skills/validate.ts
|
|
5493
|
-
import { resolveOutputFormat as
|
|
5494
|
-
import
|
|
5297
|
+
import { resolveOutputFormat as resolveOutputFormat5 } from "@cleocode/lafs";
|
|
5298
|
+
import pc15 from "picocolors";
|
|
5495
5299
|
function registerSkillsValidate(parent) {
|
|
5496
5300
|
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) => {
|
|
5497
5301
|
const operation = "skills.validate";
|
|
5498
5302
|
const mvi = "standard";
|
|
5499
5303
|
let format;
|
|
5500
5304
|
try {
|
|
5501
|
-
format =
|
|
5305
|
+
format = resolveOutputFormat5({
|
|
5502
5306
|
jsonFlag: opts.json ?? false,
|
|
5503
5307
|
humanFlag: (opts.human ?? false) || isHuman(),
|
|
5504
5308
|
projectDefault: "json"
|
|
@@ -5531,7 +5335,7 @@ function registerSkillsValidate(parent) {
|
|
|
5531
5335
|
}
|
|
5532
5336
|
);
|
|
5533
5337
|
} else {
|
|
5534
|
-
console.error(
|
|
5338
|
+
console.error(pc15.red(message));
|
|
5535
5339
|
}
|
|
5536
5340
|
process.exit(1);
|
|
5537
5341
|
}
|
|
@@ -5553,12 +5357,12 @@ function registerSkillsValidate(parent) {
|
|
|
5553
5357
|
console.log(JSON.stringify(envelope, null, 2));
|
|
5554
5358
|
} else {
|
|
5555
5359
|
if (result.valid) {
|
|
5556
|
-
console.log(
|
|
5360
|
+
console.log(pc15.green(`\u2713 ${path} is valid`));
|
|
5557
5361
|
} else {
|
|
5558
|
-
console.log(
|
|
5362
|
+
console.log(pc15.red(`\u2717 ${path} has validation errors`));
|
|
5559
5363
|
}
|
|
5560
5364
|
for (const issue of result.issues) {
|
|
5561
|
-
const icon = issue.level === "error" ?
|
|
5365
|
+
const icon = issue.level === "error" ? pc15.red("\u2717") : pc15.yellow("!");
|
|
5562
5366
|
console.log(` ${icon} [${issue.field}] ${issue.message}`);
|
|
5563
5367
|
}
|
|
5564
5368
|
}
|
|
@@ -5580,9 +5384,6 @@ function registerSkillsCommands(program2) {
|
|
|
5580
5384
|
registerSkillsInit(skills);
|
|
5581
5385
|
registerSkillsAudit(skills);
|
|
5582
5386
|
registerSkillsValidate(skills);
|
|
5583
|
-
registerSkillsDoctorMigrate(skills);
|
|
5584
|
-
registerSkillsDoctor(skills);
|
|
5585
|
-
registerSkillsDoctorAdopt(skills);
|
|
5586
5387
|
}
|
|
5587
5388
|
|
|
5588
5389
|
// src/cli.ts
|