@cleocode/caamp 2026.9.19 → 2026.9.20

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/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { PackageArtifactBudgets, PackageArtifactRequirement, PackageArtifactFile
3
3
  import { WorktreeHandle } from '@cleocode/cant';
4
4
  import { PlatformPaths, SystemInfo } from '@cleocode/paths';
5
5
  export { PlatformPaths, SystemInfo } from '@cleocode/paths';
6
+ import { SkillGateScanResult, SkillGatePolicyDecision, SkillGateFederationResult, SkillGateFederationInput } from '@cleocode/contracts';
6
7
 
7
8
  /**
8
9
  * Priority tier identifier stored in registry.json.
@@ -3160,6 +3161,73 @@ declare function withFileLock<T>(targetPath: string, fn: () => Promise<T>, optio
3160
3161
  * @public
3161
3162
  */
3162
3163
  declare function assertNotTornRead(filePath: string, content: string, sizeOnDisk: number): void;
3164
+ /**
3165
+ * A JSON config file could not be parsed, so it was left untouched.
3166
+ *
3167
+ * @remarks
3168
+ * Thrown by {@link updateJsonConfigFile} instead of treating the file as empty.
3169
+ * The pre-T12385 provider adapters caught the parse error and started from
3170
+ * `{}`, so a torn read of `~/.claude/settings.json` (Claude Code rewriting it
3171
+ * at the same moment) replaced the user's permissions, env, model and hooks
3172
+ * with CLEO's entries alone.
3173
+ *
3174
+ * @example
3175
+ * ```typescript
3176
+ * try {
3177
+ * await updateJsonConfigFile(path, (config) => false);
3178
+ * } catch (err) {
3179
+ * if (err instanceof JsonConfigParseError) console.error(err.filePath);
3180
+ * }
3181
+ * ```
3182
+ *
3183
+ * @public
3184
+ */
3185
+ declare class JsonConfigParseError extends Error {
3186
+ /** Path of the file that failed to parse. */
3187
+ readonly filePath: string;
3188
+ /**
3189
+ * @param filePath - Path of the file that failed to parse
3190
+ * @param reason - Parser message
3191
+ */
3192
+ constructor(filePath: string, reason: string);
3193
+ }
3194
+ /**
3195
+ * Read-modify-write a JSON object file under the cross-process lock, writing
3196
+ * atomically, and never replacing an unparseable file.
3197
+ *
3198
+ * @remarks
3199
+ * Composes the two existing primitives — {@link withFileLock} and core's
3200
+ * `writeFileAtomic` — for provider config files such as
3201
+ * `~/.claude/settings.json` that the provider itself also rewrites (T12385):
3202
+ *
3203
+ * - The whole read → mutate → write cycle holds the `<file>.lock` guard, so
3204
+ * two CLEO writers cannot both read the pre-state and clobber each other.
3205
+ * - The write is tmp-then-rename, so a concurrent reader (including the
3206
+ * provider) sees the whole old file or the whole new one.
3207
+ * - A missing file starts from `{}`. A file that exists but is empty on read
3208
+ * while non-empty on disk, is not valid JSON, or is not a JSON object throws
3209
+ * ({@link assertNotTornRead} / {@link JsonConfigParseError}) and the file is
3210
+ * left byte-identical.
3211
+ *
3212
+ * @param filePath - JSON file to update
3213
+ * @param mutate - Edits the parsed object in place; returns `true` when it
3214
+ * changed something that must be written
3215
+ * @returns Whether the file was written
3216
+ * @throws {@link JsonConfigParseError} when the existing file cannot be parsed
3217
+ * as a JSON object; the file is not modified
3218
+ *
3219
+ * @example
3220
+ * ```typescript
3221
+ * const wrote = await updateJsonConfigFile(settingsPath, (settings) => {
3222
+ * if (settings.enabled === true) return false;
3223
+ * settings.enabled = true;
3224
+ * return true;
3225
+ * });
3226
+ * ```
3227
+ *
3228
+ * @public
3229
+ */
3230
+ declare function updateJsonConfigFile(filePath: string, mutate: (config: Record<string, unknown>) => boolean): Promise<boolean>;
3163
3231
 
3164
3232
  /**
3165
3233
  * Skill installer - canonical + symlink model
@@ -3287,6 +3355,76 @@ interface SkillInstallResult {
3287
3355
  /** Whether at least one agent was successfully linked. */
3288
3356
  success: boolean;
3289
3357
  }
