@cleocode/caamp 2026.5.83 → 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/index.d.ts CHANGED
@@ -1,7 +1,538 @@
1
+ import { Command } from 'commander';
1
2
  import { WorktreeHandle } from '@cleocode/cant';
2
3
  import { PlatformPaths, SystemInfo } from '@cleocode/paths';
3
4
  export { PlatformPaths, SystemInfo } from '@cleocode/paths';
4
5
 
6
+ /**
7
+ * `skills doctor adopt-orphans` — interactive orphan audit + adoption.
8
+ *
9
+ * @remarks
10
+ * An "orphan" is a skill directory that exists under any tracked path
11
+ * (`~/.cleo/skills/`, legacy `~/.local/share/agents/skills/`,
12
+ * `~/.agents/skills/` as a real dir) but has NO row in the per-user
13
+ * `skills.db` registry described in
14
+ * `docs/architecture/SG-CLEO-SKILLS-architecture-v3.md` §4.
15
+ *
16
+ * The handler offers four per-orphan dispositions:
17
+ *
18
+ * - **canonical-adopt** — REFUSED on a user machine. Canonical writes
19
+ * must flow via PR to `packages/skills/skills/` (architecture-v3 §6
20
+ * invariant). The handler emits a refusal explaining the PR flow.
21
+ * - **user-adopt** — inserts a row into `skills.db` with
22
+ * `source_type='user'`, `lifecycle_state='active'`, `installedAt=now`.
23
+ * - **delete** — archives the directory to
24
+ * `~/.cleo/skills/.archive/<name>-<ts>/` before unlinking from the
25
+ * original location.
26
+ * - **skip** — no action; the orphan is logged but otherwise ignored.
27
+ *
28
+ * All decisions are recorded to a structured JSON audit log at
29
+ * `~/.cleo/skills/.audit-log/adopt-<ISO-ts>.json` regardless of mode.
30
+ *
31
+ * ## Chokepoint compliance (ADR-068)
32
+ *
33
+ * This module emits PURE DATA. The skills.db reads and writes are deferred
34
+ * to caller-supplied callbacks (`loadRegisteredNames`, `recordRow`). The
35
+ * `cleo` dispatch layer in `packages/cleo/src/cli/commands/skills.ts` plugs
36
+ * the canonical `openCleoDb('skills')`/`upsertSkillRow` helpers from
37
+ * `@cleocode/core/store/skills-db`. caamp cannot depend on `@cleocode/core`
38
+ * directly (would invert the dep direction: core dynamically imports caamp).
39
+ *
40
+ * Three execution modes:
41
+ *
42
+ * - default (TTY) — interactive prompt per orphan.
43
+ * - `--non-interactive` — list orphans and exit without action
44
+ * (read-only audit).
45
+ * - `--auto-user-adopt` — bulk user-adopt all orphans without prompting
46
+ * (safe default for `cleo-init`-style scripts).
47
+ *
48
+ * @task T9657
49
+ * @epic T9571
50
+ * @saga T9560
51
+ * @architecture docs/architecture/SG-CLEO-SKILLS-architecture-v3.md §1, §6
52
+ */
53
+
54
+ /**
55
+ * One orphan disposition decision.
56
+ *
57
+ * @public
58
+ */
59
+ type OrphanDecision = 'canonical-adopt' | 'user-adopt' | 'delete' | 'skip';
60
+ /**
61
+ * Reason an action was refused (canonical-adopt on user machine, etc.).
62
+ *
63
+ * @public
64
+ */
65
+ interface OrphanRefusal {
66
+ /** Stable code for programmatic handling. */
67
+ code: 'E_CANONICAL_ADOPT_REFUSED';
68
+ /** Human-readable explanation. */
69
+ message: string;
70
+ /** Suggested next step (e.g. PR flow). */
71
+ remediation: string;
72
+ }
73
+ /**
74
+ * A single orphan skill directory discovered on disk.
75
+ *
76
+ * @public
77
+ */
78
+ interface OrphanRecord {
79
+ /** Skill name (basename of the orphan directory). */
80
+ name: string;
81
+ /** Absolute path to the orphan directory on disk. */
82
+ path: string;
83
+ /** Which tracked root this orphan was discovered under. */
84
+ discoveredVia: 'cleo' | 'legacy-agents' | 'home-agents';
85
+ /** Whether a `SKILL.md` sentinel exists at the root. */
86
+ hasSkillMd: boolean;
87
+ /** Size of the directory in bytes (best-effort; 0 on stat failure). */
88
+ sizeBytes: number;
89
+ }
90
+ /**
91
+ * Outcome of acting on a single orphan.
92
+ *
93
+ * @public
94
+ */
95
+ interface OrphanActionResult {
96
+ /** The orphan that was acted upon. */
97
+ orphan: OrphanRecord;
98
+ /** Decision the user (or flag) made. */
99
+ decision: OrphanDecision;
100
+ /** Whether the action completed successfully. */
101
+ applied: boolean;
102
+ /** Refusal payload when `applied=false` due to a policy block. */
103
+ refusal: OrphanRefusal | null;
104
+ /** Where the directory was archived to (delete only). */
105
+ archivedTo: string | null;
106
+ /** ISO-8601 timestamp when the action was taken. */
107
+ decidedAt: string;
108
+ }
109
+ /**
110
+ * Top-level result returned in the LAFS envelope.
111
+ *
112
+ * @public
113
+ */
114
+ interface DoctorAdoptResult {
115
+ /** Total orphans discovered. */
116
+ totalOrphans: number;
117
+ /** Per-orphan action results. */
118
+ results: OrphanActionResult[];
119
+ /** Audit log file path (always written). */
120
+ auditLogPath: string;
121
+ /** Execution mode used. */
122
+ mode: 'interactive' | 'non-interactive' | 'auto-user-adopt';
123
+ }
124
+ /**
125
+ * Pure-data payload emitted when a `user-adopt` decision is applied.
126
+ *
127
+ * @remarks
128
+ * The dispatch layer translates this into an `upsertSkillRow` call via the
129
+ * `openCleoDb('skills')` chokepoint. Keeping it as pure data means caamp
130
+ * never has to touch sqlite directly.
131
+ *
132
+ * @public
133
+ */
134
+ interface AdoptedSkillRowData {
135
+ /** Skill name (PK in skills.db). */
136
+ name: string;
137
+ /** Absolute install path on disk. */
138
+ installPath: string;
139
+ /** Wall-clock timestamp the adoption occurred. */
140
+ installedAt: string;
141
+ /** Always `'user'` for the adopt-orphans flow (canonical is refused). */
142
+ sourceType: 'user';
143
+ /** Always `'active'` post-adoption. */
144
+ lifecycleState: 'active';
145
+ }
146
+ /**
147
+ * Discover orphan skills across all tracked roots.
148
+ *
149
+ * @remarks
150
+ * Visits the three tracked roots in priority order and de-duplicates by
151
+ * basename — the first occurrence of `<name>` wins (so a `~/.cleo/skills/`
152
+ * entry shadows the same-named legacy entry). Symlinks under
153
+ * `~/.agents/skills/` that resolve back into `~/.cleo/skills/` are dropped
154
+ * because those are the bridge symlinks, not real orphans.
155
+ *
156
+ * Read-side IO (the set of names already known to `skills.db`) is supplied
157
+ * via the `registeredNames` callback so this module never opens sqlite
158
+ * directly — see ADR-068 chokepoint compliance in the file header.
159
+ *
160
+ * @param registeredNames - Pre-computed set of skill names known to the
161
+ * registry. Callers in production wire this through `openCleoDb('skills')`;
162
+ * tests wire it through a sandboxed `DatabaseSync` open.
163
+ * @returns Sorted-by-name list of `OrphanRecord`s.
164
+ *
165
+ * @public
166
+ */
167
+ declare function discoverOrphans(registeredNames: ReadonlySet<string>): OrphanRecord[];
168
+ /**
169
+ * Callback signature for persisting a `user-adopt` decision.
170
+ *
171
+ * @remarks
172
+ * Production wiring lives in `packages/cleo/src/cli/commands/skills.ts` and
173
+ * funnels into `upsertSkillRow` from `@cleocode/core/store/skills-db`,
174
+ * which routes through the canonical `openCleoDb('skills')` chokepoint.
175
+ * Test code passes a sandboxed sqlite write. May be synchronous or async.
176
+ *
177
+ * @public
178
+ */
179
+ type RecordRowFn = (data: AdoptedSkillRowData) => void | Promise<void>;
180
+ /**
181
+ * Apply a single decision to an orphan, returning a structured outcome.
182
+ *
183
+ * @remarks
184
+ * This is the policy chokepoint — `canonical-adopt` is unconditionally
185
+ * refused, `user-adopt` invokes `recordRow` with the canonical
186
+ * {@link AdoptedSkillRowData} payload, `delete` archives-then-rms, and
187
+ * `skip` records the intent without side effects. Errors during
188
+ * `user-adopt` or `delete` produce an `applied=false` result with a
189
+ * synthesised refusal payload rather than throwing, so the bulk loop can
190
+ * proceed across all orphans.
191
+ *
192
+ * @param orphan - Orphan to act on.
193
+ * @param decision - Decision to apply.
194
+ * @param now - ISO-8601 timestamp to record on the result.
195
+ * @param recordRow - Callback invoked to persist a successful `user-adopt`.
196
+ * Tests pass a sandbox write; production passes the cleo-dispatch wrapper.
197
+ * @returns A populated `OrphanActionResult`.
198
+ *
199
+ * @public
200
+ */
201
+ declare function applyDecision(orphan: OrphanRecord, decision: OrphanDecision, now: string, recordRow: RecordRowFn): Promise<OrphanActionResult>;
202
+ /**
203
+ * Write the audit log to `~/.cleo/skills/.audit-log/adopt-<ts>.json`.
204
+ *
205
+ * @remarks
206
+ * The log is written atomically (tmp-then-rename) so a SIGINT mid-write
207
+ * cannot leave a half-written file. The payload is a structured object
208
+ * containing the run timestamp, mode, full per-orphan results, and a
209
+ * stable `runId` UUID for cross-referencing in other CLEO audit streams
210
+ * (e.g. release-ship logs).
211
+ *
212
+ * @param result - The doctor-adopt result to persist.
213
+ * @returns Absolute path the audit log was written to.
214
+ *
215
+ * @public
216
+ */
217
+ declare function writeAuditLog(result: DoctorAdoptResult): string;
218
+ /**
219
+ * Options controlling a `runDoctorAdopt` invocation.
220
+ *
221
+ * @public
222
+ */
223
+ interface DoctorAdoptOptions {
224
+ /** Skip prompting and write nothing — list-only audit mode. */
225
+ nonInteractive?: boolean;
226
+ /** Skip prompting and bulk-adopt every orphan as `source_type='user'`. */
227
+ autoUserAdopt?: boolean;
228
+ /**
229
+ * Loads the set of skill names already known to the registry.
230
+ *
231
+ * Production wiring opens `skills.db` via `openCleoDb('skills')`; tests
232
+ * inject a sandbox-scoped reader.
233
+ */
234
+ loadRegisteredNames: () => ReadonlySet<string> | Promise<ReadonlySet<string>>;
235
+ /**
236
+ * Persists a single `user-adopt` decision to `skills.db`.
237
+ *
238
+ * Production wiring calls `upsertSkillRow` from `@cleocode/core/store`;
239
+ * tests inject a sandbox writer.
240
+ */
241
+ recordRow: RecordRowFn;
242
+ /** Test-only injection of a readline-compatible prompt. */
243
+ prompt?: (orphan: OrphanRecord) => Promise<OrphanDecision>;
244
+ /** Test-only opt-out of writing the audit log to disk. */
245
+ skipAuditLog?: boolean;
246
+ /** Test-only override for the discovery step. */
247
+ discoverFn?: (registeredNames: ReadonlySet<string>) => OrphanRecord[];
248
+ }
249
+ /**
250
+ * Execute the doctor-adopt workflow and return a structured result.
251
+ *
252
+ * @remarks
253
+ * Designed for both CLI invocation (from {@link registerSkillsDoctorAdopt})
254
+ * and direct testing — every side effect is overridable via
255
+ * {@link DoctorAdoptOptions}. The function never throws on per-orphan
256
+ * failures; instead each failure produces an `applied=false` entry with a
257
+ * refusal payload, so the caller gets a complete report even on partial
258
+ * failure.
259
+ *
260
+ * @param options - Mode flags + dependency-injected callbacks. The
261
+ * `loadRegisteredNames` and `recordRow` callbacks are MANDATORY so the
262
+ * caller (cleo dispatch or test harness) owns the sqlite open via the
263
+ * chokepoint.
264
+ * @returns The populated `DoctorAdoptResult`.
265
+ *
266
+ * @public
267
+ */
268
+ declare function runDoctorAdopt(options: DoctorAdoptOptions): Promise<DoctorAdoptResult>;
269
+ /**
270
+ * Default skill-name loader bound at CLI dispatch time.
271
+ *
272
+ * @remarks
273
+ * Re-exported so the cleo dispatch layer can construct it once and inject
274
+ * the same instance into {@link runDoctorAdopt}.
275
+ *
276
+ * @public
277
+ */
278
+ type RegisteredNamesLoader = () => ReadonlySet<string> | Promise<ReadonlySet<string>>;
279
+ /**
280
+ * Adapter callbacks the CLI registrar needs to satisfy
281
+ * {@link DoctorAdoptOptions}'s mandatory deps.
282
+ *
283
+ * @remarks
284
+ * The caamp CLI (`caamp skills doctor adopt-orphans`) supplies a no-op pair
285
+ * — caamp is the registry-author-tool and never touches a live skills.db.
286
+ * The cleo CLI overrides both with chokepoint-routed implementations.
287
+ *
288
+ * @public
289
+ */
290
+ interface DoctorAdoptCliAdapters {
291
+ loadRegisteredNames: RegisteredNamesLoader;
292
+ recordRow: RecordRowFn;
293
+ }
294
+ /**
295
+ * Standalone-`caamp` defaults — no DB access, every directory is an orphan.
296
+ *
297
+ * @remarks
298
+ * In the standalone caamp CLI, there's no skills.db (caamp is the
299
+ * registry-author tool, not the user-runtime). We treat every directory as
300
+ * an orphan and refuse all user-adopt writes by surfacing an explanatory
301
+ * error through `recordRow`. The cleo CLI overrides this with the real
302
+ * chokepoint-routed adapters.
303
+ *
304
+ * @public
305
+ */
306
+ declare const caampStandaloneAdapters: DoctorAdoptCliAdapters;
307
+ /**
308
+ * Register the `skills doctor adopt-orphans` subcommand on the parent
309
+ * `skills` Commander group.
310
+ *
311
+ * @remarks
312
+ * The handler creates the `doctor` subgroup if it doesn't already exist on
313
+ * the parent, so registration order is tolerant of co-registration with
314
+ * `registerSkillsDoctor` (T9655 bridge). Adapters default to
315
+ * {@link caampStandaloneAdapters} which surface a clear error — pass the
316
+ * cleo-chokepoint adapters when wiring under `packages/cleo/`.
317
+ *
318
+ * Default output is LAFS JSON. Pass `--human` for the colorised summary.
319
+ *
320
+ * @param parent - The parent `skills` Command from
321
+ * {@link registerSkillsCommands}.
322
+ * @param adapters - DB read/write hooks. Defaults to
323
+ * {@link caampStandaloneAdapters} so the standalone caamp CLI surfaces a
324
+ * helpful error rather than silently no-op'ing.
325
+ *
326
+ * @example
327
+ * ```bash
328
+ * cleo skills doctor adopt-orphans # interactive
329
+ * cleo skills doctor adopt-orphans --non-interactive
330
+ * cleo skills doctor adopt-orphans --auto-user-adopt --json
331
+ * ```
332
+ *
333
+ * @public
334
+ */
335
+ declare function registerSkillsDoctorAdopt(parent: Command, adapters?: DoctorAdoptCliAdapters): void;
336
+
337
+ /**
338
+ * `cleo skills doctor bridge` — single bridge symlink + per-skill symlink removal.
339
+ *
340
+ * @remarks
341
+ * Implements the canonical discovery topology described in
342
+ * `docs/architecture/SG-CLEO-SKILLS-architecture-v3.md` §1:
343
+ *
344
+ * - `~/.cleo/skills/<name>/` is the per-user install root (Sphere A + B).
345
+ * - `~/.claude/skills/agents-shared/<name>` is a symlink INTO `~/.cleo/skills/`
346
+ * for each installed skill — Claude Code's hardcoded discovery mount.
347
+ * - `~/.agents/skills` is the SINGLE bridge symlink → `~/.claude/skills/agents-shared`
348
+ * used by every non-Claude harness (Cursor, Aider, Codeium, etc.).
349
+ *
350
+ * The bridge command takes a host machine from any pre-v3 state and:
351
+ *
352
+ * 1. Ensures `~/.claude/skills/agents-shared/` exists (mkdir -p).
353
+ * 2. Creates a symlink under `agents-shared/` for every skill currently in
354
+ * `~/.cleo/skills/` whose target is missing or wrong.
355
+ * 3. Atomically replaces `~/.agents/skills` with a symlink to
356
+ * `~/.claude/skills/agents-shared`. If the existing `~/.agents/skills` is a
357
+ * REAL directory with contents, the command refuses without `--force` and
358
+ * backs up to `~/.cleo/backups/agents-skills-pre-bridge-YYYYMMDD-HHmmss/`
359
+ * when `--force` is supplied.
360
+ * 4. Rips per-skill symlinks under `~/.claude/skills/*` that point OUTSIDE
361
+ * `agents-shared/` (orphans from the old per-skill fan-out model).
362
+ *
363
+ * The handler is pure-functional with a dependency-injected `homeDir` so it
364
+ * can be exercised against tmpfs fixtures in unit tests without touching the
365
+ * real user environment.
366
+ *
367
+ * @see {@link docs/architecture/SG-CLEO-SKILLS-architecture-v3.md} §1
368
+ * @task T9655
369
+ * @epic T9571
370
+ * @public
371
+ */
372
+
373
+ /**
374
+ * One symlink that was created (or would be created in `--dry-run`).
375
+ *
376
+ * @public
377
+ */
378
+ interface BridgeSymlinkRecord {
379
+ /** Skill basename, e.g. `ct-orchestrator`. */
380
+ name: string;
381
+ /** Absolute path of the symlink under `~/.claude/skills/agents-shared/`. */
382
+ linkPath: string;
383
+ /** Absolute path of the symlink target inside `~/.cleo/skills/`. */
384
+ target: string;
385
+ }
386
+ /**
387
+ * One per-skill symlink that was removed (or would be removed in `--dry-run`).
388
+ *
389
+ * @public
390
+ */
391
+ interface PerSkillSymlinkRemoval {
392
+ /** Absolute path of the symlink that was removed. */
393
+ linkPath: string;
394
+ /** Resolved target the symlink pointed at, or `null` when unreadable. */
395
+ previousTarget: string | null;
396
+ }
397
+ /**
398
+ * LAFS-shaped result payload emitted by {@link runDoctorBridge}.
399
+ *
400
+ * @public
401
+ */
402
+ interface DoctorBridgeResult {
403
+ /** Whether this run materially changed disk state. `false` on idempotent re-runs. */
404
+ bridgeCreated: boolean;
405
+ /**
406
+ * Whether `~/.agents/skills` is now a symlink to `~/.claude/skills/agents-shared`.
407
+ *
408
+ * @remarks
409
+ * Always `true` after a successful run. `false` only when `--dry-run` was
410
+ * requested and the bridge had to be created.
411
+ */
412
+ bridgeSymlinkActive: boolean;
413
+ /** Symlinks created under `~/.claude/skills/agents-shared/` (or planned in dry-run). */
414
+ perSkillSymlinksCreated: BridgeSymlinkRecord[];
415
+ /** Per-skill symlinks under `~/.claude/skills/*` that were removed (or planned). */
416
+ perSkillSymlinksRemoved: PerSkillSymlinkRemoval[];
417
+ /**
418
+ * Absolute backup path when the existing `~/.agents/skills` real dir was
419
+ * relocated to make room for the bridge symlink. `null` when no backup was
420
+ * needed.
421
+ */
422
+ backupPath: string | null;
423
+ /** `true` when `--dry-run` was passed and no disk state was mutated. */
424
+ dryRun: boolean;
425
+ /** Resolved skills root, e.g. `~/.cleo/skills`. */
426
+ skillsRoot: string;
427
+ /** Resolved bridge target, e.g. `~/.claude/skills/agents-shared`. */
428
+ bridgeTarget: string;
429
+ /** Resolved bridge symlink path, e.g. `~/.agents/skills`. */
430
+ bridgePath: string;
431
+ }
432
+ /**
433
+ * Dependency-injected options accepted by {@link runDoctorBridge}.
434
+ *
435
+ * @public
436
+ */
437
+ interface DoctorBridgeOptions {
438
+ /**
439
+ * Override the home directory. Defaults to {@link homedir}.
440
+ *
441
+ * @remarks
442
+ * Tests pass a tmpfs root so the bridge logic can be exercised end-to-end
443
+ * without touching the real user environment.
444
+ */
445
+ homeDir?: string;
446
+ /**
447
+ * Allow the command to clobber an existing real `~/.agents/skills` directory.
448
+ *
449
+ * @remarks
450
+ * When `false` (the default) and `~/.agents/skills` is a non-empty real
451
+ * directory, the command refuses with `E_AGENTS_SKILLS_REAL_DIR` to preserve
452
+ * user data. When `true`, the directory is moved to
453
+ * `~/.cleo/backups/agents-skills-pre-bridge-<ts>/` before the bridge symlink
454
+ * is created.
455
+ *
456
+ * @defaultValue `false`
457
+ */
458
+ force?: boolean;
459
+ /**
460
+ * Plan-only mode. When `true`, no disk state is mutated; the result still
461
+ * lists what WOULD happen.
462
+ *
463
+ * @defaultValue `false`
464
+ */
465
+ dryRun?: boolean;
466
+ }
467
+ /**
468
+ * Error thrown when {@link runDoctorBridge} refuses to clobber a real
469
+ * `~/.agents/skills` directory and `--force` was not passed.
470
+ *
471
+ * @public
472
+ */
473
+ declare class AgentsSkillsRealDirError extends Error {
474
+ /** LAFS error code surfaced by the CLI. */
475
+ readonly code: "E_AGENTS_SKILLS_REAL_DIR";
476
+ /** Resolved path of the offending real directory. */
477
+ readonly agentsSkillsPath: string;
478
+ /** Number of immediate entries in the offending directory. */
479
+ readonly entryCount: number;
480
+ /**
481
+ * Construct an `AgentsSkillsRealDirError`.
482
+ *
483
+ * @param agentsSkillsPath - Path to the real `~/.agents/skills` directory.
484
+ * @param entryCount - Number of entries inside the directory.
485
+ */
486
+ constructor(agentsSkillsPath: string, entryCount: number);
487
+ }
488
+ /**
489
+ * Generate a deterministic backup-suffix timestamp `YYYYMMDD-HHmmss` (UTC).
490
+ *
491
+ * @remarks
492
+ * Pulled out as a helper so callers (and tests) can deterministically compute
493
+ * the expected backup path without re-implementing the format. The string is
494
+ * UTC so backups taken on different machines round-trip identically.
495
+ *
496
+ * @returns Timestamp suffix string for backup directory naming.
497
+ */
498
+ declare function buildBackupTimestamp(): string;
499
+ /**
500
+ * Execute the bridge flow described in the module docblock.
501
+ *
502
+ * @remarks
503
+ * Order of operations:
504
+ *
505
+ * 1. Ensure `~/.claude/skills/agents-shared/` exists.
506
+ * 2. For each skill in `~/.cleo/skills/`, ensure
507
+ * `~/.claude/skills/agents-shared/<name>` → `~/.cleo/skills/<name>` exists.
508
+ * 3. Rip every per-skill entry under `~/.claude/skills/` that is a symlink
509
+ * pointing OUTSIDE `agents-shared/` — those are orphans from the old
510
+ * per-skill fan-out model and must be deleted.
511
+ * 4. Replace `~/.agents/skills` with a symlink to `~/.claude/skills/agents-shared`.
512
+ * If it is currently a real directory, refuse unless `options.force` is
513
+ * `true`, in which case back up to
514
+ * `~/.cleo/backups/agents-skills-pre-bridge-<ts>/` first.
515
+ *
516
+ * Idempotency invariant: re-running on a fully-bridged tree returns
517
+ * `{ bridgeCreated: false, bridgeSymlinkActive: true, perSkillSymlinksCreated: [], perSkillSymlinksRemoved: [], backupPath: null }`.
518
+ *
519
+ * @param options - Dependency-injected options (homeDir / force / dry-run).
520
+ * @returns Materialized {@link DoctorBridgeResult} reflecting the run.
521
+ * @throws AgentsSkillsRealDirError when `~/.agents/skills` is a non-empty real
522
+ * directory and `options.force` is not set.
523
+ *
524
+ * @example
525
+ * ```typescript
526
+ * import { runDoctorBridge } from '@cleocode/caamp';
527
+ *
528
+ * const result = await runDoctorBridge({ homeDir: '/tmp/test-home' });
529
+ * console.log(result.perSkillSymlinksCreated.length); // # of new bridge symlinks
530
+ * ```
531
+ *
532
+ * @public
533
+ */
534
+ declare function runDoctorBridge(options?: DoctorBridgeOptions): Promise<DoctorBridgeResult>;
535
+
5
536
  /**
6
537
  * Priority tier identifier stored in registry.json.
7
538
  *
@@ -3002,10 +3533,103 @@ declare function removeConfig(filePath: string, format: ConfigFormat, key: strin
3002
3533
  /**
3003
3534
  * Skill installer - canonical + symlink model
3004
3535
  *
3005
- * Skills are stored once in a canonical location (.agents/skills/<name>/)
3006
- * and symlinked to each target agent's skills directory.
3536
+ * Skills are stored once in a canonical location (`~/.cleo/skills/<name>/`
3537
+ * per architecture-v3 §1, with legacy `~/.local/share/agents/skills/` as a
3538
+ * read-only fallback for one release cycle) and symlinked to each target
3539
+ * agent's skills directory.
3540
+ *
3541
+ * @task T9659
3542
+ * @epic T9571
3543
+ * @saga T9560
3007
3544
  */
