@cleocode/caamp 2026.4.3 → 2026.4.5

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,3 +1,55 @@
1
+ /**
2
+ * Priority tier identifier stored in registry.json.
3
+ *
4
+ * @remarks
5
+ * Providers are tiered to express selection precedence and tooling defaults.
6
+ * Exactly **one** provider in a registry MAY have the `"primary"` tier — it
7
+ * is the first-class harness and default target when no `--agent` flag is
8
+ * given. The registry loader does not enforce this cardinality rule; instead
9
+ * {@link RegistryProvider.priority} consumers such as `getPrimaryProvider()`
10
+ * expect either zero or one provider with `"primary"` priority.
11
+ *
12
+ * @public
13
+ */
14
+ type ProviderPriority = 'primary' | 'high' | 'medium' | 'low';
15
+ /**
16
+ * Lifecycle status identifier stored in registry.json.
17
+ *
18
+ * @remarks
19
+ * The registry uses four discrete lifecycle states. The enum is duplicated
20
+ * here (and in `src/types.ts`) so the raw and resolved Provider shapes can
21
+ * share precise typing without circular imports.
22
+ *
23
+ * @public
24
+ */
25
+ type ProviderStatus = 'active' | 'beta' | 'deprecated' | 'planned';
26
+ /**
27
+ * Supported MCP config file formats.
28
+ *
29
+ * @remarks
30
+ * These mirror the wider {@link ConfigFormat} enum in `src/types.ts` but
31
+ * are restated here to avoid importing the resolved runtime type into the
32
+ * raw JSON schema definitions.
33
+ *
34
+ * @public
35
+ */
36
+ type McpConfigFormat = 'json' | 'jsonc' | 'yaml' | 'toml';
37
+ /**
38
+ * MCP transport protocols a provider may advertise.
39
+ *
40
+ * @public
41
+ */
42
+ type McpTransportType = 'stdio' | 'sse' | 'http' | 'websocket';
43
+ /**
44
+ * Harness role category for a primary or standalone harness.
45
+ *
46
+ * @remarks
47
+ * - `"orchestrator"` — can spawn subagents and coordinate multi-provider workflows.
48
+ * - `"standalone"` — runs as a single agent without delegating to spawn targets.
49
+ *
50
+ * @public
51
+ */
52
+ type RegistryHarnessKind = 'orchestrator' | 'standalone';
1
53
  /**
2
54
  * How a provider resolves skill file precedence between vendor and agents directories.
3
55
  *
@@ -27,18 +79,44 @@ type SkillsPrecedence = 'vendor-only' | 'agents-canonical' | 'agents-first' | 'a
27
79
  * @public
28
80
  */
29
81
  type HookEvent = string;
82
+ /**
83
+ * The on-disk layout of a provider's hook configuration.
84
+ *
85
+ * @remarks
86
+ * - `"json"`, `"yaml"`, `"toml"`, `"javascript"` — single configuration file
87
+ * consumed by the provider.
88
+ * - `"typescript-directory"` — a directory of `.ts` extension files (Pi's model).
89
+ *
90
+ * @public
91
+ */
92
+ type RegistryHookFormat = 'json' | 'yaml' | 'toml' | 'javascript' | 'typescript-directory';
93
+ /**
94
+ * Which native event catalog a provider's hook system uses.
95
+ *
96
+ * @remarks
97
+ * - `"canonical"` — uses the core CAAMP `canonicalEvents` catalog from
98
+ * `providers/hook-mappings.json`.
99
+ * - `"pi"` — uses the Pi-specific catalog (sibling entry to `canonicalEvents`)
100
+ * that enumerates Pi's native lifecycle events such as `before_agent_start`
101
+ * and `resources_discover`.
102
+ *
103
+ * @public
104
+ */
105
+ type RegistryHookCatalog = 'canonical' | 'pi';
30
106
  /**
31
107
  * Mechanism a provider uses to spawn subagents.
32
108
  *
33
109
  * @remarks
34
110
  * - `"native"` - Built-in spawning via the provider's own runtime.
111
+ * - `"native-child-process"` - Built-in spawning that forks a local child
112
+ * process (Pi's `pi --mode json -p --no-session` pattern).
35
113
  * - `"mcp"` - Spawning via MCP tool calls.
36
114
  * - `"cli"` - Spawning via CLI subprocess invocation.
37
115
  * - `"api"` - Spawning via a remote API endpoint.
38
116
  *
39
117
  * @public
40
118
  */
41
- type SpawnMechanism = 'native' | 'mcp' | 'cli' | 'api';
119
+ type SpawnMechanism = 'native' | 'native-child-process' | 'mcp' | 'cli' | 'api';
42
120
 
43
121
  /**
44
122
  * SkillLibrary interface - SDK standard contract for skill libraries.
@@ -329,6 +407,7 @@ type ConfigFormat = 'json' | 'jsonc' | 'yaml' | 'toml';
329
407
  * - `"stdio"` - Standard input/output (local process)
330
408
  * - `"sse"` - Server-Sent Events (remote)
331
409
  * - `"http"` - HTTP/Streamable HTTP (remote)
410
+ * - `"websocket"` - WebSocket full-duplex (remote)
332
411
  *
333
412
  * @example
334
413
  * ```typescript
@@ -337,7 +416,7 @@ type ConfigFormat = 'json' | 'jsonc' | 'yaml' | 'toml';
337
416
  *
338
417
  * @public
339
418
  */
340
- type TransportType = 'stdio' | 'sse' | 'http';
419
+ type TransportType = 'stdio' | 'sse' | 'http' | 'websocket';
341
420
  /**
342
421
  * Method used to detect whether an AI agent is installed on the system.
343
422
  *
@@ -394,6 +473,57 @@ interface DetectionConfig {
394
473
  flatpakId?: string;
395
474
  }
396
475
 
476
+ /**
477
+ * Resolved MCP server integration metadata for a provider.
478
+ *
479
+ * @remarks
480
+ * Present only for providers that consume MCP servers via a per-agent
481
+ * config file. Providers that use extensions instead of MCP configs
482
+ * (e.g. Pi) omit this block. Template variables in paths are expanded
483
+ * at registry load time.
484
+ *
485
+ * @public
486
+ */
487
+ interface ProviderMcpCapability {
488
+ /** Dot-notation key path for MCP server config (e.g. `"mcpServers"`). */
489
+ configKey: string;
490
+ /** Resolved config file format. */
491
+ configFormat: ConfigFormat;
492
+ /** Resolved global config file path. */
493
+ configPathGlobal: string;
494
+ /** Project-relative config file path, or `null` if unsupported. */
495
+ configPathProject: string | null;
496
+ /** MCP transport protocols this provider supports. */
497
+ supportedTransports: TransportType[];
498
+ /** Whether the provider supports custom HTTP headers for remote MCP servers. */
499
+ supportsHeaders: boolean;
500
+ }
501
+ /**
502
+ * Resolved first-class harness capability for a provider.
503
+ *
504
+ * @remarks
505
+ * Present only for providers that act as orchestrators or standalone
506
+ * harnesses. Paths under {@link extensionsPath} and {@link globalExtensionsHub}
507
+ * are resolved with platform template expansion at load time.
508
+ *
509
+ * @public
510
+ */
511
+ interface ProviderHarnessCapability {
512
+ /** Harness kind (`"orchestrator"` or `"standalone"`). */
513
+ kind: RegistryHarnessKind;
514
+ /** Provider ids this harness can spawn as subagents. Empty for standalone. */
515
+ spawnTargets: string[];
516
+ /** Whether the harness drives a CleoOS conductor loop. */
517
+ supportsConductorLoop: boolean;
518
+ /** Whether the harness accepts stage guidance injection. */
519
+ supportsStageGuidance: boolean;
520
+ /** Whether the harness bridges CANT events. */
521
+ supportsCantBridge: boolean;
522
+ /** Resolved path to the harness's runtime extensions directory. */
523
+ extensionsPath: string;
524
+ /** Resolved CLEO-managed shared extensions hub path, if configured. */
525
+ globalExtensionsHub: string | null;
526
+ }
397
527
  /**
398
528
  * Resolved skills capability for a provider at runtime.
399
529
  *
@@ -417,18 +547,29 @@ interface ProviderSkillsCapability {
417
547
  *
418
548
  * @remarks
419
549
  * Describes which hook lifecycle events a provider supports and where
420
- * the hook configuration file is located. The hook format indicates how
421
- * the configuration should be read and written.
550
+ * the hook configuration file (or extensions directory) is located. The
551
+ * hook format indicates how the configuration should be read and written;
552
+ * the `"typescript-directory"` value denotes providers (like Pi) whose
553
+ * hooks are compiled from a directory of TypeScript files rather than
554
+ * a single config file.
422
555
  *
423
556
  * @public
424
557
  */
425
558
  interface ProviderHooksCapability {
426
559
  /** Hook lifecycle events this provider supports. */
427
560
  supported: HookEvent[];
428
- /** Resolved path to hook configuration file, or `null`. */
561
+ /** Resolved path to the hook configuration file or directory, or `null`. */
429
562
  hookConfigPath: string | null;
430
- /** Format of the hook config file. */
431
- hookFormat: 'json' | 'yaml' | 'toml' | 'javascript' | null;
563
+ /** Resolved project-relative hook configuration path, or `null`. */
564
+ hookConfigPathProject: string | null;
565
+ /** Format of the hook config. */
566
+ hookFormat: RegistryHookFormat | null;
567
+ /** Which native event catalog this provider's hooks are drawn from. */
568
+ nativeEventCatalog: RegistryHookCatalog;
569
+ /** Whether hooks may inject or modify the system prompt. */
570
+ canInjectSystemPrompt: boolean;
571
+ /** Whether hooks may block tool calls. */
572
+ canBlockTools: boolean;
432
573
  }
