@cleocode/caamp 2026.5.84 → 2026.5.86
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-QSJSM57K.js → chunk-WXL7RPS4.js} +435 -47
- package/dist/chunk-WXL7RPS4.js.map +1 -0
- package/dist/cli.js +173 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +333 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-QSJSM57K.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
recommendSkills,
|
|
45
45
|
recordSkillInstall,
|
|
46
46
|
registerDoctorBridge,
|
|
47
|
+
registerSkillsDoctorAdopt,
|
|
47
48
|
removeMcpServer,
|
|
48
49
|
removeMcpServerFromAll,
|
|
49
50
|
removeSkillFromLock,
|
|
@@ -60,7 +61,7 @@ import {
|
|
|
60
61
|
tokenizeCriteriaValue,
|
|
61
62
|
updateInstructionsSingleOperation,
|
|
62
63
|
validateSkill
|
|
63
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-WXL7RPS4.js";
|
|
64
65
|
import {
|
|
65
66
|
buildSkillsMap,
|
|
66
67
|
checkAllInjections,
|
|
@@ -4394,6 +4395,76 @@ Show example inputs and expected outputs.
|
|
|
4394
4395
|
// src/commands/skills/install.ts
|
|
4395
4396
|
import { existsSync as existsSync12 } from "fs";
|
|
4396
4397
|
import pc12 from "picocolors";
|
|
4398
|
+
|
|
4399
|
+
// src/core/skills/trust-gate-adapter.ts
|
|
4400
|
+
var cachedCore;
|
|
4401
|
+
async function resolveCore() {
|
|
4402
|
+
if (cachedCore !== void 0) return cachedCore;
|
|
4403
|
+
try {
|
|
4404
|
+
const mod = await import("@cleocode/core");
|
|
4405
|
+
cachedCore = mod;
|
|
4406
|
+
} catch {
|
|
4407
|
+
cachedCore = null;
|
|
4408
|
+
process.stderr.write(
|
|
4409
|
+
"[caamp] WARNING: @cleocode/core unavailable \u2014 skipping trust gate (skill installs not security-checked)\n"
|
|
4410
|
+
);
|
|
4411
|
+
}
|
|
4412
|
+
return cachedCore;
|
|
4413
|
+
}
|
|
4414
|
+
async function evaluateSkillTrustGate(localPath, source, force = false) {
|
|
4415
|
+
const core = await resolveCore();
|
|
4416
|
+
if (!core) {
|
|
4417
|
+
return {
|
|
4418
|
+
decision: "allow",
|
|
4419
|
+
reason: "Trust gate skipped \u2014 @cleocode/core not available",
|
|
4420
|
+
scan: {
|
|
4421
|
+
skillName: localPath.split("/").filter(Boolean).pop() ?? localPath,
|
|
4422
|
+
source,
|
|
4423
|
+
trustLevel: "community",
|
|
4424
|
+
verdict: "safe",
|
|
4425
|
+
findings: [],
|
|
4426
|
+
scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4427
|
+
summary: "core-unavailable"
|
|
4428
|
+
}
|
|
4429
|
+
};
|
|
4430
|
+
}
|
|
4431
|
+
const scan = core.scanSkill(localPath, source);
|
|
4432
|
+
const gate = core.shouldAllowInstall(scan, force);
|
|
4433
|
+
return { decision: gate.decision, reason: gate.reason, scan };
|
|
4434
|
+
}
|
|
4435
|
+
async function evaluateFederationGate(source, opts = {}) {
|
|
4436
|
+
const core = await resolveCore();
|
|
4437
|
+
if (!core) {
|
|
4438
|
+
return {
|
|
4439
|
+
decision: "allow",
|
|
4440
|
+
reason: "Federation gate skipped \u2014 @cleocode/core not available",
|
|
4441
|
+
peer: null,
|
|
4442
|
+
isFederationSource: false,
|
|
4443
|
+
computedChecksum: null,
|
|
4444
|
+
expectedChecksum: null
|
|
4445
|
+
};
|
|
4446
|
+
}
|
|
4447
|
+
return core.evaluateFederationInstallGate({
|
|
4448
|
+
source,
|
|
4449
|
+
artefactPath: opts.artefactPath,
|
|
4450
|
+
expectedChecksum: opts.expectedChecksum,
|
|
4451
|
+
approveNewSource: opts.approveNewSource
|
|
4452
|
+
});
|
|
4453
|
+
}
|
|
4454
|
+
async function recordSkillTrustBypass(scan, reason = null) {
|
|
4455
|
+
const core = await resolveCore();
|
|
4456
|
+
if (!core) return;
|
|
4457
|
+
try {
|
|
4458
|
+
core.recordTrustBypass(scan, reason);
|
|
4459
|
+
} catch (err) {
|
|
4460
|
+
process.stderr.write(
|
|
4461
|
+
`[caamp] WARNING: failed to record trust-bypass audit row: ${err instanceof Error ? err.message : String(err)}
|
|
4462
|
+
`
|
|
4463
|
+
);
|
|
4464
|
+
}
|
|
4465
|
+
}
|
|
4466
|
+
|
|
4467
|
+
// src/commands/skills/install.ts
|
|
4397
4468
|
function registerSkillsInstall(parent) {
|
|
4398
4469
|
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(
|
|
4399
4470
|
"-a, --agent <name>",
|
|
@@ -4403,6 +4474,12 @@ function registerSkillsInstall(parent) {
|
|
|
4403
4474
|
).option("-g, --global", "Install globally").option("-y, --yes", "Skip confirmation").option("--all", "Install to all detected agents").option(
|
|
4404
4475
|
"--profile <name>",
|
|
4405
4476
|
"Install a skill library profile (minimal, core, recommended, full)"
|
|
4477
|
+
).option(
|
|
4478
|
+
"--force",
|
|
4479
|
+
"Override trust-gate block decisions (audited to .cleo/audit/skill-trust-bypass.jsonl)"
|
|
4480
|
+
).option(
|
|
4481
|
+
"--allow-new-source",
|
|
4482
|
+
"Bypass first-install confirmation prompt for unknown federation sources (non-TTY safe)"
|
|
4406
4483
|
).option("--json", "Output as JSON (default)").option("--human", "Output in human-readable format").action(
|
|
4407
4484
|
async (source, opts) => {
|
|
4408
4485
|
const operation = "skills.install";
|
|
@@ -4629,6 +4706,100 @@ function registerSkillsInstall(parent) {
|
|
|
4629
4706
|
console.error(pc12.red(message));
|
|
4630
4707
|
process.exit(1);
|
|
4631
4708
|
}
|
|
4709
|
+
if (sourceType !== "library" && sourceType !== "package") {
|
|
4710
|
+
const fedGate = await evaluateFederationGate(sourceValue, {
|
|
4711
|
+
artefactPath: localPath,
|
|
4712
|
+
approveNewSource: opts.allowNewSource === true
|
|
4713
|
+
});
|
|
4714
|
+
if (fedGate.decision === "block-checksum") {
|
|
4715
|
+
const message = `Federation install blocked: ${fedGate.reason}`;
|
|
4716
|
+
if (format === "json") {
|
|
4717
|
+
emitJsonError(
|
|
4718
|
+
operation,
|
|
4719
|
+
mvi,
|
|
4720
|
+
ErrorCodes.FEDERATION_CHECKSUM_MISMATCH,
|
|
4721
|
+
message,
|
|
4722
|
+
ErrorCategories.VALIDATION,
|
|
4723
|
+
{
|
|
4724
|
+
expectedChecksum: fedGate.expectedChecksum,
|
|
4725
|
+
computedChecksum: fedGate.computedChecksum
|
|
4726
|
+
}
|
|
4727
|
+
);
|
|
4728
|
+
}
|
|
4729
|
+
console.error(pc12.red(message));
|
|
4730
|
+
process.exit(1);
|
|
4731
|
+
}
|
|
4732
|
+
if (fedGate.decision === "prompt-first-install") {
|
|
4733
|
+
const message = `${fedGate.reason} Use --allow-new-source to approve in non-interactive contexts.`;
|
|
4734
|
+
if (format === "json") {
|
|
4735
|
+
emitJsonError(
|
|
4736
|
+
operation,
|
|
4737
|
+
mvi,
|
|
4738
|
+
ErrorCodes.FEDERATION_UNKNOWN_SOURCE_INTERACTIVE_REQUIRED,
|
|
4739
|
+
message,
|
|
4740
|
+
ErrorCategories.VALIDATION,
|
|
4741
|
+
{ peer: fedGate.peer?.url ?? null }
|
|
4742
|
+
);
|
|
4743
|
+
}
|
|
4744
|
+
console.error(pc12.yellow(message));
|
|
4745
|
+
process.exit(1);
|
|
4746
|
+
}
|
|
4747
|
+
}
|
|
4748
|
+
if (sourceType !== "library" && sourceType !== "package") {
|
|
4749
|
+
const gate = await evaluateSkillTrustGate(localPath, sourceValue, opts.force ?? false);
|
|
4750
|
+
if (gate.decision === "block") {
|
|
4751
|
+
const message = `Trust gate blocked install: ${gate.reason}`;
|
|
4752
|
+
if (format === "json") {
|
|
4753
|
+
const envelope = buildEnvelope(
|
|
4754
|
+
operation,
|
|
4755
|
+
mvi,
|
|
4756
|
+
{ scan: gate.scan },
|
|
4757
|
+
{
|
|
4758
|
+
code: ErrorCodes.SKILL_TRUST_GATE_BLOCKED,
|
|
4759
|
+
message,
|
|
4760
|
+
category: ErrorCategories.VALIDATION,
|
|
4761
|
+
retryable: false,
|
|
4762
|
+
retryAfterMs: null,
|
|
4763
|
+
details: {
|
|
4764
|
+
verdict: gate.scan.verdict,
|
|
4765
|
+
trustLevel: gate.scan.trustLevel,
|
|
4766
|
+
findingsCount: gate.scan.findings.length
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4769
|
+
);
|
|
4770
|
+
console.error(JSON.stringify(envelope, null, 2));
|
|
4771
|
+
} else {
|
|
4772
|
+
console.error(pc12.red(`
|
|
4773
|
+
${message}`));
|
|
4774
|
+
for (const f of gate.scan.findings.slice(0, 5)) {
|
|
4775
|
+
console.error(
|
|
4776
|
+
pc12.dim(
|
|
4777
|
+
` [${f.severity}] ${f.category} ${f.file}:${f.line} \u2014 ${f.description}`
|
|
4778
|
+
)
|
|
4779
|
+
);
|
|
4780
|
+
}
|
|
4781
|
+
console.error(pc12.yellow(" Use --force to override (audited)."));
|
|
4782
|
+
}
|
|
4783
|
+
process.exit(1);
|
|
4784
|
+
}
|
|
4785
|
+
if (gate.decision === "ask") {
|
|
4786
|
+
const message = `Trust gate requires confirmation: ${gate.reason}`;
|
|
4787
|
+
if (format === "json") {
|
|
4788
|
+
emitJsonError(
|
|
4789
|
+
operation,
|
|
4790
|
+
mvi,
|
|
4791
|
+
ErrorCodes.SKILL_TRUST_GATE_BLOCKED,
|
|
4792
|
+
message,
|
|
4793
|
+
ErrorCategories.VALIDATION
|
|
4794
|
+
);
|
|
4795
|
+
}
|
|
4796
|
+
console.error(pc12.red(message));
|
|
4797
|
+
process.exit(1);
|
|
4798
|
+
}
|
|
4799
|
+
if (opts.force === true && gate.scan.verdict !== "safe") {
|
|
4800
|
+
await recordSkillTrustBypass(gate.scan, "operator --force on caamp skills install");
|
|
4801
|
+
}
|
|
4802
|
+
}
|
|
4632
4803
|
const result = await dispatchInstallSkillAcrossProviders(
|
|
4633
4804
|
localPath,
|
|
4634
4805
|
skillName,
|
|
@@ -5411,6 +5582,7 @@ function registerSkillsCommands(program2) {
|
|
|
5411
5582
|
registerSkillsValidate(skills);
|
|
5412
5583
|
registerSkillsDoctorMigrate(skills);
|
|
5413
5584
|
registerSkillsDoctor(skills);
|
|
5585
|
+
registerSkillsDoctorAdopt(skills);
|
|
5414
5586
|
}
|
|
5415
5587
|
|
|
5416
5588
|
// src/cli.ts
|