3008
3545
 
3546
+ /**
3547
+ * Source-type discriminator emitted with {@link SkillRowData}.
3548
+ *
3549
+ * @remarks
3550
+ * Mirrors the `source_type` column on the `skills` table defined in
3551
+ * architecture-v3 §4. Kept as a local string-literal union (NOT a
3552
+ * `@cleocode/core` import) so caamp stays free of a circular dep on core —
3553
+ * the dispatch layer in `packages/cleo/` is responsible for plugging the
3554
+ * `upsertSkillRow` callback that consumes this shape.
3555
+ *
3556
+ * @public
3557
+ */
3558
+ type SkillRowSourceType = 'canonical' | 'user' | 'community' | 'agent-created';
3559
+ /**
3560
+ * Provenance payload emitted by {@link installSkill} after a successful copy.
3561
+ *
3562
+ * @remarks
3563
+ * The CAAMP installer ONLY emits this shape — it never writes to
3564
+ * `skills.db` directly. The dispatch layer in `packages/cleo/` (where it's
3565
+ * legal to import from `@cleocode/core`) plugs an `upsertSkillRow` callback
3566
+ * via {@link InstallSkillOptions.recordRow}. This keeps caamp free of a
3567
+ * `@cleocode/core` dependency (mirrors the migration callback pattern
3568
+ * established by T9653 — see `migration.ts`).
3569
+ *
3570
+ * @public
3571
+ */
3572
+ interface SkillRowData {
3573
+ /** Skill folder basename (matches `skills.name` column). */
3574
+ name: string;
3575
+ /** Resolved canonical install path under `~/.cleo/skills/<name>/`. */
3576
+ installPath: string;
3577
+ /** Source URL or identifier (matches `skills.source_url`). */
3578
+ sourceUrl: string | null;
3579
+ /**
3580
+ * Source provenance discriminator (matches `skills.source_type`).
3581
+ *
3582
+ * @remarks
3583
+ * Set to `'canonical'` for skills whose name appears in the bundled
3584
+ * Sphere A manifest; `'community'` for marketplace / GitHub-clone installs;
3585
+ * `'user'` for everything else (local-path installs, library installs).
3586
+ * Architecture-v3 §4 enumerates the full set.
3587
+ */
3588
+ sourceType: SkillRowSourceType;
3589
+ }
3590
+ /**
3591
+ * Optional knobs accepted by {@link installSkill}.
3592
+ *
3593
+ * @remarks
3594
+ * Encoded as an interface so future T-STORE follow-ups (e.g. `pinned`,
3595
+ * `version`) can be added without churning the call sites.
3596
+ *
3597
+ * @public
3598
+ */
3599
+ interface InstallSkillOptions {
3600
+ /**
3601
+ * Per-install sink invoked after a successful canonical copy.
3602
+ *
3603
+ * @remarks
3604
+ * Caamp NEVER imports `@cleocode/core` directly — the dispatch layer in
3605
+ * `packages/cleo/` plugs `upsertSkillRow` here so installs are recorded
3606
+ * to `~/.cleo/skills.db`. Defaults to a no-op when omitted. May be sync
3607
+ * or async; thrown errors propagate to the caller.
3608
+ */
3609
+ recordRow?: (row: SkillRowData) => Promise<void> | void;
3610
+ /**
3611
+ * Explicit `sourceUrl` to record on the row.
3612
+ *
3613
+ * @remarks
3614
+ * When omitted, falls back to the `sourcePath` argument. Callers that
3615
+ * resolve a library or marketplace identifier (e.g. `library:ct-foo` or
3616
+ * `https://github.com/owner/repo`) BEFORE copying to a tmpdir should set
3617
+ * this so the row preserves the original provenance string instead of
3618
+ * the disposable filesystem path.
3619
+ */
3620
+ sourceUrl?: string | null;
3621
+ /**
3622
+ * Explicit `sourceType` to record on the row.
3623
+ *
3624
+ * @remarks
3625
+ * When omitted, the type is heuristically inferred from
3626
+ * {@link InstallSkillOptions.sourceUrl} (or `sourcePath` as a fallback)
3627
+ * via {@link inferSkillSourceType}. Dispatch-layer callers that know the
3628
+ * authoritative provenance (e.g. catalog → `'canonical'`, GitHub URL →
3629
+ * `'community'`) SHOULD set this explicitly to bypass the heuristic.
3630
+ */
3631
+ sourceType?: SkillRowSourceType;
3632
+ }
3009
3633
  /**
3010
3634
  * Result of installing a skill to the canonical location and linking to agents.
3011
3635
  *
@@ -3032,6 +3656,29 @@ interface SkillInstallResult {
3032
3656
  /** Whether at least one agent was successfully linked. */