3358
+ /**
3359
+ * Move a fully staged entry onto `targetPath` without ever deleting the entry
3360
+ * it replaces before the replacement is in place.
3361
+ *
3362
+ * @remarks
3363
+ * T12383. The previous installer ran `rm -rf <target>` and only then copied
3364
+ * the new source; when the copy failed (for instance because the "source" was
3365
+ * the unresolved string `library:<name>`) the installed skill was gone.
3366
+ *
3367
+ * The swap moves the current entry aside to a hidden sibling, renames the
3368
+ * staged entry into place, then deletes the set-aside copy. If the second
3369
+ * rename fails, the set-aside copy is renamed back, so a failure at any step
3370
+ * leaves the original entry where it was. POSIX offers no portable atomic
3371
+ * exchange of two directories, so the path is absent for the span of one
3372
+ * `rename(2)` — but no step discards data that has not already been superseded
3373
+ * on disk.
3374
+ *
3375
+ * When a concurrent installer occupies the path between the two renames, the
3376
+ * swap retries a bounded number of times; the last writer wins, as before.
3377
+ *
3378
+ * @param stagedPath - A complete replacement, on the same filesystem as `targetPath`
3379
+ * @param targetPath - The path to replace (need not exist)
3380
+ * @throws The underlying filesystem error when the swap cannot complete; the
3381
+ * original entry is restored before the error propagates
3382
+ *
3383
+ * @example
3384
+ * ```typescript
3385
+ * const staged = await stageSkillCopy("/tmp/my-skill", target);
3386
+ * await swapIntoPlace(staged, target);
3387
+ * ```
3388
+ *
3389
+ * @public
3390
+ */
3391
+ declare function swapIntoPlace(stagedPath: string, targetPath: string): Promise<void>;
3392
+ /**
3393
+ * Copy `sourcePath` into a hidden staging sibling of `targetPath`.
3394
+ *
3395
+ * @remarks
3396
+ * Nothing at `targetPath` is touched. If the copy fails the partial staging
3397
+ * directory is removed and the error propagates.
3398
+ *
3399
+ * @param sourcePath - Directory to copy
3400
+ * @param targetPath - Path the staged copy will later replace
3401
+ * @returns Absolute path of the complete staged copy
3402
+ * @throws The copy error (e.g. `ENOENT` when `sourcePath` does not exist)
3403
+ *
3404
+ * @example
3405
+ * ```typescript
3406
+ * const staged = await stageSkillCopy("/tmp/my-skill", "/home/u/.cleo/skills/my-skill");
3407
+ * ```
3408
+ *
3409
+ * @public
3410
+ */
3411
+ declare function stageSkillCopy(sourcePath: string, targetPath: string): Promise<string>;
3412
+ /**
3413
+ * Replace the directory at `targetPath` with a copy of `sourcePath`, staging
3414
+ * the copy completely before anything existing is moved.
3415
+ *
3416
+ * @param sourcePath - Directory to copy
3417
+ * @param targetPath - Directory to replace (need not exist)
3418
+ * @throws When the copy or the swap fails; the existing directory is kept
3419
+ *
3420
+ * @example
3421
+ * ```typescript
3422
+ * await replaceDirectoryFromSource("/tmp/my-skill", "/home/u/.pi/agent/skills/my-skill");
3423
+ * ```
3424
+ *
3425
+ * @public
3426
+ */
3427
+ declare function replaceDirectoryFromSource(sourcePath: string, targetPath: string): Promise<void>;
3290
3428
  /**
3291
3429
  * Heuristic source-type classifier for installs that don't carry an explicit
3292
3430
  * `source_type`.
@@ -5450,6 +5588,82 @@ interface EnsureProviderInstructionFileResult {
5450
5588
  * @public
5451
5589
  */
5452
5590
  declare function ensureProviderInstructionFile(providerId: string, projectDir: string, options: EnsureProviderInstructionFileOptions): Promise<EnsureProviderInstructionFileResult>;
5591
+ /**
5592
+ * Options for {@link ensureProviderRuleFile}.
5593
+ *
5594
+ * @public
5595
+ */
5596
+ interface EnsureProviderRuleFileOptions {
5597
+ /** File path relative to the project directory (e.g. `.cursor/rules/cleo.mdc`). */
5598
+ relativePath: string;
5599
+ /**
5600
+ * Text the file must begin with (e.g. MDC frontmatter). When set, CAAMP owns
5601
+ * the whole file: its content is exactly the preamble followed by one CAAMP
5602
+ * block. When omitted, only the CAAMP block is managed and every byte outside
5603
+ * it is preserved.
5604
+ * @defaultValue `undefined`
5605
+ */
5606
+ preamble?: string;
5607
+ /** Update the file only when it already exists; never create it. @defaultValue `false` */
5608
+ onlyIfExists?: boolean;
5609
+ /**
5610
+ * `@` references to write. Defaults to the provider's registry
5611
+ * `instructionReferences`.
5612
+ * @defaultValue Registry `instructionReferences` for the provider
5613
+ */
5614
+ references?: string[];
5615
+ }
5616
+ /**
5617
+ * Result of {@link ensureProviderRuleFile}.
5618
+ *
5619
+ * @public
5620
+ */
5621
+ interface EnsureProviderRuleFileResult {
5622
+ /** Absolute path of the rule file. */
5623
+ filePath: string;
5624
+ /** Action taken. */
5625
+ action: CaampInjectionAction;
5626
+ /** Provider ID. */
5627
+ providerId: string;
5628
+ }
5629
+ /**
5630
+ * Ensure a provider's auxiliary rule file (one that is not its registry
5631
+ * `instructFile`) carries the CAAMP-managed reference block.
5632
+ *
5633
+ * @remarks
5634
+ * ADR-064: every provider instruction write goes through CAAMP. Some providers
5635
+ * read extra rule files beside their primary instruction file — Cursor reads
5636
+ * `.cursor/rules/*.mdc` and the legacy `.cursorrules` — and the adapters used
5637
+ * to write those with raw `writeFileSync` and a local copy of the references
5638
+ * (T12385). This writes them the way {@link inject} writes instruction files:
5639
+ * under the cross-process lock, atomically, with a torn-read guard, and with
5640
+ * references from the registry.
5641
+ *
5642
+ * The block carries references, not embedded sources: these files sit beside
5643
+ * the provider's primary instruction file, which
5644
+ * {@link ensureProviderInstructionFile} already fills with the self-contained
5645
+ * delivery, so embedding here would load the protocol twice.
5646
+ *
5647
+ * A file managed without a preamble that predates CAAMP markers has its bare
5648
+ * reference lines replaced by the block rather than duplicated.
5649
+ *
5650
+ * @param providerId - Provider ID from the registry
5651
+ * @param projectDir - Absolute project directory
5652
+ * @param options - Target path, optional preamble, create policy, references
5653
+ * @returns The result, or `null` when `onlyIfExists` is set and the file is absent
5654
+ * @throws Error if the provider ID is not in the registry, or on a torn read
5655
+ *
5656
+ * @example
5657
+ * ```typescript
5658
+ * await ensureProviderRuleFile("cursor", "/project", {
5659
+ * relativePath: ".cursor/rules/cleo.mdc",
5660
+ * preamble: "---\nalwaysApply: true\n---\n",
5661
+ * });
5662
+ * ```
5663
+ *
5664
+ * @public
5665
+ */
5666
+ declare function ensureProviderRuleFile(providerId: string, projectDir: string, options: EnsureProviderRuleFileOptions): Promise<EnsureProviderRuleFileResult | null>;
5453
5667
  /**
5454
5668
  * Ensure instruction files for multiple providers at once.
5455
5669
  *
@@ -8214,6 +8428,372 @@ declare function discoverSkill(skillDir: string): Promise<SkillEntry | null>;
8214
8428
  */