433
574
  /**
434
575
  * Resolved spawn capability for a provider at runtime.
@@ -451,18 +592,30 @@ interface ProviderSpawnCapability {
451
592
  supportsParallelSpawn: boolean;
452
593
  /** Mechanism used for spawning. */
453
594
  spawnMechanism: SpawnMechanism | null;
595
+ /**
596
+ * Literal command-line invocation used by the harness to spawn a child
597
+ * worker. Only meaningful when `spawnMechanism === "native-child-process"`.
598
+ */
599
+ spawnCommand: string[] | null;
454
600
  }
455
601
  /**
456
- * Aggregate provider capabilities for skills, hooks, and spawn.
602
+ * Aggregate provider capabilities for MCP, harness role, skills, hooks, and spawn.
457
603
  *
458
604
  * @remarks
459
- * Groups the three capability dimensions into a single object that is
460
- * always populated on the resolved {@link Provider} interface at runtime.
461
- * Unlike the raw registry type, all three fields are required here.
605
+ * Groups the capability dimensions into a single object on the resolved
606
+ * {@link Provider} interface at runtime. Skills, hooks, and spawn are
607
+ * always populated (with safe defaults when absent from the registry).
608
+ * MCP and harness are optional because not every provider is an MCP
609
+ * consumer (e.g. Pi uses extensions instead) and not every provider is
610
+ * a first-class harness (most are pure spawn targets).
462
611
  *
463
612
  * @public
464
613
  */
465
614
  interface ProviderCapabilities {
615
+ /** MCP server integration, when the provider consumes MCP via a config file. */
616
+ mcp: ProviderMcpCapability | null;
617
+ /** Harness role, present only for orchestrators and standalone harnesses. */
618
+ harness: ProviderHarnessCapability | null;
466
619
  /** Skills path resolution and precedence. */
467
620
  skills: ProviderSkillsCapability;
468
621
  /** Hook/lifecycle event support. */
@@ -470,41 +623,26 @@ interface ProviderCapabilities {
470
623
  /** Subagent spawn capabilities. */
471
624
  spawn: ProviderSpawnCapability;
472
625
  }
473
- /**
474
- * Priority tier for a provider, used for sorting and default selection.
475
- *
476
- * - `"high"` - Major, widely-used agents
477
- * - `"medium"` - Established but less common agents
478
- * - `"low"` - Niche or experimental agents
479
- *
480
- * @public
481
- */
482
- type ProviderPriority = 'high' | 'medium' | 'low';
483
- /**
484
- * Lifecycle status of a provider in the registry.
485
- *
486
- * - `"active"` - Fully supported
487
- * - `"beta"` - Supported but may have rough edges
488
- * - `"deprecated"` - Still present but no longer recommended
489
- * - `"planned"` - Not yet implemented
490
- *
491
- * @public
492
- */
493
- type ProviderStatus = 'active' | 'beta' | 'deprecated' | 'planned';
626
+
494
627
  /**
495
628
  * A resolved AI agent provider definition with platform-specific paths.
496
629
  *
497
630
  * @remarks
498
631
  * Providers are loaded from `providers/registry.json` and resolved at runtime
499
- * to expand platform-specific path variables (`$HOME`, `$CONFIG`, etc.).
500
- * This is the primary type used throughout the CAAMP codebase for working
501
- * with provider configurations.
632
+ * to expand platform-specific path variables (`$HOME`, `$CONFIG`, `$CLEO_HOME`,
633
+ * etc.). This is the primary type used throughout the CAAMP codebase for
634
+ * working with provider configurations.
635
+ *
636
+ * MCP server integration metadata (config key, format, paths, transports,
637
+ * headers) lives on {@link ProviderCapabilities.mcp} rather than at the
638
+ * top level. Providers that do not consume MCP servers (e.g. Pi, which uses
639
+ * TypeScript extensions) have `capabilities.mcp === null`.
502
640
  *
503
641
  * @example
504
642
  * ```typescript
505
643
  * const provider = getProvider("claude-code");
506
- * if (provider) {
507
- * console.log(provider.configPathGlobal);
644
+ * if (provider?.capabilities.mcp) {
645
+ * console.log(provider.capabilities.mcp.configPathGlobal);
508
646
  * }
509
647
  * ```
510
648
  *
@@ -527,31 +665,19 @@ interface Provider {
527
665
  pathProject: string;
528
666
  /** Instruction file name (e.g. `"CLAUDE.md"`, `"AGENTS.md"`). */
529
667
  instructFile: string;
530
- /** Dot-notation key path for MCP server config (e.g. `"mcpServers"`). */
531
- configKey: string;
532
- /** Config file format used by this provider. */
533
- configFormat: ConfigFormat;
534
- /** Resolved global config file path. */
535
- configPathGlobal: string;
536
- /** Project-relative config file path, or `null` if unsupported. */
537
- configPathProject: string | null;
538
668
  /** Resolved global skills directory path. */
539
669
  pathSkills: string;
540
670
  /** Project-relative skills directory path. */
541
671
  pathProjectSkills: string;
542
672
  /** Detection configuration for auto-discovering this provider. */
543
673
  detection: DetectionConfig;
544
- /** MCP transport protocols this provider supports. */
545
- supportedTransports: TransportType[];
546
- /** Whether the provider supports custom HTTP headers for remote MCP servers. */
547
- supportsHeaders: boolean;
548
674
  /** Priority tier for sorting and default selection. */
549
675
  priority: ProviderPriority;
550
676
  /** Lifecycle status in the registry. */
551
677
  status: ProviderStatus;
552
678
  /** Whether the provider is compatible with the Agent Skills standard. */
553
679
  agentSkillsCompatible: boolean;
554
- /** Provider capabilities for skills, hooks, and spawn. Always populated at runtime. */
680
+ /** Provider capabilities (MCP, harness, skills, hooks, spawn). Always populated at runtime. */
555
681
  capabilities: ProviderCapabilities;
556
682
  }