3033
3657
  success: boolean;
3034
3658
  }
3659
+ /**
3660
+ * Heuristic source-type classifier for installs that don't carry an explicit
3661
+ * `source_type`.
3662
+ *
3663
+ * @remarks
3664
+ * Pure string inspection — keeps the installer free of network calls and
3665
+ * filesystem reads. The dispatch layer can ALWAYS override the result by
3666
+ * passing an explicit row through {@link InstallSkillOptions.recordRow}.
3667
+ *
3668
+ * Classification rules:
3669
+ *
3670
+ * 1. `library:<name>` → `'canonical'` (installed from the bundled Sphere A
3671
+ * skill library — `packages/skills/skills/`).
3672
+ * 2. `github.com` / `gitlab.com` / scoped `@author/name` → `'community'`.
3673
+ * 3. Anything else (local paths, opaque values) → `'user'`.
3674
+ *
3675
+ * @param sourceUrl - The source identifier passed to {@link installSkill}.
3676
+ * `null` is treated as `'user'`.
3677
+ * @returns The inferred source-type discriminator.
3678
+ *
3679
+ * @public
3680
+ */
3681
+ declare function inferSkillSourceType(sourceUrl: string | null | undefined): SkillRowSourceType;
3035
3682
  /**
3036
3683
  * Install a skill from a local path to the canonical location and link to agents.
3037
3684
  *
@@ -3039,24 +3686,45 @@ interface SkillInstallResult {
3039
3686
  * Copies the skill directory to the canonical skills directory and creates symlinks
3040
3687
  * (or copies on Windows) from each provider's skills directory to the canonical path.
3041
3688
  *
3689
+ * **T9659** — when `options.recordRow` is supplied, the callback is invoked
3690
+ * with a {@link SkillRowData} payload after the canonical copy lands and
3691
+ * BEFORE provider linking. This is the integration seam that the cleo
3692
+ * dispatch layer uses to plug `upsertSkillRow` from
3693
+ * `@cleocode/core/store/skills-db` into `~/.cleo/skills.db`. The row is
3694
+ * recorded regardless of whether subsequent provider linking succeeds — the
3695
+ * canonical install is itself the durable artefact.
3696
+ *
3042
3697
  * @param sourcePath - Local path to the skill directory to install
3043
3698
  * @param skillName - Name for the installed skill
3044
3699
  * @param providers - Target providers to link the skill to
3045
3700
  * @param isGlobal - Whether to link to global or project skill directories
3046
3701
  * @param projectDir - Project directory (defaults to `process.cwd()`)
3702
+ * @param options - Optional callbacks (incl. `recordRow` for `skills.db`)
3047
3703
  * @returns Install result with linked agents and any errors
3048
3704
  *
3049
3705
  * @example
3050
3706
  * ```typescript
3051
- * const result = await installSkill("/tmp/my-skill", "my-skill", providers, true, "/my/project");
3052
- * if (result.success) {
3053
- * console.log(`Linked to: ${result.linkedAgents.join(", ")}`);
3054
- * }
3707
+ * const result = await installSkill(
3708
+ * "/tmp/my-skill",
3709
+ * "my-skill",
3710
+ * providers,
3711
+ * true,
3712
+ * "/my/project",
3713
+ * {
3714
+ * recordRow: async (row) => upsertSkillRow({
3715
+ * name: row.name,
3716
+ * installPath: row.installPath,
3717
+ * sourceType: row.sourceType,
3718
+ * sourceUrl: row.sourceUrl,
3719
+ * installedAt: new Date().toISOString(),
3720
+ * }),
3721
+ * },
3722
+ * );
3055
3723
  * ```
3056
3724
  *
3057
3725
  * @public
3058
3726
  */