8215
8429
  declare function discoverSkills(rootDir: string): Promise<SkillEntry[]>;
8216
8430
 
8431
+ /**
8432
+ * Shared LAFS utilities for CAAMP commands
8433
+ *
8434
+ * Provides standardized LAFS envelope creation, error handling, and format resolution
8435
+ * to ensure all commands follow the LAFS (Language-Agnostic Format Specification) protocol.
8436
+ *
8437
+ * @module lafs
8438
+ * @requires @cleocode/lafs
8439
+ * @requires ../logger.js
8440
+ */
8441
+
8442
+ /**
8443
+ * Common error codes for consistency.
8444
+ *
8445
+ * @public
8446
+ */
8447
+ declare const ErrorCodes: {
8448
+ readonly FORMAT_CONFLICT: "E_FORMAT_CONFLICT";
8449
+ readonly INVALID_JSON: "E_INVALID_JSON";
8450
+ readonly SKILL_NOT_FOUND: "E_SKILL_NOT_FOUND";
8451
+ readonly PROVIDER_NOT_FOUND: "E_PROVIDER_NOT_FOUND";
8452
+ readonly MCP_SERVER_NOT_FOUND: "E_MCP_SERVER_NOT_FOUND";
8453
+ readonly FILE_NOT_FOUND: "E_FILE_NOT_FOUND";
8454
+ readonly INVALID_INPUT: "E_INVALID_INPUT";
8455
+ readonly INVALID_CONSTRAINT: "E_INVALID_CONSTRAINT";
8456
+ readonly INVALID_FORMAT: "E_INVALID_FORMAT";
8457
+ readonly INSTALL_FAILED: "E_INSTALL_FAILED";
8458
+ readonly SKILL_TRUST_GATE_BLOCKED: "E_SKILL_TRUST_GATE_BLOCKED";
8459
+ /** The skill security gate could not be loaded, so the install was refused (T12384). */
8460
+ readonly SKILL_GATE_UNAVAILABLE: "E_SKILL_GATE_UNAVAILABLE";
8461
+ readonly FEDERATION_UNKNOWN_SOURCE_INTERACTIVE_REQUIRED: "E_FEDERATION_UNKNOWN_SOURCE_INTERACTIVE_REQUIRED";
8462
+ readonly FEDERATION_CHECKSUM_MISMATCH: "E_FEDERATION_CHECKSUM_MISMATCH";
8463
+ readonly REMOVE_FAILED: "E_REMOVE_FAILED";
8464
+ readonly UPDATE_FAILED: "E_UPDATE_FAILED";
8465
+ readonly VALIDATION_FAILED: "E_VALIDATION_FAILED";
8466
+ readonly AUDIT_FAILED: "E_AUDIT_FAILED";
8467
+ readonly NETWORK_ERROR: "E_NETWORK_ERROR";
8468
+ readonly FILE_SYSTEM_ERROR: "E_FILE_SYSTEM_ERROR";
8469
+ readonly PERMISSION_DENIED: "E_PERMISSION_DENIED";
8470
+ readonly INTERNAL_ERROR: "E_INTERNAL_ERROR";
8471
+ };
8472
+
8473
+ /**
8474
+ * Gated skill install pipeline — the one library entry point every skill
8475
+ * install goes through, from `caamp skills install` and from `cleo tools skill
8476
+ * install` alike.
8477
+ *
8478
+ * Before T12384 the pipeline (resolve → fetch → security gate → copy → link →
8479
+ * record) lived inside the Commander action in `commands/skills/install.ts`,
8480
+ * where CLEO could not reach it. CLEO therefore called the bare `installSkill`
8481
+ * primitive, which has no gate, and passed it the literal string
8482
+ * `library:<name>` as a filesystem path (T12383). The caamp copy of the gate
8483
+ * also failed OPEN: when `@cleocode/core` could not be loaded it logged a
8484
+ * warning and installed anyway.
8485
+ *
8486
+ * This module fixes all three:
8487
+ *
8488
+ * - {@link resolveSkillSource} turns any accepted source string — a registered
8489
+ * library id (`library:<name>` or a bare name), a local path, a GitHub or
8490
+ * GitLab repo/URL, a marketplace `@author/name` — into a real local
8491
+ * directory, or throws. It never hands an identifier to the copier.
8492
+ * - {@link runSkillInstallGate} runs the federation checksum gate and the
8493
+ * skills-guard scan and FAILS CLOSED: if the gate's modules cannot be loaded,
8494
+ * the install is refused.
8495
+ * - {@link installSkillFromSource} / {@link installResolvedSkill} are the only
8496
+ * functions that should place a skill. Both gate before any filesystem
8497
+ * write, and the underlying copier stages the new copy before replacing the
8498
+ * old one.
8499
+ *
8500
+ * @task T12383
8501
+ * @task T12384
8502
+ */
8503
+
8504
+ /**
8505
+ * Error codes raised by the gated install pipeline.
8506
+ *
8507
+ * @remarks
8508
+ * Values are drawn from caamp's LAFS {@link ErrorCodes} table so CLI envelopes
8509
+ * and library callers report the same code for the same refusal.
8510
+ *
8511
+ * @public
8512
+ */
8513
+ type SkillInstallErrorCode = typeof ErrorCodes.SKILL_NOT_FOUND | typeof ErrorCodes.INVALID_INPUT | typeof ErrorCodes.INVALID_FORMAT | typeof ErrorCodes.NETWORK_ERROR | typeof ErrorCodes.SKILL_TRUST_GATE_BLOCKED | typeof ErrorCodes.SKILL_GATE_UNAVAILABLE | typeof ErrorCodes.FEDERATION_CHECKSUM_MISMATCH | typeof ErrorCodes.FEDERATION_UNKNOWN_SOURCE_INTERACTIVE_REQUIRED;
8514
+ /**
8515
+ * Structured detail attached to a {@link SkillInstallError}.
8516
+ *
8517
+ * @public
8518
+ */
8519
+ interface SkillInstallErrorDetails {
8520
+ /** Scan result when the refusal came from the skills-guard scan. */
8521
+ scan?: SkillGateScanResult;
8522
+ /** Federation gate result when the refusal came from the checksum/source gate. */
8523
+ federation?: SkillGateFederationResult;
8524
+ /** Skill names the registered library does offer, when a lookup missed. */
8525
+ availableSkills?: string[];
8526
+ /** Underlying error message, when the refusal wraps another failure. */
8527
+ cause?: string;
8528
+ }
8529
+ /**
8530
+ * A skill install that was refused before anything was written.
8531
+ *
8532
+ * @remarks
8533
+ * Every refusal from this module is thrown as this type, so callers can map
8534
+ * `code` to an envelope and trust that the installed copy was not touched.
8535
+ *
8536
+ * @example
8537
+ * ```typescript
8538
+ * try {
8539
+ * await installSkillFromSource("owner/repo", { providers, isGlobal: true });
8540
+ * } catch (err) {
8541
+ * if (err instanceof SkillInstallError) console.error(err.code, err.message);
8542
+ * }
8543
+ * ```
8544
+ *
8545
+ * @public
8546
+ */
8547
+ declare class SkillInstallError extends Error {
8548
+ /** Machine-readable refusal code. */
8549
+ readonly code: SkillInstallErrorCode;
8550
+ /** Structured context for the refusal. */
8551
+ readonly details: SkillInstallErrorDetails;
8552
+ /**
8553
+ * @param code - Refusal code
8554
+ * @param message - Human-readable reason
8555
+ * @param details - Structured context
8556
+ */
8557
+ constructor(code: SkillInstallErrorCode, message: string, details?: SkillInstallErrorDetails);
8558
+ }
8559
+ /**
8560
+ * A skill source resolved to a real local directory.
8561
+ *
8562
+ * @public
8563
+ */
8564
+ interface ResolvedSkillSource {
8565
+ /** Absolute path of the directory to install from. */
8566
+ localPath: string;
8567
+ /** Name the skill is installed under. */
8568
+ skillName: string;
8569
+ /** Provenance string recorded for the install (e.g. `library:ct-foo`, a GitHub URL). */
8570
+ sourceValue: string;
8571
+ /** Classified source type. */
8572
+ sourceType: SourceType;
8573
+ /** Removes any temporary checkout; absent for sources that live on disk already. */
8574
+ cleanup?: () => Promise<void>;
8575
+ }
8576
+ /**
8577
+ * A resolution step worth telling a human about.
8578
+ *
8579
+ * @remarks
8580
+ * The library does not print; a CLI renders these (e.g. in `--human` mode).
8581
+ *
8582
+ * @public
8583
+ */
8584
+ type SkillSourceProgress = {
8585
+ readonly kind: 'marketplace-search';
8586
+ readonly source: string;
8587
+ } | {
8588
+ readonly kind: 'marketplace-found';
8589
+ readonly name: string;
8590
+ readonly author: string;
8591
+ readonly repo: string;
8592
+ } | {
8593
+ readonly kind: 'catalog-found';
8594
+ readonly name: string;
8595
+ readonly version: string;
8596
+ readonly category: string;
8597
+ };
8598
+ /**
8599
+ * Resolve a skill source string to a real local directory.
8600
+ *
8601
+ * @remarks
8602
+ * Accepted forms:
8603
+ *
8604
+ * - `library:<name>` (or `<package>:<name>`) and bare `<name>` — looked up in
8605
+ * the registered skill library ({@link catalog}).
8606
+ * - An absolute, `./`, `../` or `~` path — used as is (the name comes from its
8607
+ * `SKILL.md` when present).
8608
+ * - `owner/repo[/path]`, a GitHub URL or a GitLab URL — cloned to a temporary
8609
+ * directory; call `cleanup` when done.
8610
+ * - `@author/name` — looked up in the skill marketplace, then cloned.
8611
+ *
8612
+ * Anything else is refused. An identifier is never returned as `localPath`,
8613
+ * which is the T12383 defect: `library:<name>` used to reach `cp()` verbatim.
8614
+ *
8615
+ * @param source - Source string as typed by the user or stored in a lock row
8616
+ * @param onProgress - Optional sink for human-facing resolution events
8617
+ * @returns The resolved local source
8618
+ * @throws {@link SkillInstallError} when the source cannot be resolved
8619
+ *
8620
+ * @example
8621
+ * ```typescript
8622
+ * const resolved = await resolveSkillSource("library:ct-cleo");
8623
+ * try {
8624
+ * console.log(resolved.localPath);
8625
+ * } finally {
8626
+ * await resolved.cleanup?.();
8627
+ * }
8628
+ * ```
8629
+ *
8630
+ * @public
8631
+ */
8632
+ declare function resolveSkillSource(source: string, onProgress?: (event: SkillSourceProgress) => void): Promise<ResolvedSkillSource>;
8633
+ /**
8634
+ * The `@cleocode/core` functions the gate calls.
8635
+ *
8636
+ * @remarks
8637
+ * Loaded lazily because core depends on caamp at build time; a static import
8638
+ * of these modules would put core's whole skills graph on caamp's startup
8639
+ * path. Typed against the shared `@cleocode/contracts` gate shapes, which
8640
+ * mirror core's types structurally, so core's functions are assignable here.
8641
+ *
8642
+ * @public
8643
+ */
8644
+ interface SkillGateModules {
8645
+ /** Skills-guard static scan. */
8646
+ scanSkill: (skillPath: string, source: string) => SkillGateScanResult;
8647
+ /** INSTALL_POLICY decision over a scan result. */
8648
+ shouldAllowInstall: (result: SkillGateScanResult, force: boolean) => SkillGatePolicyDecision;
8649
+ /** Federation first-install and checksum gate. */
8650
+ evaluateFederationInstallGate: (opts: SkillGateFederationInput) => SkillGateFederationResult;
8651
+ /** Audit writer for operator `force` bypasses. */
8652
+ recordTrustBypass: (result: SkillGateScanResult, reason: string | null) => object;
8653
+ }
8654
+ /**
8655
+ * Options for {@link runSkillInstallGate}.
8656
+ *
8657
+ * @public
8658
+ */
8659
+ interface SkillInstallGateOptions {
8660
+ /** Operator override of a `block` scan decision (audited). Never overrides `ask` or a checksum mismatch. */
8661
+ force?: boolean;
8662
+ /** Approve a first install from an unverified federation source (non-interactive contexts). */
8663
+ allowNewSource?: boolean;
8664
+ /** Checksum the artefact must match, when the source declares one. */
8665
+ expectedChecksum?: string | null;
8666
+ }
8667
+ /**
8668
+ * What the gate decided, for callers that report it.
8669
+ *
8670
+ * @public
8671
+ */
8672
+ interface SkillInstallGateReport {
8673
+ /** The skills-guard scan of the staged source. */
8674
+ scan: SkillGateScanResult;
8675
+ /** The install-policy decision (always `allow` when this returns). */
8676
+ decision: SkillGatePolicyDecision;
8677
+ /** The federation gate result (always `allow` when this returns). */
8678
+ federation: SkillGateFederationResult;
8679
+ /** Whether an operator `force` bypass was used and audited. */
8680
+ bypassed: boolean;
8681
+ }
8682
+ /**
8683
+ * Run the federation checksum gate and the skills-guard scan over a resolved
8684
+ * source. Fails closed.
8685
+ *
8686
+ * @remarks
8687
+ * Order matters: the federation gate runs first, so a checksum mismatch or an
8688
+ * unapproved federation source is refused before the scanner reads the bytes.
8689
+ * Both run before any filesystem write.
8690
+ *
8691
+ * Unlike the pre-T12384 caamp CLI gate, a failure to load the gate's modules is
8692
+ * a refusal (`E_SKILL_GATE_UNAVAILABLE`), not a skipped check.
8693
+ *
8694
+ * @param source - The resolved source to vet
8695
+ * @param options - Operator overrides
8696
+ * @returns The gate report when the install may proceed
8697
+ * @throws {@link SkillInstallError} when the install is refused or the gate is unavailable
8698
+ *
8699
+ * @example
8700
+ * ```typescript
8701
+ * const report = await runSkillInstallGate(resolved, { force: false });
8702
+ * console.log(report.scan.verdict);
8703
+ * ```
8704
+ *
8705
+ * @public
8706
+ */
8707
+ declare function runSkillInstallGate(source: ResolvedSkillSource, options?: SkillInstallGateOptions): Promise<SkillInstallGateReport>;
8708
+ /**
8709
+ * Options for {@link installSkillFromSource} and {@link installResolvedSkill}.
8710
+ *
8711
+ * @public
8712
+ */
8713
+ interface GatedSkillInstallOptions extends SkillInstallGateOptions {
8714
+ /** Providers to link the skill into. */
8715
+ providers: Provider[];
8716
+ /** Global (`true`) or project scope. */
8717
+ isGlobal: boolean;
8718
+ /** Project directory for project scope. */
8719
+ projectDir?: string;
8720
+ /** Provenance sink forwarded to the canonical installer. */
8721
+ recordRow?: InstallSkillOptions['recordRow'];
8722
+ /** Record the install in the CAAMP lock file. @defaultValue false */
8723
+ recordLock?: boolean;
8724
+ /** Override the name the skill installs under. */
8725
+ skillName?: string;
8726
+ /** Sink for human-facing resolution events (used by {@link installSkillFromSource}). */
8727
+ onProgress?: (event: SkillSourceProgress) => void;
8728
+ }
8729
+ /**
8730
+ * Result of a gated install.
8731
+ *
8732
+ * @public
8733
+ */
8734
+ interface GatedSkillInstallResult extends SkillInstallResult {
8735
+ /** Provenance string recorded for the install. */
8736
+ sourceValue: string;
8737
+ /** Classified source type. */
8738
+ sourceType: SourceType;
8739
+ /** The gate's report. */
8740
+ gate: SkillInstallGateReport;
8741
+ }
8742
+ /**
8743
+ * Gate and install an already-resolved source.
8744
+ *
8745
+ * @remarks
8746
+ * Use this when the caller has a checkout in hand (for example an update that
8747
+ * cloned the source itself). The gate runs first; on refusal nothing is
8748
+ * written. The canonical copy is staged before it replaces the installed one
8749
+ * (T12383), so a failure part-way through keeps the installed skill.
8750
+ *
8751
+ * Does not call `source.cleanup` — the caller owns the checkout.
8752
+ *
8753
+ * @param source - Resolved source
8754
+ * @param options - Targets, scope, provenance and gate overrides
8755
+ * @returns The install result, including the gate report
8756
+ * @throws {@link SkillInstallError} when the gate refuses the install
8757
+ *
8758
+ * @example
8759
+ * ```typescript
8760
+ * const result = await installResolvedSkill(
8761
+ * { localPath: "/tmp/co/skill", skillName: "demo", sourceValue: "owner/repo", sourceType: "github" },
8762
+ * { providers, isGlobal: true },
8763
+ * );
8764
+ * ```
8765
+ *
8766
+ * @public
8767
+ */
8768
+ declare function installResolvedSkill(source: ResolvedSkillSource, options: GatedSkillInstallOptions): Promise<GatedSkillInstallResult>;
8769
+ /**
8770
+ * Resolve, gate and install a skill from any accepted source string.
8771
+ *
8772
+ * @remarks
8773
+ * The single entry point for installing a skill (T12384). Resolution turns the
8774
+ * source into a real directory ({@link resolveSkillSource}); the gate vets it
8775
+ * and fails closed ({@link runSkillInstallGate}); the installer stages the new
8776
+ * copy before replacing the old one. Temporary checkouts are always removed.
8777
+ *
8778
+ * @param source - `library:<name>`, a bare library name, a local path,
8779
+ * `owner/repo`, a GitHub/GitLab URL, or `@author/name`
8780
+ * @param options - Targets, scope, provenance and gate overrides
8781
+ * @returns The install result, including the gate report
8782
+ * @throws {@link SkillInstallError} when the source cannot be resolved or the gate refuses it
8783
+ *
8784
+ * @example
8785
+ * ```typescript
8786
+ * const result = await installSkillFromSource("library:ct-cleo", {
8787
+ * providers: getInstalledProviders(),
8788
+ * isGlobal: true,
8789
+ * });
8790
+ * console.log(result.linkedAgents);
8791
+ * ```
8792
+ *
8793
+ * @public
8794
+ */
8795
+ declare function installSkillFromSource(source: string, options: GatedSkillInstallOptions): Promise<GatedSkillInstallResult>;
8796
+
8217
8797
  /**
8218
8798
  * Skill integrity checking
8219
8799
  *
@@ -9153,4 +9733,4 @@ declare function parseSource(input: string): ParsedSource;
9153
9733
  */