557
683
  /**
@@ -1341,169 +1467,801 @@ interface InstructionUpdateSummary {
1341
1467
  * providers by their instruction file targets and injects content using
1342
1468
  * marker-based sections.
1343
1469
  *
1344
- * @param providers - The providers whose instruction files to update
1345
- * @param content - The instruction content to inject
1346
- * @param scope - The scope for instruction updates, defaults to `"project"`
1347
- * @param projectDir - The project root directory, defaults to `process.cwd()`
1348
- * @returns A summary of updated files and actions taken per file
1470
+ * @param providers - The providers whose instruction files to update
1471
+ * @param content - The instruction content to inject
1472
+ * @param scope - The scope for instruction updates, defaults to `"project"`
1473
+ * @param projectDir - The project root directory, defaults to `process.cwd()`
1474
+ * @returns A summary of updated files and actions taken per file
1475
+ *
1476
+ * @example
1477
+ * ```typescript
1478
+ * const summary = await updateInstructionsSingleOperation(
1479
+ * providers,
1480
+ * "## CAAMP Config\nUse these MCP servers...",
1481
+ * "project",
1482
+ * );
1483
+ * console.log(`Updated ${summary.updatedFiles} files`);
1484
+ * ```
1485
+ *
1486
+ * @public
1487
+ */
1488
+ declare function updateInstructionsSingleOperation(providers: Provider[], content: string, scope?: Scope, projectDir?: string): Promise<InstructionUpdateSummary>;
1489
+
1490
+ /**
1491
+ * Format utility functions
1492
+ */
1493
+ /**
1494
+ * Deep merge two objects, with `source` values winning on conflict.
1495
+ *
1496
+ * Recursively merges nested plain objects. Arrays and non-object values from
1497
+ * `source` overwrite `target` values.
1498
+ *
1499
+ * @param target - Base object to merge into
1500
+ * @param source - Object with values that take precedence
1501
+ * @returns A new merged object (does not mutate inputs)
1502
+ *
1503
+ * @remarks
1504
+ * Only plain objects are recursively merged. Arrays and primitive values from
1505
+ * `source` replace `target` values outright. Neither input is mutated.
1506
+ *
1507
+ * @example
1508
+ * ```typescript
1509
+ * const merged = deepMerge({ a: 1, b: { c: 2 } }, { b: { d: 3 } });
1510
+ * // { a: 1, b: { c: 2, d: 3 } }
1511
+ * ```
1512
+ *
1513
+ * @public
1514
+ */
1515
+ declare function deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown>;
1516
+ /**
1517
+ * Get a nested value from an object using a dot-notation key path.
1518
+ *
1519
+ * @param obj - Object to traverse
1520
+ * @param keyPath - Dot-separated key path (e.g. `"mcpServers"` or `"a.b.c"`)
1521
+ * @returns The value at the key path, or `undefined` if not found
1522
+ *
1523
+ * @remarks
1524
+ * Splits the key path on `.` and walks the object tree. Returns `undefined`
1525
+ * at the first missing or non-object segment.
1526
+ *
1527
+ * @example
1528
+ * ```typescript
1529
+ * getNestedValue({ a: { b: { c: 42 } } }, "a.b.c"); // 42
1530
+ * getNestedValue({ a: 1 }, "a.b"); // undefined
1531
+ * ```
1532
+ *
1533
+ * @public
1534
+ */
1535
+ declare function getNestedValue(obj: Record<string, unknown>, keyPath: string): unknown;
1536
+ /**
1537
+ * Ensure that the parent directories of a file path exist.
1538
+ *
1539
+ * Creates directories recursively if they do not exist.
1540
+ *
1541
+ * @param filePath - Absolute path to a file (parent directories will be created)
1542
+ *
1543
+ * @remarks
1544
+ * Uses `mkdir` with `recursive: true` so existing directories are not an error.
1545
+ *
1546
+ * @example
1547
+ * ```typescript
1548
+ * await ensureDir("/path/to/new/dir/file.json");
1549
+ * // /path/to/new/dir/ now exists
1550
+ * ```
1551
+ *
1552
+ * @public
1553
+ */
1554
+ declare function ensureDir(filePath: string): Promise<void>;
1555
+
1556
+ /**
1557
+ * Provides format-agnostic config read, write, and remove operations that
1558
+ * dispatch to JSON/JSONC, YAML, or TOML handlers based on the specified
1559
+ * format.
1560
+ *
1561
+ * @packageDocumentation
1562
+ */
1563
+
1564
+ /**
1565
+ * Read and parse a config file in the specified format.
1566
+ *
1567
+ * Dispatches to the appropriate format handler (JSON/JSONC, YAML, or TOML).
1568
+ *
1569
+ * @param filePath - Absolute path to the config file
1570
+ * @param format - Config file format
1571
+ * @returns Parsed config object
1572
+ * @throws If the file cannot be read or the format is unsupported
1573
+ *
1574
+ * @remarks
1575
+ * Supported formats: `"json"`, `"jsonc"`, `"yaml"`, `"toml"`. Throws for
1576
+ * any unrecognized format string.
1577
+ *
1578
+ * @example
1579
+ * ```typescript
1580
+ * const config = await readConfig("/path/to/config.json", "jsonc");
1581
+ * ```
1582
+ *
1583
+ * @public
1584
+ */
1585
+ declare function readConfig(filePath: string, format: ConfigFormat): Promise<Record<string, unknown>>;
1586
+ /**
1587
+ * Write a server entry to a config file, preserving existing content.
1588
+ *
1589
+ * Dispatches to the appropriate format handler. For JSONC files, comments are
1590
+ * preserved using `jsonc-parser`.
1591
+ *
1592
+ * @param filePath - Absolute path to the config file
1593
+ * @param format - Config file format
1594
+ * @param key - Dot-notation key path to the servers section (e.g. `"mcpServers"`)
1595
+ * @param serverName - Name/key for the server entry
1596
+ * @param serverConfig - Server configuration object to write
1597
+ * @throws If the format is unsupported
1598
+ *
1599
+ * @remarks
1600
+ * For JSONC files, comments and formatting are preserved using `jsonc-parser`.
1601
+ * For YAML and TOML, the file is fully re-serialized after deep-merging.
1602
+ *
1603
+ * @example
1604
+ * ```typescript
1605
+ * await writeConfig("/path/to/config.json", "jsonc", "mcpServers", "my-server", config);
1606
+ * ```
1607
+ *
1608
+ * @public
1609
+ */
1610
+ declare function writeConfig(filePath: string, format: ConfigFormat, key: string, serverName: string, serverConfig: unknown): Promise<void>;
1611
+ /**
1612
+ * Remove a server entry from a config file in the specified format.
1613
+ *
1614
+ * @param filePath - Absolute path to the config file
1615
+ * @param format - Config file format
1616
+ * @param key - Dot-notation key path to the servers section
1617
+ * @param serverName - Name/key of the server entry to remove
1618
+ * @returns `true` if the entry was removed, `false` otherwise
1619
+ * @throws If the format is unsupported
1620
+ *
1621
+ * @remarks
1622
+ * Delegates to the format-specific removal function. Returns `false` when the
1623
+ * file does not exist or the entry is not found.
1624
+ *
1625
+ * @example
1626
+ * ```typescript
1627
+ * const removed = await removeConfig("/path/to/config.json", "jsonc", "mcpServers", "my-server");
1628
+ * ```
1629
+ *
1630
+ * @public
1631
+ */
1632
+ declare function removeConfig(filePath: string, format: ConfigFormat, key: string, serverName: string): Promise<boolean>;
1633
+
1634
+ /**
1635
+ * Skill installer - canonical + symlink model
1636
+ *
1637
+ * Skills are stored once in a canonical location (.agents/skills/<name>/)
1638
+ * and symlinked to each target agent's skills directory.
1639
+ */
1640
+
1641
+ /**
1642
+ * Result of installing a skill to the canonical location and linking to agents.
1643
+ *
1644
+ * @example
1645
+ * ```typescript
1646
+ * const result = await installSkill(sourcePath, "my-skill", providers, true);
1647
+ * if (result.success) {
1648
+ * console.log(`Installed to ${result.canonicalPath}`);
1649
+ * console.log(`Linked to: ${result.linkedAgents.join(", ")}`);
1650
+ * }
1651
+ * ```
1652
+ *
1653
+ * @public
1654
+ */
1655
+ interface SkillInstallResult {
1656
+ /** Skill name. */
1657
+ name: string;
1658
+ /** Absolute path to the canonical installation directory. */
1659
+ canonicalPath: string;
1660
+ /** Provider IDs that were successfully linked. */
1661
+ linkedAgents: string[];
1662
+ /** Error messages from failed link operations. */
1663
+ errors: string[];
1664
+ /** Whether at least one agent was successfully linked. */
1665
+ success: boolean;
1666
+ }
1667
+ /**
1668
+ * Install a skill from a local path to the canonical location and link to agents.
1669
+ *
1670
+ * @remarks
1671
+ * Copies the skill directory to the canonical skills directory and creates symlinks
1672
+ * (or copies on Windows) from each provider's skills directory to the canonical path.
1673
+ *
1674
+ * @param sourcePath - Local path to the skill directory to install
1675
+ * @param skillName - Name for the installed skill
1676
+ * @param providers - Target providers to link the skill to
1677
+ * @param isGlobal - Whether to link to global or project skill directories
1678
+ * @param projectDir - Project directory (defaults to `process.cwd()`)
1679
+ * @returns Install result with linked agents and any errors
1680
+ *
1681
+ * @example
1682
+ * ```typescript
1683
+ * const result = await installSkill("/tmp/my-skill", "my-skill", providers, true, "/my/project");
1684
+ * if (result.success) {
1685
+ * console.log(`Linked to: ${result.linkedAgents.join(", ")}`);
1686
+ * }
1687
+ * ```
1688
+ *
1689
+ * @public
1690
+ */
1691
+ declare function installSkill(sourcePath: string, skillName: string, providers: Provider[], isGlobal: boolean, projectDir?: string): Promise<SkillInstallResult>;
1692
+ /**
1693
+ * Remove a skill from the canonical location and all agent symlinks.
1694
+ *
1695
+ * @remarks
1696
+ * Removes symlinks from each provider's skills directory and then removes the
1697
+ * canonical copy from the centralized canonical skills directory.
1698
+ *
1699
+ * @param skillName - Name of the skill to remove
1700
+ * @param providers - Providers to unlink the skill from
1701
+ * @param isGlobal - Whether to target global or project skill directories
1702
+ * @param projectDir - Project directory (defaults to `process.cwd()`)
1703
+ * @returns Object with arrays of successfully removed provider IDs and error messages
1704
+ *
1705
+ * @example
1706
+ * ```typescript
1707
+ * const { removed, errors } = await removeSkill("my-skill", providers, true, "/my/project");
1708
+ * console.log(`Removed from: ${removed.join(", ")}`);
1709
+ * ```
1710
+ *
1711
+ * @public
1712
+ */
1713
+ declare function removeSkill(skillName: string, providers: Provider[], isGlobal: boolean, projectDir?: string): Promise<{
1714
+ removed: string[];
1715
+ errors: string[];
1716
+ }>;
1717
+ /**
1718
+ * List all skills installed in the canonical skills directory.
1719
+ *
1720
+ * @remarks
1721
+ * Returns the directory names of all skills, which correspond to skill names.
1722
+ * Includes both regular directories and symlinks in the canonical location.
1723
+ *
1724
+ * @returns Array of skill names
1725
+ *
1726
+ * @example
1727
+ * ```typescript
1728
+ * const skills = await listCanonicalSkills();
1729
+ * // ["my-skill", "another-skill"]
1730
+ * ```
1731
+ *
1732
+ * @public
1733
+ */
1734
+ declare function listCanonicalSkills(): Promise<string[]>;
1735
+
1736
+ /**
1737
+ * Harness layer type definitions.
1738
+ *
1739
+ * @remarks
1740
+ * Defines the contract every first-class CAAMP harness must implement.
1741
+ * A harness is a provider that CAAMP treats natively — not through the
1742
+ * generic MCP-config-file path. Pi is the first (and currently only)
1743
+ * harness. The interface is intentionally generic so future harnesses
1744
+ * (Goose, OpenCode, ...) can slot in without shape churn.
1745
+ *
1746
+ * All methods are async even when they could be sync, so implementations
1747
+ * that need I/O (filesystem, child process) are not forced to lie about
1748
+ * their return types.
1749
+ *
1750
+ * @packageDocumentation
1751
+ */
1752
+
1753
+ /**
1754
+ * Scope at which a harness operation should be performed.
1755
+ *
1756
+ * @remarks
1757
+ * Harness operations target either the user's global state root (e.g.
1758
+ * `~/.pi/agent/`) or a specific project directory. Project scope requires
1759
+ * the caller to provide the absolute project directory path — the harness
1760
+ * does not infer cwd.
1761
+ *
1762
+ * @public
1763
+ */
1764
+ type HarnessScope = {
1765
+ kind: 'global';
1766
+ } | {
1767
+ kind: 'project';
1768
+ projectDir: string;
1769
+ };
1770
+ /**
1771
+ * Declarative description of an MCP server that should be bridged into a
1772
+ * harness's native extension mechanism.
1773
+ *
1774
+ * @remarks
1775
+ * This is a harness-agnostic input shape. Fields mirror the MCP
1776
+ * configuration surface: stdio transports use {@link command} + {@link args},
1777
+ * remote transports use {@link url} + optional {@link headers}, and all
1778
+ * transports may carry environment variables via {@link env}.
1779
+ *
1780
+ * Harnesses that cannot host MCP servers as extensions will throw or omit
1781
+ * the {@link Harness.installMcpAsExtension} method entirely.
1782
+ *
1783
+ * @public
1784
+ */
1785
+ interface McpServerSpec {
1786
+ /** Logical name of the MCP server (e.g. `"filesystem"`, `"brave-search"`). */
1787
+ name: string;
1788
+ /**
1789
+ * Command to launch the server over stdio transport.
1790
+ * @defaultValue undefined
1791
+ */
1792
+ command?: string;
1793
+ /**
1794
+ * Arguments for the stdio command.
1795
+ * @defaultValue undefined
1796
+ */
1797
+ args?: string[];
1798
+ /**
1799
+ * URL for SSE/HTTP transports.
1800
+ * @defaultValue undefined
1801
+ */
1802
+ url?: string;
1803
+ /**
1804
+ * Environment variables for the server process.
1805
+ * @defaultValue undefined
1806
+ */
1807
+ env?: Record<string, string>;
1808
+ /**
1809
+ * HTTP headers for remote transports.
1810
+ * @defaultValue undefined
1811
+ */
1812
+ headers?: Record<string, string>;
1813
+ }
1814
+ /**
1815
+ * Description of a subagent task to be spawned under a harness.
1816
+ *
1817
+ * @remarks
1818
+ * Generic across harnesses: the same shape describes a Pi-managed child,
1819
+ * a future Goose-managed child, or any other. The {@link targetProviderId}
1820
+ * is a routing hint passed to the harness; concrete harnesses may use it
1821
+ * to select an inner agent or simply record it for observability.
1822
+ *
1823
+ * @public
1824
+ */
1825
+ interface SubagentTask {
1826
+ /** Provider id of the agent to spawn (e.g. `"claude-code"`). */
1827
+ targetProviderId: string;
1828
+ /** The prompt / instruction to give the spawned agent. */
1829
+ prompt: string;
1830
+ /**
1831
+ * Working directory for the spawned agent.
1832
+ * @defaultValue undefined
1833
+ */
1834
+ cwd?: string;
1835
+ /**
1836
+ * Environment variable overrides layered atop the parent environment.
1837
+ * @defaultValue undefined
1838
+ */
1839
+ env?: Record<string, string>;
1840
+ /**
1841
+ * Abort signal. When it aborts, the harness will terminate the subagent.
1842
+ * @defaultValue undefined
1843
+ */
1844
+ signal?: AbortSignal;
1845
+ }
1846
+ /**
1847
+ * Final result of a subagent's execution.
1848
+ *
1849
+ * @remarks
1850
+ * Collected once the child process exits. {@link parsed} is populated
1851
+ * on a best-effort basis: if the subagent emits JSON on stdout the
1852
+ * harness will parse it, otherwise {@link parsed} is left undefined.
1853
+ *
1854
+ * @public
1855
+ */
1856
+ interface SubagentResult {
1857
+ /** Process exit code, or `null` if the process was killed by a signal. */
1858
+ exitCode: number | null;
1859
+ /** Full stdout captured from the subagent. */
1860
+ stdout: string;
1861
+ /** Full stderr captured from the subagent. */
1862
+ stderr: string;
1863
+ /**
1864
+ * Parsed JSON output, when the target supports a JSON output mode and
1865
+ * emitted well-formed JSON on stdout.
1866
+ * @defaultValue undefined
1867
+ */
1868
+ parsed?: unknown;
1869
+ }
1870
+ /**
1871
+ * Live handle to a running subagent.
1872
+ *
1873
+ * @remarks
1874
+ * Returned synchronously from {@link Harness.spawnSubagent}. The caller
1875
+ * may await {@link result} to collect the final output, or invoke
1876
+ * {@link abort} to terminate the child early.
1877
+ *
1878
+ * @public
1879
+ */
1880
+ interface SubagentHandle {
1881
+ /** PID of the spawned process, or `null` if spawning did not yield one. */
1882
+ pid: number | null;
1883
+ /** Promise resolving to the subagent's final output once the process exits. */
1884
+ result: Promise<SubagentResult>;
1885
+ /** Synchronously terminate the subagent. Safe to call after exit. */
1886
+ abort: () => void;
1887
+ }
1888
+ /**
1889
+ * Contract every first-class harness must implement.
1890
+ *
1891
+ * @remarks
1892
+ * A harness is a provider that CAAMP treats natively — installing skills,
1893
+ * MCP bridges, instruction files, and subagent spawns through harness-specific
1894
+ * mechanisms rather than a generic MCP config file. Pi is the first concrete
1895
+ * harness; the interface is shaped so future harnesses (Goose, OpenCode, ...)
1896
+ * can be added without changing any caller code.
1897
+ *
1898
+ * Optional methods ({@link installMcpAsExtension}, {@link spawnSubagent},
1899
+ * {@link configureModels}) may be omitted by harnesses that cannot support
1900
+ * them. Callers MUST feature-check before invoking.
1901
+ *
1902
+ * @public
1903
+ */
1904
+ interface Harness {
1905
+ /** Short id matching the provider id (e.g. `"pi"`). */
1906
+ readonly id: string;
1907
+ /** The underlying resolved provider entry. */
1908
+ readonly provider: Provider;
1909
+ /**
1910
+ * Install a skill using the harness's native mechanism.
1911
+ *
1912
+ * @remarks
1913
+ * For Pi: copy the source skill directory into
1914
+ * `~/.pi/agent/skills/<skillName>/` (global) or `<projectDir>/.pi/skills/<skillName>/`
1915
+ * (project). Pi resolves paths at load time so a symlink would work, but
1916
+ * CAAMP prefers a recursive copy to avoid cross-filesystem symlink issues.
1917
+ *
1918
+ * @param sourcePath - Absolute path to the skill directory to install.
1919
+ * @param skillName - Target skill name (becomes the directory name on disk).
1920
+ * @param scope - Install target scope.
1921
+ */
1922
+ installSkill(sourcePath: string, skillName: string, scope: HarnessScope): Promise<void>;
1923
+ /**
1924
+ * Remove a skill previously installed via this harness.
1925
+ *
1926
+ * @remarks
1927
+ * Missing skills are tolerated silently so callers can use this as an
1928
+ * idempotent "ensure absent" operation.
1929
+ *
1930
+ * @param skillName - Skill name to remove.
1931
+ * @param scope - Install target scope.
1932
+ */
1933
+ removeSkill(skillName: string, scope: HarnessScope): Promise<void>;
1934
+ /**
1935
+ * List skills installed in this harness's skill directory for a scope.
1936
+ *
1937
+ * @remarks
1938
+ * Returns the skill directory names (not absolute paths). Missing scope
1939
+ * directories return an empty array rather than throwing.
1940
+ *
1941
+ * @param scope - Scope to inspect.
1942
+ * @returns Array of skill directory names.
1943
+ */
1944
+ listSkills(scope: HarnessScope): Promise<string[]>;
1945
+ /**
1946
+ * Inject content into the harness's instruction file using a marker-based
1947
+ * idempotent block.
1948
+ *
1949
+ * @remarks
1950
+ * For Pi the target file is `~/.pi/agent/AGENTS.md` (global) or
1951
+ * `<projectDir>/AGENTS.md` at the project root (not under `.pi/`). The
1952
+ * injection uses `<!-- CAAMP:START -->` / `<!-- CAAMP:END -->` markers so
1953
+ * subsequent calls replace the block in place.
1954
+ *
1955
+ * @param content - The content to inject inside the marker block.
1956
+ * @param scope - Instruction file scope.
1957
+ */
1958
+ injectInstructions(content: string, scope: HarnessScope): Promise<void>;
1959
+ /**
1960
+ * Remove the CAAMP injection block from the harness's instruction file.
1961
+ *
1962
+ * @remarks
1963
+ * The surrounding file content is preserved. Missing files are tolerated.
1964
+ *
1965
+ * @param scope - Instruction file scope.
1966
+ */
1967
+ removeInstructions(scope: HarnessScope): Promise<void>;
1968
+ /**
1969
+ * Install an MCP server as a harness extension.
1970
+ *
1971
+ * @remarks
1972
+ * For legacy providers with a native MCP config file, this is a
1973
+ * passthrough. For Pi it generates a TypeScript extension file under
1974
+ * `extensions/` that wraps the MCP server as a Pi tool via
1975
+ * `pi.registerTool()`.
1976
+ *
1977
+ * Optional — harnesses that cannot host MCP bridges should omit this
1978
+ * method. Callers MUST feature-check before invoking.
1979
+ *
1980
+ * @param server - Server spec to bridge.
1981
+ * @param scope - Install scope.
1982
+ */
1983
+ installMcpAsExtension?(server: McpServerSpec, scope: HarnessScope): Promise<void>;
1984
+ /**
1985
+ * Spawn a subagent under this harness's control.
1986
+ *
1987
+ * @remarks
1988
+ * For Pi: invokes `child_process.spawn` with the provider's configured
1989
+ * `capabilities.spawn.spawnCommand`, appending the task prompt as a
1990
+ * trailing positional argument. The returned handle lets the caller await
1991
+ * completion or abort early.
1992
+ *
1993
+ * Optional — harnesses that cannot spawn other agents should omit this
1994
+ * method. Callers MUST feature-check before invoking.
1995
+ *
1996
+ * @param task - Subagent task specification.
1997
+ * @returns A live subagent handle.
1998
+ */
1999
+ spawnSubagent?(task: SubagentTask): Promise<SubagentHandle>;
2000
+ /**
2001
+ * Configure which models are available in the harness's model picker.
2002
+ *
2003
+ * @remarks
2004
+ * For Pi: writes the provided glob list to `settings.json:enabledModels`.
2005
+ *
2006
+ * Optional — harnesses without a model picker should omit this method.
2007
+ *
2008
+ * @param modelPatterns - Glob patterns enumerating enabled models.
2009
+ * @param scope - Settings scope.
2010
+ */
2011
+ configureModels?(modelPatterns: string[], scope: HarnessScope): Promise<void>;
2012
+ /**
2013
+ * Read the harness's current settings as an opaque object.
2014
+ *
2015
+ * @remarks
2016
+ * The shape is harness-specific; callers that care about fields must know
2017
+ * the concrete harness's schema. Missing files resolve to an empty object.
2018
+ *
2019
+ * @param scope - Settings scope.
2020
+ * @returns Opaque settings blob.
2021
+ */
2022
+ readSettings(scope: HarnessScope): Promise<unknown>;
2023
+ /**
2024
+ * Deep-merge a patch into the harness's settings and persist the result.
2025
+ *
2026
+ * @remarks
2027
+ * The patch is merged, not replaced, so unrelated fields survive. The
2028
+ * shape is harness-specific.
2029
+ *
2030
+ * @param patch - Partial settings object to merge.
2031
+ * @param scope - Settings scope.
2032
+ */
2033
+ writeSettings(patch: Record<string, unknown>, scope: HarnessScope): Promise<void>;
2034
+ }
2035
+
2036
+ /**
2037
+ * Pi coding agent harness.
2038
+ *
2039
+ * @remarks
2040
+ * Concrete {@link Harness} implementation for the Pi coding agent
2041
+ * (https://github.com/badlogic/pi-mono). Pi is CAAMP's first first-class
2042
+ * primary harness: it owns skills, instructions, extensions, and subagent
2043
+ * spawning through native filesystem conventions rather than a generic
2044
+ * MCP config file.
1349
2045
  *
1350
- * @example
1351
- * ```typescript
1352
- * const summary = await updateInstructionsSingleOperation(
1353
- * providers,
1354
- * "## CAAMP Config\nUse these MCP servers...",
1355
- * "project",
1356
- * );
1357
- * console.log(`Updated ${summary.updatedFiles} files`);
1358
- * ```
2046
+ * Filesystem layout honoured by this harness:
2047
+ * - Global state root: `$PI_CODING_AGENT_DIR` if set, else `~/.pi/agent/`.
2048
+ * - Global skills: `<root>/skills/<name>/`
2049
+ * - Global extensions: `<root>/extensions/*.ts`
2050
+ * - Global settings: `<root>/settings.json`
2051
+ * - Global instructions: `<root>/AGENTS.md`
2052
+ * - Project skills: `<projectDir>/.pi/skills/<name>/`
2053
+ * - Project extensions: `<projectDir>/.pi/extensions/*.ts`
2054
+ * - Project settings: `<projectDir>/.pi/settings.json`
2055
+ * - Project instructions: `<projectDir>/AGENTS.md` (at project root, NOT under `.pi/`)
1359
2056
  *
1360
- * @public
2057
+ * @packageDocumentation
1361
2058
  */