3059
- declare function installSkill(sourcePath: string, skillName: string, providers: Provider[], isGlobal: boolean, projectDir?: string): Promise<SkillInstallResult>;
3727
+ declare function installSkill(sourcePath: string, skillName: string, providers: Provider[], isGlobal: boolean, projectDir?: string, options?: InstallSkillOptions): Promise<SkillInstallResult>;
3060
3728
  /**
3061
3729
  * Remove a skill from the canonical location and all agent symlinks.
3062
3730
  *
@@ -5630,20 +6298,73 @@ declare function getAgentsHome(): string;
5630
6298
  * @public
5631
6299
  */
5632
6300
  declare function getProjectAgentsDir(projectRoot?: string): string;
6301
+ /**
6302
+ * Reset the cached deprecation-warning flag.
6303
+ *
6304
+ * @remarks
6305
+ * Test-only seam. Production code should never call this.
6306
+ *
6307
+ * @internal
6308
+ */
6309
+ declare function _resetLegacySkillsWarning(): void;
6310
+ /**
6311
+ * Returns the canonical user-machine skills install root.
6312
+ *
6313
+ * @remarks
6314
+ * Per architecture-v3 §1 the new SSoT for ALL installed skills is
6315
+ * `~/.cleo/skills/` (replacing the legacy XDG path
6316
+ * `~/.local/share/agents/skills/`). This resolver implements the migration
6317
+ * contract: it ALWAYS returns the new SSoT when it exists, falls through to
6318
+ * the legacy path as a read-only fallback for one release cycle, and
6319
+ * defaults to the new SSoT on a fresh install so first-write lands in the
6320
+ * correct location.
6321
+ *
6322
+ * Resolution order:
6323
+ *
6324
+ * 1. `~/.cleo/skills/` (new SSoT — preferred). Returned when it exists.
6325
+ * 2. `getAgentsHome()/skills` (legacy XDG via `AGENTS_HOME` /
6326
+ * `~/.local/share/agents/skills/`). Returned when the new SSoT is missing
6327
+ * but the legacy directory exists. Emits a one-shot stderr deprecation
6328
+ * warning so the user is prompted to migrate.
6329
+ * 3. `~/.cleo/skills/` (new SSoT) on a fresh install when neither exists,
6330
+ * so first-write creates the correct directory.
6331
+ *
6332
+ * **Test override:** when the `AGENTS_HOME` env var is set explicitly (the
6333
+ * primary test seam used by `skills-installer.test.ts`), the resolver SKIPS
6334
+ * step 1 and returns `getAgentsHome()/skills` directly. This preserves the
6335
+ * existing test surface (tmpdirs via `AGENTS_HOME`) while production paths
6336
+ * resolve through the new SSoT chain.
6337
+ *
6338
+ * @returns Absolute path to the resolved canonical skills directory
6339
+ *
6340
+ * @example
6341
+ * ```typescript
6342
+ * const dir = getCanonicalSkillsRoot();
6343
+ * // Fresh install: "/home/user/.cleo/skills"
6344
+ * // Legacy install + warning: "/home/user/.local/share/agents/skills"
6345
+ * // Test (AGENTS_HOME=/tmp/foo): "/tmp/foo/skills"
6346
+ * ```
6347
+ *
6348
+ * @task T9659
6349
+ * @public
6350
+ */
6351
+ declare function getCanonicalSkillsRoot(): string;
5633
6352
  /**
5634
6353
  * Returns the canonical skills storage directory path.
5635
6354
  *
5636
6355
  * @remarks
5637
6356
  * Skills are stored once in this canonical directory and symlinked into
5638
6357
  * provider-specific locations. This is the single source of truth for
5639
- * installed skill files.
6358
+ * installed skill files. **T9659 — this now delegates to
6359
+ * {@link getCanonicalSkillsRoot} so the SSoT is `~/.cleo/skills/` with the
6360
+ * legacy XDG path as a read-only fallback per architecture-v3 §1.**
5640
6361
  *
5641
6362
  * @returns The absolute path to the canonical skills directory
5642
6363
  *
5643
6364
  * @example
5644
6365
  * ```typescript
5645
6366
  * const dir = getCanonicalSkillsDir();
5646
- * // e.g., "/home/user/.local/share/caamp/skills"
6367
+ * // e.g., "/home/user/.cleo/skills" (new SSoT)
5647
6368
  * ```
5648
6369
  *
5649
6370
  * @public
@@ -8331,4 +9052,4 @@ declare function parseSource(input: string): ParsedSource;
8331
9052
  */