9154
9734
  declare function isMarketplaceScoped(input: string): boolean;
9155
9735
 
9156
- export { type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, type BlockInsertPosition, CANONICAL_HOOK_EVENTS, CLEO_ARTIFACT_BUDGETS, CLEO_ARTIFACT_REQUIREMENTS, type CaampBlock, type CaampLockFile, type CanonicalEventDefinition, type CanonicalHookEvent, type CantProfileCounts, type CantProfileEntry, type CantValidationDiagnostic, type ConfigFormat, type CrossProviderMatrix, type CtDispatchMatrix, type CtManifest, type CtManifestSkill, type CtProfileDefinition, type CtSkillEntry, type CtValidationIssue, type CtValidationResult, DEFAULT_EXCLUSIVITY_MODE, type DedupeResult, type DetectionCacheOptions, type DetectionResult, EXCLUSIVITY_MODE_ENV_VAR, EmbeddedDeliveryDowngradeError, type EnsureProviderInstructionFileOptions, type EnsureProviderInstructionFileResult, type ExclusivityMode, type FileLockOptions, type GlobalInstructionOptions, type GlobalOptions, HOOK_CATEGORIES, type Harness, type HarnessScope, type HookCategory, type HookEvent, type HookHandlerType, type HookMapping, type HookSupportResult, type HookSystemType, type InjectionCheckResult, type InjectionStatus, type InjectionTemplate, type InstallMcpServerOptions, type InstallMcpServerResult, type InstallSkillOptions, type InstructionUpdateSummary, type KnownProviderAgentFolderId, type LockEntry, MarketplaceClient, type MarketplaceResult, type MarketplaceSearchResult, type MarketplaceSkill, type McpConfigFormat, type McpDetectionEntry, type McpScope, type McpServerConfig, type McpServerEntriesByProvider, type McpServerEntry, type McpTransportType, type NormalizeResult, type NormalizedHookEvent, type NormalizedRecommendationCriteria, type ParsedSource, PiHarness, PiRequiredError, type Provider, type ProviderCapabilities, type ProviderHarnessCapability, type ProviderHookProfile, type ProviderHookSummary, type ProviderHooksCapability, type ProviderMcpCapability, type ProviderPriority, type ProviderSkillsCapability, type ProviderSpawnCapability, type ProviderStatus, RECOMMENDATION_ERROR_CODES, type RankedSkillRecommendation, type RecommendSkillsResult, type RecommendationCriteriaInput, type RecommendationErrorCode, type RecommendationOptions, type RecommendationReason, type RecommendationReasonCode, type RecommendationScoreBreakdown, type RecommendationValidationIssue, type RecommendationValidationResult, type RecommendationWeights, type ReconcileResult, type RegistryHarnessKind, type RegistryHookCatalog, type RegistryHookFormat, type RemoveMcpServerOptions, type RemoveMcpServerResult, type RepairResult, type ResolveDefaultTargetProvidersOptions, type SkillBatchOperation, type SkillEntry, type SkillInstallResult, type SkillIntegrityResult, type SkillIntegrityStatus, type SkillLibrary, type SkillLibraryDispatchMatrix, type SkillLibraryEntry, type SkillLibraryManifest, type SkillLibraryManifestSkill, type SkillLibraryProfile, type SkillLibraryValidationIssue, type SkillLibraryValidationResult, type SkillMetadata, type SkillRowData, type SkillRowSourceType, type SkillsPrecedence, type SourceType, type SpawnAdapter, type SpawnMechanism, type SpawnOptions, type SpawnResult, type SubagentHandle, type SubagentResult, type SubagentTask, type SyncGlobalInstructionsOptions, type TransportType, type ValidateCantProfileResult, type ValidationIssue, type ValidationResult, type WriteAgentFileOptions, type WriteAgentFileResult, _resetPlatformPathsCache, assertCleoShippedBuildShape, assertNotTornRead, blockPattern, buildBlock, buildHookMatrix, buildInjectionContent, buildLibraryFromFiles, buildSkillsMap, catalog, checkAllInjections, checkAllSkillIntegrity, checkAllSkillUpdates, checkGlobalInstructionStaleness, checkInjection, checkSkillIntegrity, checkSkillUpdate, classifyPackageFilesEntry, clearRegisteredLibrary, dedupeFile, dedupeFiles, deepMerge, detectAllProviders, detectMcpInstallations, detectProjectProviders, detectProvider, discoverSkill, discoverSkills, ensureAllProviderInstructionFiles, ensureDir, ensureProviderInstructionFile, formatSkillRecommendations, generateInjectionContent, generateSkillsSection, getAgentsConfigPath, getAgentsHome, getAgentsInstructFile, getAgentsLinksDir, getAgentsMcpDir, getAgentsMcpServersPath, getAgentsSpecDir, getAgentsWikiDir, getAllCanonicalEvents, getAllHarnesses, getAllProviders, getCanonicalEvent, getCanonicalEventsByCategory, getCommonEvents, getCommonHookEvents, getEffectiveSkillsPaths, getExclusivityMode, getHarnessFor, getHookConfigPath, getHookMappingsVersion, getHookSupport, getHookSystemType, getInstalledProviders, getInstructionFiles, getLockFilePath, getMappedProviderIds, getNestedValue, getPlatformLocations, getPlatformPaths, getPrimaryHarness, getPrimaryProvider, getProjectAgentsDir, getProvider, getProviderAgentFolder, getProviderCapabilities, getProviderCount, getProviderHookProfile, getProviderInstructionReferences, getProviderOnlyEvents, getProviderSummary, getProvidersByHookEvent, getProvidersByInstructFile, getProvidersByPriority, getProvidersBySkillsPrecedence, getProvidersBySpawnCapability, getProvidersByStatus, getProvidersForEvent, getRegistryVersion, getSpawnCapableProviders, getSupportedEvents, getSystemInfo, getTrackedSkills, getUnsupportedEvents, groupByInstructFile, inferSkillSourceType, inject, injectAll, installBatchWithRollback, installMcpServer, installSkill, instructionFileCascade, isCaampOwnedSkill, isEmbeddedDelivery, isExclusivityMode, isMarketplaceScoped, isQuiet, isVerbose, listAllMcpServers, listCanonicalSkills, listMcpServers, loadLibraryFromModule, mergeBlockBodies, normalizeMarkers, normalizeRecommendationCriteria, parseBlocks, parseCaampBlocks, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, recommendSkills, reconcile, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, removeConfig, removeInjection, removeMcpServer, removeMcpServerFromAll, removeSkill, removeSkillFromLock, repairContent, repairInstructionFiles, resetDetectionCache, resetExclusivityModeOverride, resetRegistry, resolveAlias, resolveDefaultTargetProviders, resolveGlobalInstructionPath, resolveInstructionDelivery, resolveMcpConfigPath, resolveNativeEvent, resolveProviderSkillsDirs, resolveRegistryTemplatePath, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setExclusivityMode, setQuiet, setVerbose, shouldOverrideSkill, supportsHook, syncGlobalInstructions, toCanonical, toNative, toNativeBatch, toSarif, tokenizeCriteriaValue, translateToAll, updateInstructionsSingleOperation, validateInstructionIntegrity, validatePackageArtifact, validateRecommendationCriteria, validateSkill, withFileLock, writeAgentFileToAllProviders, writeConfig };
9736
+ export { type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, type BlockInsertPosition, CANONICAL_HOOK_EVENTS, CLEO_ARTIFACT_BUDGETS, CLEO_ARTIFACT_REQUIREMENTS, type CaampBlock, type CaampLockFile, type CanonicalEventDefinition, type CanonicalHookEvent, type CantProfileCounts, type CantProfileEntry, type CantValidationDiagnostic, type ConfigFormat, type CrossProviderMatrix, type CtDispatchMatrix, type CtManifest, type CtManifestSkill, type CtProfileDefinition, type CtSkillEntry, type CtValidationIssue, type CtValidationResult, DEFAULT_EXCLUSIVITY_MODE, type DedupeResult, type DetectionCacheOptions, type DetectionResult, EXCLUSIVITY_MODE_ENV_VAR, EmbeddedDeliveryDowngradeError, type EnsureProviderInstructionFileOptions, type EnsureProviderInstructionFileResult, type EnsureProviderRuleFileOptions, type EnsureProviderRuleFileResult, type ExclusivityMode, type FileLockOptions, type GatedSkillInstallOptions, type GatedSkillInstallResult, type GlobalInstructionOptions, type GlobalOptions, HOOK_CATEGORIES, type Harness, type HarnessScope, type HookCategory, type HookEvent, type HookHandlerType, type HookMapping, type HookSupportResult, type HookSystemType, type InjectionCheckResult, type InjectionStatus, type InjectionTemplate, type InstallMcpServerOptions, type InstallMcpServerResult, type InstallSkillOptions, type InstructionUpdateSummary, JsonConfigParseError, type KnownProviderAgentFolderId, type LockEntry, MarketplaceClient, type MarketplaceResult, type MarketplaceSearchResult, type MarketplaceSkill, type McpConfigFormat, type McpDetectionEntry, type McpScope, type McpServerConfig, type McpServerEntriesByProvider, type McpServerEntry, type McpTransportType, type NormalizeResult, type NormalizedHookEvent, type NormalizedRecommendationCriteria, type ParsedSource, PiHarness, PiRequiredError, type Provider, type ProviderCapabilities, type ProviderHarnessCapability, type ProviderHookProfile, type ProviderHookSummary, type ProviderHooksCapability, type ProviderMcpCapability, type ProviderPriority, type ProviderSkillsCapability, type ProviderSpawnCapability, type ProviderStatus, RECOMMENDATION_ERROR_CODES, type RankedSkillRecommendation, type RecommendSkillsResult, type RecommendationCriteriaInput, type RecommendationErrorCode, type RecommendationOptions, type RecommendationReason, type RecommendationReasonCode, type RecommendationScoreBreakdown, type RecommendationValidationIssue, type RecommendationValidationResult, type RecommendationWeights, type ReconcileResult, type RegistryHarnessKind, type RegistryHookCatalog, type RegistryHookFormat, type RemoveMcpServerOptions, type RemoveMcpServerResult, type RepairResult, type ResolveDefaultTargetProvidersOptions, type ResolvedSkillSource, type SkillBatchOperation, type SkillEntry, type SkillGateModules, SkillInstallError, type SkillInstallErrorCode, type SkillInstallErrorDetails, type SkillInstallGateOptions, type SkillInstallGateReport, type SkillInstallResult, type SkillIntegrityResult, type SkillIntegrityStatus, type SkillLibrary, type SkillLibraryDispatchMatrix, type SkillLibraryEntry, type SkillLibraryManifest, type SkillLibraryManifestSkill, type SkillLibraryProfile, type SkillLibraryValidationIssue, type SkillLibraryValidationResult, type SkillMetadata, type SkillRowData, type SkillRowSourceType, type SkillSourceProgress, type SkillsPrecedence, type SourceType, type SpawnAdapter, type SpawnMechanism, type SpawnOptions, type SpawnResult, type SubagentHandle, type SubagentResult, type SubagentTask, type SyncGlobalInstructionsOptions, type TransportType, type ValidateCantProfileResult, type ValidationIssue, type ValidationResult, type WriteAgentFileOptions, type WriteAgentFileResult, _resetPlatformPathsCache, assertCleoShippedBuildShape, assertNotTornRead, blockPattern, buildBlock, buildHookMatrix, buildInjectionContent, buildLibraryFromFiles, buildSkillsMap, catalog, checkAllInjections, checkAllSkillIntegrity, checkAllSkillUpdates, checkGlobalInstructionStaleness, checkInjection, checkSkillIntegrity, checkSkillUpdate, classifyPackageFilesEntry, clearRegisteredLibrary, dedupeFile, dedupeFiles, deepMerge, detectAllProviders, detectMcpInstallations, detectProjectProviders, detectProvider, discoverSkill, discoverSkills, ensureAllProviderInstructionFiles, ensureDir, ensureProviderInstructionFile, ensureProviderRuleFile, formatSkillRecommendations, generateInjectionContent, generateSkillsSection, getAgentsConfigPath, getAgentsHome, getAgentsInstructFile, getAgentsLinksDir, getAgentsMcpDir, getAgentsMcpServersPath, getAgentsSpecDir, getAgentsWikiDir, getAllCanonicalEvents, getAllHarnesses, getAllProviders, getCanonicalEvent, getCanonicalEventsByCategory, getCommonEvents, getCommonHookEvents, getEffectiveSkillsPaths, getExclusivityMode, getHarnessFor, getHookConfigPath, getHookMappingsVersion, getHookSupport, getHookSystemType, getInstalledProviders, getInstructionFiles, getLockFilePath, getMappedProviderIds, getNestedValue, getPlatformLocations, getPlatformPaths, getPrimaryHarness, getPrimaryProvider, getProjectAgentsDir, getProvider, getProviderAgentFolder, getProviderCapabilities, getProviderCount, getProviderHookProfile, getProviderInstructionReferences, getProviderOnlyEvents, getProviderSummary, getProvidersByHookEvent, getProvidersByInstructFile, getProvidersByPriority, getProvidersBySkillsPrecedence, getProvidersBySpawnCapability, getProvidersByStatus, getProvidersForEvent, getRegistryVersion, getSpawnCapableProviders, getSupportedEvents, getSystemInfo, getTrackedSkills, getUnsupportedEvents, groupByInstructFile, inferSkillSourceType, inject, injectAll, installBatchWithRollback, installMcpServer, installResolvedSkill, installSkill, installSkillFromSource, instructionFileCascade, isCaampOwnedSkill, isEmbeddedDelivery, isExclusivityMode, isMarketplaceScoped, isQuiet, isVerbose, listAllMcpServers, listCanonicalSkills, listMcpServers, loadLibraryFromModule, mergeBlockBodies, normalizeMarkers, normalizeRecommendationCriteria, parseBlocks, parseCaampBlocks, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, recommendSkills, reconcile, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, removeConfig, removeInjection, removeMcpServer, removeMcpServerFromAll, removeSkill, removeSkillFromLock, repairContent, repairInstructionFiles, replaceDirectoryFromSource, resetDetectionCache, resetExclusivityModeOverride, resetRegistry, resolveAlias, resolveDefaultTargetProviders, resolveGlobalInstructionPath, resolveInstructionDelivery, resolveMcpConfigPath, resolveNativeEvent, resolveProviderSkillsDirs, resolveRegistryTemplatePath, resolveSkillSource, runSkillInstallGate, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setExclusivityMode, setQuiet, setVerbose, shouldOverrideSkill, stageSkillCopy, supportsHook, swapIntoPlace, syncGlobalInstructions, toCanonical, toNative, toNativeBatch, toSarif, tokenizeCriteriaValue, translateToAll, updateInstructionsSingleOperation, updateJsonConfigFile, validateInstructionIntegrity, validatePackageArtifact, validateRecommendationCriteria, validateSkill, withFileLock, writeAgentFileToAllProviders, writeConfig };