1362
- declare function updateInstructionsSingleOperation(providers: Provider[], content: string, scope?: Scope, projectDir?: string): Promise<InstructionUpdateSummary>;
1363
2059
 
1364
2060
  /**
1365
- * Format utility functions
1366
- */
1367
- /**
1368
- * Deep merge two objects, with `source` values winning on conflict.
1369
- *
1370
- * Recursively merges nested plain objects. Arrays and non-object values from
1371
- * `source` overwrite `target` values.
1372
- *
1373
- * @param target - Base object to merge into
1374
- * @param source - Object with values that take precedence
1375
- * @returns A new merged object (does not mutate inputs)
2061
+ * Pi coding agent harness — CAAMP's first-class primary harness.
1376
2062
  *
1377
2063
  * @remarks
1378
- * Only plain objects are recursively merged. Arrays and primitive values from
1379
- * `source` replace `target` values outright. Neither input is mutated.
2064
+ * Implements the full {@link Harness} contract using Pi's filesystem
2065
+ * conventions. All mutating operations are idempotent: re-installing a
2066
+ * skill overwrites it cleanly, injecting instructions twice replaces the
2067
+ * marker block rather than appending, and removing absent assets is a
2068
+ * no-op.
1380
2069
  *
1381
- * @example
1382
- * ```typescript
1383
- * const merged = deepMerge({ a: 1, b: { c: 2 } }, { b: { d: 3 } });
1384
- * // { a: 1, b: { c: 2, d: 3 } }
1385
- * ```
2070
+ * @see {@link https://github.com/badlogic/pi-mono | pi-mono}
1386
2071
  *
1387
2072
  * @public
1388
2073
  */