8332
9053
  declare function isMarketplaceScoped(input: string): boolean;
8333
9054
 
8334
- export { type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, CANONICAL_HOOK_EVENTS, 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, type EnsureProviderInstructionFileOptions, type EnsureProviderInstructionFileResult, type ExclusivityMode, 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 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 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 RegistryHarnessKind, type RegistryHookCatalog, type RegistryHookFormat, type RemoveMcpServerOptions, type RemoveMcpServerResult, 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 SkillsPrecedence, type SourceType, type SpawnAdapter, type SpawnMechanism, type SpawnOptions, type SpawnResult, type SubagentHandle, type SubagentResult, type SubagentTask, type TransportType, type ValidateCantProfileResult, type ValidationIssue, type ValidationResult, type WriteAgentFileOptions, type WriteAgentFileResult, _resetPlatformPathsCache, buildHookMatrix, buildInjectionContent, buildLibraryFromFiles, buildSkillsMap, catalog, checkAllInjections, checkAllSkillIntegrity, checkAllSkillUpdates, checkInjection, checkSkillIntegrity, checkSkillUpdate, 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, getCanonicalSkillsDir, 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, inject, injectAll, installBatchWithRollback, installMcpServer, installSkill, isCaampOwnedSkill, isExclusivityMode, isMarketplaceScoped, isQuiet, isVerbose, listAllMcpServers, listCanonicalSkills, listMcpServers, loadLibraryFromModule, normalizeRecommendationCriteria, parseCaampBlocks, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, recommendSkills, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, removeConfig, removeInjection, removeMcpServer, removeMcpServerFromAll, removeSkill, removeSkillFromLock, resetDetectionCache, resetExclusivityModeOverride, resolveAlias, resolveDefaultTargetProviders, resolveMcpConfigPath, resolveNativeEvent, resolveProviderSkillsDirs, resolveRegistryTemplatePath, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setExclusivityMode, setQuiet, setVerbose, shouldOverrideSkill, supportsHook, toCanonical, toNative, toNativeBatch, toSarif, tokenizeCriteriaValue, translateToAll, updateInstructionsSingleOperation, validateInstructionIntegrity, validateRecommendationCriteria, validateSkill, writeAgentFileToAllProviders, writeConfig };
9055
+ export { type AdoptedSkillRowData, AgentsSkillsRealDirError, type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, type BridgeSymlinkRecord, CANONICAL_HOOK_EVENTS, 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, type DoctorAdoptCliAdapters, type DoctorAdoptOptions, type DoctorAdoptResult, type DoctorBridgeOptions, type DoctorBridgeResult, EXCLUSIVITY_MODE_ENV_VAR, type EnsureProviderInstructionFileOptions, type EnsureProviderInstructionFileResult, type ExclusivityMode, 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 NormalizedHookEvent, type NormalizedRecommendationCriteria, type OrphanActionResult, type OrphanDecision, type OrphanRecord, type OrphanRefusal, type ParsedSource, type PerSkillSymlinkRemoval, 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 RecordRowFn, type RegisteredNamesLoader, type RegistryHarnessKind, type RegistryHookCatalog, type RegistryHookFormat, type RemoveMcpServerOptions, type RemoveMcpServerResult, 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 TransportType, type ValidateCantProfileResult, type ValidationIssue, type ValidationResult, type WriteAgentFileOptions, type WriteAgentFileResult, _resetLegacySkillsWarning, _resetPlatformPathsCache, applyDecision, buildBackupTimestamp, buildHookMatrix, buildInjectionContent, buildLibraryFromFiles, buildSkillsMap, caampStandaloneAdapters, catalog, checkAllInjections, checkAllSkillIntegrity, checkAllSkillUpdates, checkInjection, checkSkillIntegrity, checkSkillUpdate, clearRegisteredLibrary, dedupeFile, dedupeFiles, deepMerge, detectAllProviders, detectMcpInstallations, detectProjectProviders, detectProvider, discoverOrphans, discoverSkill, discoverSkills, ensureAllProviderInstructionFiles, ensureDir, ensureProviderInstructionFile, formatSkillRecommendations, generateInjectionContent, generateSkillsSection, getAgentsConfigPath, getAgentsHome, getAgentsInstructFile, getAgentsLinksDir, getAgentsMcpDir, getAgentsMcpServersPath, getAgentsSpecDir, getAgentsWikiDir, getAllCanonicalEvents, getAllHarnesses, getAllProviders, getCanonicalEvent, getCanonicalEventsByCategory, getCanonicalSkillsDir, getCanonicalSkillsRoot, 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, isCaampOwnedSkill, isExclusivityMode, isMarketplaceScoped, isQuiet, isVerbose, listAllMcpServers, listCanonicalSkills, listMcpServers, loadLibraryFromModule, normalizeRecommendationCriteria, parseCaampBlocks, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, recommendSkills, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, registerSkillsDoctorAdopt, removeConfig, removeInjection, removeMcpServer, removeMcpServerFromAll, removeSkill, removeSkillFromLock, resetDetectionCache, resetExclusivityModeOverride, resolveAlias, resolveDefaultTargetProviders, resolveMcpConfigPath, resolveNativeEvent, resolveProviderSkillsDirs, resolveRegistryTemplatePath, runDoctorAdopt, runDoctorBridge, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setExclusivityMode, setQuiet, setVerbose, shouldOverrideSkill, supportsHook, toCanonical, toNative, toNativeBatch, toSarif, tokenizeCriteriaValue, translateToAll, updateInstructionsSingleOperation, validateInstructionIntegrity, validateRecommendationCriteria, validateSkill, writeAgentFileToAllProviders, writeAuditLog, writeConfig };