1389
- declare function deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown>;
2074
+ declare class PiHarness implements Harness {
2075
+ readonly provider: Provider;
2076
+ /** Provider id, always `"pi"`. */
2077
+ readonly id = "pi";
2078
+ /**
2079
+ * Construct a harness bound to a resolved Pi provider.
2080
+ *
2081
+ * @param provider - The resolved provider entry for `"pi"`.
2082
+ */
2083
+ constructor(provider: Provider);
2084
+ /**
2085
+ * Resolve the skills directory for a given scope.
2086
+ */
2087
+ private skillsDir;
2088
+ /**
2089
+ * Resolve the extensions directory for a given scope.
2090
+ */
2091
+ private extensionsDir;
2092
+ /**
2093
+ * Resolve the settings.json path for a given scope.
2094
+ */
2095
+ private settingsPath;
2096
+ /**
2097
+ * Resolve the AGENTS.md instruction file path for a given scope.
2098
+ *
2099
+ * @remarks
2100
+ * Global scope lives under the Pi state root; project scope lives at
2101
+ * the project root (NOT under `.pi/`), matching Pi's convention of
2102
+ * auto-discovering `AGENTS.md` from the working directory upwards.
2103
+ */
2104
+ private agentsMdPath;
2105
+ /** {@inheritDoc Harness.installSkill} */
2106
+ installSkill(sourcePath: string, skillName: string, scope: HarnessScope): Promise<void>;
2107
+ /** {@inheritDoc Harness.removeSkill} */
2108
+ removeSkill(skillName: string, scope: HarnessScope): Promise<void>;
2109
+ /** {@inheritDoc Harness.listSkills} */
2110
+ listSkills(scope: HarnessScope): Promise<string[]>;
2111
+ /** {@inheritDoc Harness.injectInstructions} */
2112
+ injectInstructions(content: string, scope: HarnessScope): Promise<void>;
2113
+ /** {@inheritDoc Harness.removeInstructions} */
2114
+ removeInstructions(scope: HarnessScope): Promise<void>;
2115
+ /**
2116
+ * {@inheritDoc Harness.installMcpAsExtension}
2117
+ *
2118
+ * @remarks
2119
+ * Emits a SCAFFOLD Pi extension file under `extensions/mcp-<name>.ts`.
2120
+ * The scaffold registers a Pi tool whose `execute` function currently
2121
+ * returns an "isError" payload explaining that the MCP bridge runtime
2122
+ * is not yet implemented. This preserves the public lifecycle surface
2123
+ * (install/list/remove) so orchestration code can treat the bridge as
2124
+ * a first-class asset while the concrete JSON-RPC runtime is built out
2125
+ * in a later wave.
2126
+ */
2127
+ installMcpAsExtension(server: McpServerSpec, scope: HarnessScope): Promise<void>;
2128
+ /**
2129
+ * {@inheritDoc Harness.spawnSubagent}
2130
+ *
2131
+ * @remarks
2132
+ * Invokes Pi's configured `spawnCommand` (e.g.
2133
+ * `["pi", "--mode", "json", "-p", "--no-session"]`) with the task prompt
2134
+ * appended as the trailing positional argument. The {@link SubagentTask.targetProviderId}
2135
+ * is a routing hint carried in the prompt stream; Pi's own extension
2136
+ * layer dispatches to the correct inner agent.
2137
+ *
2138
+ * Throws immediately when the provider entry is missing a `spawnCommand`
2139
+ * so callers see configuration errors early rather than at child-exit time.
2140
+ */
2141
+ spawnSubagent(task: SubagentTask): Promise<SubagentHandle>;
2142
+ /** {@inheritDoc Harness.readSettings} */
2143
+ readSettings(scope: HarnessScope): Promise<unknown>;
2144
+ /** {@inheritDoc Harness.writeSettings} */
2145
+ writeSettings(patch: Record<string, unknown>, scope: HarnessScope): Promise<void>;
2146
+ /** {@inheritDoc Harness.configureModels} */
2147
+ configureModels(modelPatterns: string[], scope: HarnessScope): Promise<void>;
2148
+ }
2149
+
1390
2150
  /**
1391
- * Get a nested value from an object using a dot-notation key path.
1392
- *
1393
- * @param obj - Object to traverse
1394
- * @param keyPath - Dot-separated key path (e.g. `"mcpServers"` or `"a.b.c"`)
1395
- * @returns The value at the key path, or `undefined` if not found
2151
+ * Harness layer dispatcher.
1396
2152
  *
1397
2153
  * @remarks
1398
- * Splits the key path on `.` and walks the object tree. Returns `undefined`
1399
- * at the first missing or non-object segment.
2154
+ * This module is the single entry point for resolving a concrete
2155
+ * {@link Harness} implementation from a provider (or from the registry's
2156
+ * primary provider). It owns the switch that maps provider ids to
2157
+ * implementations so the rest of CAAMP never needs to construct harness
2158
+ * classes directly.
1400
2159
  *
1401
- * @example
1402
- * ```typescript
1403
- * getNestedValue({ a: { b: { c: 42 } } }, "a.b.c"); // 42
1404
- * getNestedValue({ a: 1 }, "a.b"); // undefined
1405
- * ```
2160
+ * Today only Pi has a harness implementation. Future harnesses (Goose,
2161
+ * OpenCode, ...) will be added to {@link getHarnessFor} alongside Pi.
1406
2162
  *
1407
- * @public
2163
+ * @packageDocumentation
1408
2164
  */
1409
- declare function getNestedValue(obj: Record<string, unknown>, keyPath: string): unknown;
2165
+
1410
2166
  /**
1411
- * Ensure that the parent directories of a file path exist.
1412
- *
1413
- * Creates directories recursively if they do not exist.
1414
- *
1415
- * @param filePath - Absolute path to a file (parent directories will be created)
2167
+ * Return the harness implementation for a provider, or `null` if the
2168
+ * provider has no first-class harness.
1416
2169
  *
1417
2170
  * @remarks
1418
- * Uses `mkdir` with `recursive: true` so existing directories are not an error.
2171
+ * This is the primary dispatcher. As new harnesses are added, their
2172
+ * provider id → implementation mapping lives here.
2173
+ *
2174
+ * @param provider - Resolved provider to look up.
2175
+ * @returns A harness instance, or `null` if the provider is a pure spawn
2176
+ * target with no native harness.
1419
2177
  *
1420
2178
  * @example
1421
2179
  * ```typescript
1422
- * await ensureDir("/path/to/new/dir/file.json");
1423
- * // /path/to/new/dir/ now exists
2180
+ * const pi = getProvider("pi");
2181
+ * if (pi) {
2182
+ * const harness = getHarnessFor(pi);
2183
+ * await harness?.installSkill("/path/to/skill", "my-skill", { kind: "global" });
2184
+ * }
1424
2185
  * ```
1425
2186
  *
1426
2187
  * @public
1427
2188
  */
1428
- declare function ensureDir(filePath: string): Promise<void>;
1429
-
1430
- /**
1431
- * Provides format-agnostic config read, write, and remove operations that
1432
- * dispatch to JSON/JSONC, YAML, or TOML handlers based on the specified
1433
- * format.
1434
- *
1435
- * @packageDocumentation
1436
- */
1437
-
2189
+ declare function getHarnessFor(provider: Provider): Harness | null;
1438
2190
  /**
1439
- * Read and parse a config file in the specified format.
1440
- *
1441
- * Dispatches to the appropriate format handler (JSON/JSONC, YAML, or TOML).
1442
- *
1443
- * @param filePath - Absolute path to the config file
1444
- * @param format - Config file format
1445
- * @returns Parsed config object
1446
- * @throws If the file cannot be read or the format is unsupported
2191
+ * Return the primary harness declared in the registry, if any.
1447
2192
  *
1448
2193
  * @remarks
1449
- * Supported formats: `"json"`, `"jsonc"`, `"yaml"`, `"toml"`. Throws for
1450
- * any unrecognized format string.
2194
+ * Resolves the registry's primary provider (via
2195
+ * {@link getPrimaryProvider}) and returns its harness implementation.
2196
+ * Callers use this to resolve the default `--agent` target when no flag
2197
+ * is provided.
2198
+ *
2199
+ * @returns The primary harness, or `null` if no primary provider exists
2200
+ * or the primary provider has no harness implementation.
1451
2201
  *
1452
2202
  * @example
1453
2203
  * ```typescript
1454
- * const config = await readConfig("/path/to/config.json", "jsonc");
2204
+ * const primary = getPrimaryHarness();
2205
+ * if (primary) {
2206
+ * console.log(`Primary harness: ${primary.provider.toolName}`);
2207
+ * }
1455
2208
  * ```
1456
2209
  *
1457
2210
  * @public
1458
2211
  */
1459
- declare function readConfig(filePath: string, format: ConfigFormat): Promise<Record<string, unknown>>;
2212
+ declare function getPrimaryHarness(): Harness | null;
1460
2213
  /**
1461
- * Write a server entry to a config file, preserving existing content.
1462
- *
1463
- * Dispatches to the appropriate format handler. For JSONC files, comments are
1464
- * preserved using `jsonc-parser`.
1465
- *
1466
- * @param filePath - Absolute path to the config file
1467
- * @param format - Config file format
1468
- * @param key - Dot-notation key path to the servers section (e.g. `"mcpServers"`)
1469
- * @param serverName - Name/key for the server entry
1470
- * @param serverConfig - Server configuration object to write
1471
- * @throws If the format is unsupported
2214
+ * Return every provider that has a harness implementation.
1472
2215
  *
1473
2216
  * @remarks
1474
- * For JSONC files, comments and formatting are preserved using `jsonc-parser`.
1475
- * For YAML and TOML, the file is fully re-serialized after deep-merging.
2217
+ * Iterates all registered providers and collects their harness instances.
2218
+ * Useful for diagnostics and for surfaces like
2219
+ * `caamp providers list --harnesses`.
1476
2220
  *
1477
- * @example
1478
- * ```typescript
1479
- * await writeConfig("/path/to/config.json", "jsonc", "mcpServers", "my-server", config);
1480
- * ```
2221
+ * @returns Array of harness instances, one per provider that implements
2222
+ * the {@link Harness} contract.
1481
2223
  *
1482
2224
  * @public
1483
2225
  */
1484
- declare function writeConfig(filePath: string, format: ConfigFormat, key: string, serverName: string, serverConfig: unknown): Promise<void>;
2226
+ declare function getAllHarnesses(): Harness[];
1485
2227
  /**
1486
- * Remove a server entry from a config file in the specified format.
1487
- *
1488
- * @param filePath - Absolute path to the config file
1489
- * @param format - Config file format
1490
- * @param key - Dot-notation key path to the servers section
1491
- * @param serverName - Name/key of the server entry to remove
1492
- * @returns `true` if the entry was removed, `false` otherwise
1493
- * @throws If the format is unsupported
2228
+ * Resolve the default set of target providers when the user has not passed
2229
+ * `--agent`.
1494
2230
  *
1495
2231
  * @remarks
1496
- * Delegates to the format-specific removal function. Returns `false` when the
1497
- * file does not exist or the entry is not found.
2232
+ * Resolution policy:
2233
+ *
2234
+ * 1. If the registry's primary harness (the provider with
2235
+ * `priority === "primary"`) is installed on the current system,
2236
+ * return `[primaryProvider]` so that commands dispatch to the
2237
+ * primary harness by default.
2238
+ * 2. Otherwise, return the set of installed providers at priority
2239
+ * `"primary"` or `"high"`. This restores the legacy "detected high-tier
2240
+ * providers" fallback that CAAMP has always used when no primary
2241
+ * harness is available.
2242
+ * 3. If the priority filter yields an empty list (e.g. in tests that stub
2243
+ * providers without a `priority` field, or in fresh installs with only
2244
+ * medium/low-tier providers detected), fall back to the full installed
2245
+ * provider list so that commands retain a valid target.
2246
+ *
2247
+ * This helper is intentionally defensive: it swallows registry-related
2248
+ * exceptions (returning an empty-primary-harness result) so stubbed test
2249
+ * environments that do not wire the full provider registry still behave
2250
+ * sensibly.
2251
+ *
2252
+ * @returns Ordered list of providers to target by default.
1498
2253
  *
1499
2254
  * @example
1500
2255
  * ```typescript
1501
- * const removed = await removeConfig("/path/to/config.json", "jsonc", "mcpServers", "my-server");
2256
+ * const targets = resolveDefaultTargetProviders();
2257
+ * if (targets.length === 0) {
2258
+ * console.error("No target providers found. Use --agent or --all.");
2259
+ * }
1502
2260
  * ```
1503
2261
  *
1504
2262
  * @public
1505
2263
  */
1506
- declare function removeConfig(filePath: string, format: ConfigFormat, key: string, serverName: string): Promise<boolean>;
2264
+ declare function resolveDefaultTargetProviders(): Provider[];
1507
2265
 
1508
2266
  /**
1509
2267
  * All hook event categories (8 total).
@@ -3090,9 +3848,9 @@ declare function getAgentsLinksDir(scope?: PathScope, projectDir?: string): stri
3090
3848
  *
3091
3849
  * @remarks
3092
3850
  * Replaces template variables like `$HOME`, `$CONFIG`, `$VSCODE_CONFIG`,
3093
- * `$ZED_CONFIG`, `$CLAUDE_DESKTOP_CONFIG`, and `$AGENTS_HOME` with their
3094
- * actual platform-specific values. Used to resolve paths from the provider
3095
- * registry JSON.
3851
+ * `$ZED_CONFIG`, `$CLAUDE_DESKTOP_CONFIG`, `$AGENTS_HOME`, and `$CLEO_HOME`
3852
+ * with their actual platform-specific values. Used to resolve paths from
3853
+ * the provider registry JSON.
3096
3854
  *
3097
3855
  * @param template - The template string containing `$VARIABLE` placeholders
3098
3856
  * @returns The resolved absolute path with all variables expanded
@@ -3478,8 +4236,10 @@ declare function resolveAlias(idOrAlias: string): string;
3478
4236
  * @remarks
3479
4237
  * Provider priority is assigned in `providers/registry.json` and indicates the
3480
4238
  * relative importance of a provider for detection ordering and display.
4239
+ * Callers filtering by `"primary"` should expect zero or one result; the
4240
+ * registry loader does not enforce the single-primary invariant.
3481
4241
  *
3482
- * @param priority - Priority level to filter by (`"high"`, `"medium"`, or `"low"`)
4242
+ * @param priority - Priority level to filter by (`"primary"`, `"high"`, `"medium"`, or `"low"`)
3483
4243
  * @returns Array of providers matching the given priority
3484
4244
  *
3485
4245
  * @example
@@ -3491,6 +4251,29 @@ declare function resolveAlias(idOrAlias: string): string;
3491
4251
  * @public
3492
4252
  */
3493
4253
  declare function getProvidersByPriority(priority: ProviderPriority): Provider[];
4254
+ /**
4255
+ * Get the single primary harness provider, if any is registered.
4256
+ *
4257
+ * @remarks
4258
+ * Returns the provider with `priority === "primary"`. By convention a
4259
+ * registry defines at most one primary harness; this function returns
4260
+ * the first match if the invariant is violated and logs no warning. Use
4261
+ * {@link getProvidersByPriority} instead if you need to diagnose
4262
+ * duplicates.
4263
+ *
4264
+ * @returns The primary provider, or `undefined` if none is registered
4265
+ *
4266
+ * @example
4267
+ * ```typescript
4268
+ * const primary = getPrimaryProvider();
4269
+ * if (primary) {
4270
+ * console.log(`Primary harness: ${primary.toolName}`);
4271
+ * }
4272
+ * ```
4273
+ *
4274
+ * @public
4275
+ */
4276
+ declare function getPrimaryProvider(): Provider | undefined;
3494
4277
  /**
3495
4278
  * Filter providers by their lifecycle status.
3496
4279
  *
@@ -3574,7 +4357,7 @@ declare function getProviderCount(): number;
3574
4357
  * The version is read from the top-level `version` field in `providers/registry.json`
3575
4358
  * and follows semver conventions. It is bumped when provider definitions change.
3576
4359
  *
3577
- * @returns Version string from `providers/registry.json` (e.g. `"1.0.0"`)
4360
+ * @returns Version string from `providers/registry.json` (e.g. `"2.0.0"`)
3578
4361
  *
3579
4362
  * @example
3580
4363
  * ```typescript
@@ -3679,8 +4462,8 @@ declare function getSpawnCapableProviders(): Provider[];
3679
4462
  *
3680
4463
  * @remarks
3681
4464
  * The spawn capability has four boolean flags that can be queried independently.
3682
- * The `spawnMechanism` string field is excluded from the flag type since it is
3683
- * not a boolean check.
4465
+ * The `spawnMechanism` and `spawnCommand` fields are excluded from the flag
4466
+ * type since they are not boolean checks.
3684
4467
  *
3685
4468
  * @param flag - One of the four boolean flags on {@link ProviderSpawnCapability}
3686
4469
  * (`"supportsSubagents"`, `"supportsProgrammaticSpawn"`,
@@ -3697,7 +4480,7 @@ declare function getSpawnCapableProviders(): Provider[];
3697
4480
  *
3698
4481
  * @public
3699
4482
  */
3700
- declare function getProvidersBySpawnCapability(flag: keyof Omit<ProviderSpawnCapability, 'spawnMechanism'>): Provider[];
4483
+ declare function getProvidersBySpawnCapability(flag: keyof Omit<ProviderSpawnCapability, 'spawnMechanism' | 'spawnCommand'>): Provider[];
3701
4484
  /**
3702
4485
  * Filter providers by their skills precedence value.
3703
4486
  *
@@ -3784,7 +4567,8 @@ declare function buildSkillsMap(): Array<{
3784
4567
  *
3785
4568
  * @remarks
3786
4569
  * Shorthand for `getProvider(idOrAlias)?.capabilities`. Returns the full
3787
- * capabilities object containing skills, hooks, and spawn sub-objects.
4570
+ * capabilities object containing mcp, harness, skills, hooks, and spawn
4571
+ * sub-objects.
3788
4572
  *
3789
4573
  * @param idOrAlias - Provider ID or alias
3790
4574
  * @returns The provider's capabilities, or undefined if not found
@@ -4622,108 +5406,6 @@ declare function discoverSkill(skillDir: string): Promise<SkillEntry | null>;
4622
5406
  */
4623
5407
  declare function discoverSkills(rootDir: string): Promise<SkillEntry[]>;
4624
5408
 
4625
- /**
4626
- * Skill installer - canonical + symlink model
4627
- *
4628
- * Skills are stored once in a canonical location (.agents/skills/<name>/)
4629
- * and symlinked to each target agent's skills directory.
4630
- */
4631
-
4632
- /**
4633
- * Result of installing a skill to the canonical location and linking to agents.
4634
- *
4635
- * @example
4636
- * ```typescript
4637
- * const result = await installSkill(sourcePath, "my-skill", providers, true);
4638
- * if (result.success) {
4639
- * console.log(`Installed to ${result.canonicalPath}`);
4640
- * console.log(`Linked to: ${result.linkedAgents.join(", ")}`);
4641
- * }
4642
- * ```
4643
- *
4644
- * @public
4645
- */
4646
- interface SkillInstallResult {
4647
- /** Skill name. */
4648
- name: string;
4649
- /** Absolute path to the canonical installation directory. */
4650
- canonicalPath: string;
4651
- /** Provider IDs that were successfully linked. */
4652
- linkedAgents: string[];
4653
- /** Error messages from failed link operations. */
4654
- errors: string[];
4655
- /** Whether at least one agent was successfully linked. */
4656
- success: boolean;
4657
- }
4658
- /**
4659
- * Install a skill from a local path to the canonical location and link to agents.
4660
- *
4661
- * @remarks
4662
- * Copies the skill directory to the canonical skills directory and creates symlinks
4663
- * (or copies on Windows) from each provider's skills directory to the canonical path.
4664
- *
4665
- * @param sourcePath - Local path to the skill directory to install
4666
- * @param skillName - Name for the installed skill
4667
- * @param providers - Target providers to link the skill to
4668
- * @param isGlobal - Whether to link to global or project skill directories
4669
- * @param projectDir - Project directory (defaults to `process.cwd()`)
4670
- * @returns Install result with linked agents and any errors
4671
- *
4672
- * @example
4673
- * ```typescript
4674
- * const result = await installSkill("/tmp/my-skill", "my-skill", providers, true, "/my/project");
4675
- * if (result.success) {
4676
- * console.log(`Linked to: ${result.linkedAgents.join(", ")}`);
4677
- * }
4678
- * ```
4679
- *
4680
- * @public
4681
- */
4682
- declare function installSkill(sourcePath: string, skillName: string, providers: Provider[], isGlobal: boolean, projectDir?: string): Promise<SkillInstallResult>;
4683
- /**
4684
- * Remove a skill from the canonical location and all agent symlinks.
4685
- *
4686
- * @remarks
4687
- * Removes symlinks from each provider's skills directory and then removes the
4688
- * canonical copy from the centralized canonical skills directory.
4689
- *
4690
- * @param skillName - Name of the skill to remove
4691
- * @param providers - Providers to unlink the skill from
4692
- * @param isGlobal - Whether to target global or project skill directories
4693
- * @param projectDir - Project directory (defaults to `process.cwd()`)
4694
- * @returns Object with arrays of successfully removed provider IDs and error messages
4695
- *
4696
- * @example
4697
- * ```typescript
4698
- * const { removed, errors } = await removeSkill("my-skill", providers, true, "/my/project");
4699
- * console.log(`Removed from: ${removed.join(", ")}`);
4700
- * ```
4701
- *
4702
- * @public
4703
- */
4704
- declare function removeSkill(skillName: string, providers: Provider[], isGlobal: boolean, projectDir?: string): Promise<{
4705
- removed: string[];
4706
- errors: string[];
4707
- }>;
4708
- /**
4709
- * List all skills installed in the canonical skills directory.
4710
- *
4711
- * @remarks
4712
- * Returns the directory names of all skills, which correspond to skill names.
4713
- * Includes both regular directories and symlinks in the canonical location.
4714
- *
4715
- * @returns Array of skill names
4716
- *
4717
- * @example
4718
- * ```typescript
4719
- * const skills = await listCanonicalSkills();
4720
- * // ["my-skill", "another-skill"]
4721
- * ```
4722
- *
4723
- * @public
4724
- */
4725
- declare function listCanonicalSkills(): Promise<string[]>;
4726
-
4727
5409
  /**
4728
5410
  * Skill integrity checking
4729
5411
  *
@@ -4906,7 +5588,7 @@ declare function validateInstructionIntegrity(providers: Provider[], projectDir:
4906
5588
  *
4907
5589
  * @example
4908
5590
  * ```typescript
4909
- * const library = loadLibraryFromModule("/home/user/.agents/libraries/ct-skills");
5591
+ * const library = loadLibraryFromModule("/home/user/.agents/libraries/cleocode-skills");
4910
5592
  * console.log(`Loaded v${library.version} with ${library.listSkills().length} skills`);
4911
5593
  * ```
4912
5594
  *
@@ -4931,7 +5613,7 @@ declare function loadLibraryFromModule(root: string): SkillLibrary;
4931
5613
  *
4932
5614
  * @example
4933
5615
  * ```typescript
4934
- * const library = buildLibraryFromFiles("/home/user/.agents/libraries/ct-skills");
5616
+ * const library = buildLibraryFromFiles("/home/user/.agents/libraries/cleocode-skills");
4935
5617
  * const coreSkills = library.getCoreSkills();
4936
5618
  * console.log(`Core skills: ${coreSkills.map(s => s.name).join(", ")}`);
4937
5619
  * ```
@@ -5663,4 +6345,4 @@ declare function parseSource(input: string): ParsedSource;
5663
6345
  */
5664
6346
  declare function isMarketplaceScoped(input: string): boolean;
5665
6347
 
5666
- export { type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, CANONICAL_HOOK_EVENTS, type CaampLockFile, type CanonicalEventDefinition, type CanonicalHookEvent, type ConfigFormat, type CrossProviderMatrix, type CtDispatchMatrix, type CtManifest, type CtManifestSkill, type CtProfileDefinition, type CtSkillEntry, type CtValidationIssue, type CtValidationResult, type DetectionCacheOptions, type DetectionResult, type EnsureProviderInstructionFileOptions, type EnsureProviderInstructionFileResult, type GlobalOptions, HOOK_CATEGORIES, type HookCategory, type HookEvent, type HookHandlerType, type HookMapping, type HookSupportResult, type HookSystemType, type InjectionCheckResult, type InjectionStatus, type InjectionTemplate, type InstructionUpdateSummary, type LockEntry, MarketplaceClient, type MarketplaceResult, type MarketplaceSearchResult, type MarketplaceSkill, type McpServerConfig, type McpServerEntry, type NormalizedHookEvent, type NormalizedRecommendationCriteria, type ParsedSource, type PlatformPaths, type Provider, type ProviderCapabilities, type ProviderHookProfile, type ProviderHookSummary, type ProviderHooksCapability, 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 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 SystemInfo, type TransportType, type ValidationIssue, type ValidationResult, _resetPlatformPathsCache, buildHookMatrix, buildInjectionContent, buildLibraryFromFiles, buildSkillsMap, catalog, checkAllInjections, checkAllSkillIntegrity, checkAllSkillUpdates, checkInjection, checkSkillIntegrity, checkSkillUpdate, clearRegisteredLibrary, deepMerge, detectAllProviders, detectProjectProviders, detectProvider, discoverSkill, discoverSkills, ensureAllProviderInstructionFiles, ensureDir, ensureProviderInstructionFile, formatSkillRecommendations, generateInjectionContent, generateSkillsSection, getAgentsConfigPath, getAgentsHome, getAgentsInstructFile, getAgentsLinksDir, getAgentsMcpDir, getAgentsMcpServersPath, getAgentsSpecDir, getAgentsWikiDir, getAllCanonicalEvents, getAllProviders, getCanonicalEvent, getCanonicalEventsByCategory, getCanonicalSkillsDir, getCommonEvents, getCommonHookEvents, getEffectiveSkillsPaths, getHookConfigPath, getHookMappingsVersion, getHookSupport, getHookSystemType, getInstalledProviders, getInstructionFiles, getLockFilePath, getMappedProviderIds, getNestedValue, getPlatformLocations, getPlatformPaths, getProjectAgentsDir, getProvider, getProviderCapabilities, getProviderCount, getProviderHookProfile, getProviderOnlyEvents, getProviderSummary, getProvidersByHookEvent, getProvidersByInstructFile, getProvidersByPriority, getProvidersBySkillsPrecedence, getProvidersBySpawnCapability, getProvidersByStatus, getProvidersForEvent, getRegistryVersion, getSpawnCapableProviders, getSupportedEvents, getSystemInfo, getTrackedSkills, getUnsupportedEvents, groupByInstructFile, inject, injectAll, installBatchWithRollback, installSkill, isCaampOwnedSkill, isMarketplaceScoped, isQuiet, isVerbose, listCanonicalSkills, loadLibraryFromModule, normalizeRecommendationCriteria, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, recommendSkills, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, removeConfig, removeInjection, removeSkill, removeSkillFromLock, resetDetectionCache, resolveAlias, resolveNativeEvent, resolveProviderSkillsDirs, resolveRegistryTemplatePath, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setQuiet, setVerbose, shouldOverrideSkill, supportsHook, toCanonical, toNative, toNativeBatch, toSarif, tokenizeCriteriaValue, translateToAll, updateInstructionsSingleOperation, validateInstructionIntegrity, validateRecommendationCriteria, validateSkill, writeConfig };
6348
+ export { type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, CANONICAL_HOOK_EVENTS, type CaampLockFile, type CanonicalEventDefinition, type CanonicalHookEvent, type ConfigFormat, type CrossProviderMatrix, type CtDispatchMatrix, type CtManifest, type CtManifestSkill, type CtProfileDefinition, type CtSkillEntry, type CtValidationIssue, type CtValidationResult, type DetectionCacheOptions, type DetectionResult, type EnsureProviderInstructionFileOptions, type EnsureProviderInstructionFileResult, 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 InstructionUpdateSummary, type LockEntry, MarketplaceClient, type MarketplaceResult, type MarketplaceSearchResult, type MarketplaceSkill, type McpConfigFormat, type McpServerConfig, type McpServerEntry, type McpServerSpec, type McpTransportType, type NormalizedHookEvent, type NormalizedRecommendationCriteria, type ParsedSource, PiHarness, type PlatformPaths, 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 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 SystemInfo, type TransportType, type ValidationIssue, type ValidationResult, _resetPlatformPathsCache, buildHookMatrix, buildInjectionContent, buildLibraryFromFiles, buildSkillsMap, catalog, checkAllInjections, checkAllSkillIntegrity, checkAllSkillUpdates, checkInjection, checkSkillIntegrity, checkSkillUpdate, clearRegisteredLibrary, deepMerge, detectAllProviders, 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, getHarnessFor, getHookConfigPath, getHookMappingsVersion, getHookSupport, getHookSystemType, getInstalledProviders, getInstructionFiles, getLockFilePath, getMappedProviderIds, getNestedValue, getPlatformLocations, getPlatformPaths, getPrimaryHarness, getPrimaryProvider, getProjectAgentsDir, getProvider, getProviderCapabilities, getProviderCount, getProviderHookProfile, getProviderOnlyEvents, getProviderSummary, getProvidersByHookEvent, getProvidersByInstructFile, getProvidersByPriority, getProvidersBySkillsPrecedence, getProvidersBySpawnCapability, getProvidersByStatus, getProvidersForEvent, getRegistryVersion, getSpawnCapableProviders, getSupportedEvents, getSystemInfo, getTrackedSkills, getUnsupportedEvents, groupByInstructFile, inject, injectAll, installBatchWithRollback, installSkill, isCaampOwnedSkill, isMarketplaceScoped, isQuiet, isVerbose, listCanonicalSkills, loadLibraryFromModule, normalizeRecommendationCriteria, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, recommendSkills, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, removeConfig, removeInjection, removeSkill, removeSkillFromLock, resetDetectionCache, resolveAlias, resolveDefaultTargetProviders, resolveNativeEvent, resolveProviderSkillsDirs, resolveRegistryTemplatePath, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setQuiet, setVerbose, shouldOverrideSkill, supportsHook, toCanonical, toNative, toNativeBatch, toSarif, tokenizeCriteriaValue, translateToAll, updateInstructionsSingleOperation, validateInstructionIntegrity, validateRecommendationCriteria, validateSkill, writeConfig };