@cleocode/caamp 2026.4.7 → 2026.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-HEAGCHKU.js → chunk-JC77OAHA.js} +790 -44
- package/dist/chunk-JC77OAHA.js.map +1 -0
- package/dist/cli.js +279 -29
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1103 -290
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-HEAGCHKU.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1487,252 +1487,6 @@ interface InstructionUpdateSummary {
|
|
|
1487
1487
|
*/
|
|
1488
1488
|
declare function updateInstructionsSingleOperation(providers: Provider[], content: string, scope?: Scope, projectDir?: string): Promise<InstructionUpdateSummary>;
|
|
1489
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
1490
|
/**
|
|
1737
1491
|
* Three-tier scope helper for Pi harness operations.
|
|
1738
1492
|
*
|
|
@@ -1816,6 +1570,72 @@ type HarnessScope = {
|
|
|
1816
1570
|
kind: 'project';
|
|
1817
1571
|
projectDir: string;
|
|
1818
1572
|
};
|
|
1573
|
+
/**
|
|
1574
|
+
* Options accepted by `resolveDefaultTargetProviders` (defined in
|
|
1575
|
+
* `./index.ts`).
|
|
1576
|
+
*
|
|
1577
|
+
* @remarks
|
|
1578
|
+
* Both fields are optional. When the entire options object is omitted the
|
|
1579
|
+
* helper behaves exactly as it did pre-ADR-035 §D7 in `auto` mode with Pi
|
|
1580
|
+
* installed — the no-regression contract for existing callers.
|
|
1581
|
+
*
|
|
1582
|
+
* Lives here in `types.ts` rather than next to the function so that
|
|
1583
|
+
* downstream packages can `import type { ResolveDefaultTargetProvidersOptions }`
|
|
1584
|
+
* without pulling in the harness dispatcher's runtime imports.
|
|
1585
|
+
*
|
|
1586
|
+
* @public
|
|
1587
|
+
*/
|
|
1588
|
+
interface ResolveDefaultTargetProvidersOptions {
|
|
1589
|
+
/**
|
|
1590
|
+
* Explicit list of providers requested by the user (e.g. via `--agent`).
|
|
1591
|
+
*
|
|
1592
|
+
* @remarks
|
|
1593
|
+
* When supplied, this list signals that the caller is honouring an
|
|
1594
|
+
* explicit user selection rather than asking for the implicit default.
|
|
1595
|
+
* In `auto` mode, an explicit list that excludes Pi while Pi is installed
|
|
1596
|
+
* triggers a one-time deprecation warning per process. In `force-pi`
|
|
1597
|
+
* mode the explicit list is ignored if it does not contain Pi (Pi is
|
|
1598
|
+
* still required). In `legacy` mode the list is returned verbatim with
|
|
1599
|
+
* no warning.
|
|
1600
|
+
*
|
|
1601
|
+
* Pass `undefined` (or omit entirely) to request the implicit default
|
|
1602
|
+
* resolution.
|
|
1603
|
+
*
|
|
1604
|
+
* @defaultValue undefined
|
|
1605
|
+
*/
|
|
1606
|
+
explicit?: Provider[];
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Controls how `resolveDefaultTargetProviders` (defined in `./index.ts`)
|
|
1610
|
+
* selects target providers at runtime invocation time.
|
|
1611
|
+
*
|
|
1612
|
+
* @remarks
|
|
1613
|
+
* Introduced by ADR-035 §D7 ("v3 exclusivity") to give users an explicit
|
|
1614
|
+
* knob over how aggressively CAAMP routes runtime commands through Pi
|
|
1615
|
+
* versus other installed providers.
|
|
1616
|
+
*
|
|
1617
|
+
* - `'auto'` (default) — Pi is preferred when installed; explicit
|
|
1618
|
+
* `--agent <non-pi>` selections are still honoured but emit a one-time
|
|
1619
|
+
* deprecation warning per process. Behaviourally identical to v2026.4.5
|
|
1620
|
+
* when no explicit non-Pi target is supplied.
|
|
1621
|
+
* - `'force-pi'` — Pi is required at runtime invocation. The dispatcher
|
|
1622
|
+
* throws with an `E_NOT_FOUND_RESOURCE`-shaped error when Pi is not
|
|
1623
|
+
* installed; callers decide whether to surface this as an exit code 4
|
|
1624
|
+
* or render a remediation hint.
|
|
1625
|
+
* - `'legacy'` — Pre-exclusivity behaviour. No deprecation warnings, no
|
|
1626
|
+
* hard requirement on Pi. Matches the resolution order CAAMP shipped
|
|
1627
|
+
* before ADR-035 §D7 landed; preserved so users with brittle scripts
|
|
1628
|
+
* can pin until they migrate.
|
|
1629
|
+
*
|
|
1630
|
+
* **Important**: this setting affects RUNTIME INVOCATION paths only. Skill
|
|
1631
|
+
* and instruction install paths
|
|
1632
|
+
* (e.g. {@link dispatchInstallSkillAcrossProviders} and friends) are
|
|
1633
|
+
* UNAFFECTED and continue to dispatch to multiple providers regardless of
|
|
1634
|
+
* mode. See ADR-035 §D7 for the full design rationale.
|
|
1635
|
+
*
|
|
1636
|
+
* @public
|
|
1637
|
+
*/
|
|
1638
|
+
type ExclusivityMode = 'auto' | 'force-pi' | 'legacy';
|
|
1819
1639
|
/**
|
|
1820
1640
|
* Metadata describing a Pi extension discovered on disk.
|
|
1821
1641
|
*
|
|
@@ -1896,6 +1716,121 @@ interface HarnessInstallOptions {
|
|
|
1896
1716
|
*/
|
|
1897
1717
|
force?: boolean;
|
|
1898
1718
|
}
|
|
1719
|
+
/**
|
|
1720
|
+
* Counts of top-level CANT sections discovered in a `.cant` file.
|
|
1721
|
+
*
|
|
1722
|
+
* @remarks
|
|
1723
|
+
* Returned by {@link Harness.listCantProfiles} and
|
|
1724
|
+
* {@link Harness.validateCantProfile} so that callers can surface a
|
|
1725
|
+
* concise summary of every profile (agents, workflows, pipelines,
|
|
1726
|
+
* top-level hooks, and skill references declared by an agent's
|
|
1727
|
+
* `skills:` property) without reading the full document body.
|
|
1728
|
+
*
|
|
1729
|
+
* The cant-core AST tags every section as a single-key wrapper
|
|
1730
|
+
* (`{ Agent: { ... } }`, `{ Workflow: { ... } }`, etc.), so these
|
|
1731
|
+
* counters are derived by walking `document.sections` and bucketing
|
|
1732
|
+
* by tag. `skillCount` aggregates the unique skill names declared
|
|
1733
|
+
* across every Agent section's `skills:` property — it is NOT a
|
|
1734
|
+
* count of standalone `skill { ... }` blocks because cant-core does
|
|
1735
|
+
* not currently expose those at the document level.
|
|
1736
|
+
*
|
|
1737
|
+
* @public
|
|
1738
|
+
*/
|
|
1739
|
+
interface CantProfileCounts {
|
|
1740
|
+
/** Number of `agent { ... }` sections in the document. */
|
|
1741
|
+
agentCount: number;
|
|
1742
|
+
/** Number of `workflow { ... }` sections in the document. */
|
|
1743
|
+
workflowCount: number;
|
|
1744
|
+
/** Number of `pipeline { ... }` sections in the document. */
|
|
1745
|
+
pipelineCount: number;
|
|
1746
|
+
/**
|
|
1747
|
+
* Number of hook bodies discovered. Top-level `Hook` sections plus
|
|
1748
|
+
* the `hooks` array nested inside every Agent section are summed.
|
|
1749
|
+
*/
|
|
1750
|
+
hookCount: number;
|
|
1751
|
+
/**
|
|
1752
|
+
* Number of distinct skill names referenced via an Agent section's
|
|
1753
|
+
* `skills:` property (e.g. `skills: ["ct-cleo", "ct-task-executor"]`).
|
|
1754
|
+
* The count is de-duplicated across agents within a single document.
|
|
1755
|
+
*/
|
|
1756
|
+
skillCount: number;
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Metadata describing a `.cant` profile installed at one of the three
|
|
1760
|
+
* Pi harness tiers.
|
|
1761
|
+
*
|
|
1762
|
+
* @remarks
|
|
1763
|
+
* Returned by {@link Harness.listCantProfiles}. Mirrors the shape of
|
|
1764
|
+
* {@link ExtensionEntry} so consumers can render both with the same
|
|
1765
|
+
* UI primitives, but adds a {@link counts} bag with parsed AST stats
|
|
1766
|
+
* so the list output can summarise each profile without forcing the
|
|
1767
|
+
* caller to re-parse every file.
|
|
1768
|
+
*
|
|
1769
|
+
* @public
|
|
1770
|
+
*/
|
|
1771
|
+
interface CantProfileEntry {
|
|
1772
|
+
/** Profile name (basename of the `.cant` file without the extension). */
|
|
1773
|
+
name: string;
|
|
1774
|
+
/** Tier at which this entry lives. */
|
|
1775
|
+
tier: HarnessTier;
|
|
1776
|
+
/** Absolute on-disk path to the `.cant` file. */
|
|
1777
|
+
sourcePath: string;
|
|
1778
|
+
/** Parsed section counts for the profile. */
|
|
1779
|
+
counts: CantProfileCounts;
|
|
1780
|
+
/**
|
|
1781
|
+
* When `true`, this entry is shadowed by a higher-precedence entry
|
|
1782
|
+
* with the same name. Mirrors the shadow flag emitted by
|
|
1783
|
+
* {@link Harness.listExtensions} so the same UI logic applies.
|
|
1784
|
+
* @defaultValue false
|
|
1785
|
+
*/
|
|
1786
|
+
shadowedByHigherTier?: boolean;
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Diagnostic emitted by the cant-core 42-rule validator, normalised to
|
|
1790
|
+
* the harness layer's vocabulary.
|
|
1791
|
+
*
|
|
1792
|
+
* @remarks
|
|
1793
|
+
* Mirrors the `NativeDiagnostic` shape exported by `@cleocode/cant`'s
|
|
1794
|
+
* native loader. Captured here as a first-class harness type so callers
|
|
1795
|
+
* never have to import from `@cleocode/cant` directly to consume
|
|
1796
|
+
* {@link Harness.validateCantProfile} results.
|
|
1797
|
+
*
|
|
1798
|
+
* @public
|
|
1799
|
+
*/
|
|
1800
|
+
interface CantValidationDiagnostic {
|
|
1801
|
+
/** Cant-core rule id (`PARSE`, `S01`, `P06`, ...). */
|
|
1802
|
+
ruleId: string;
|
|
1803
|
+
/** Human-readable diagnostic message. */
|
|
1804
|
+
message: string;
|
|
1805
|
+
/** 1-based line number where the diagnostic was emitted. */
|
|
1806
|
+
line: number;
|
|
1807
|
+
/** 1-based column number where the diagnostic was emitted. */
|
|
1808
|
+
col: number;
|
|
1809
|
+
/** Severity bucket from cant-core (`error`, `warning`, `info`, `hint`). */
|
|
1810
|
+
severity: 'error' | 'warning' | 'info' | 'hint';
|
|
1811
|
+
}
|
|
1812
|
+
/**
|
|
1813
|
+
* Result of validating a `.cant` profile via the cant-core 42-rule
|
|
1814
|
+
* engine.
|
|
1815
|
+
*
|
|
1816
|
+
* @remarks
|
|
1817
|
+
* Returned by {@link Harness.validateCantProfile}. The `valid` flag is
|
|
1818
|
+
* `true` only when no error-severity diagnostics were emitted (warnings
|
|
1819
|
+
* are tolerated, matching cant-core's own definition). The
|
|
1820
|
+
* {@link counts} bag is populated only when parsing succeeded — when
|
|
1821
|
+
* the file is so broken cant-core cannot produce a document, every
|
|
1822
|
+
* counter is `0` and the diagnostics array carries the parse errors.
|
|
1823
|
+
*
|
|
1824
|
+
* @public
|
|
1825
|
+
*/
|
|
1826
|
+
interface ValidateCantProfileResult {
|
|
1827
|
+
/** Whether validation passed (no error-severity diagnostics). */
|
|
1828
|
+
valid: boolean;
|
|
1829
|
+
/** All diagnostics emitted by the 42-rule engine, in source order. */
|
|
1830
|
+
errors: CantValidationDiagnostic[];
|
|
1831
|
+
/** Section counts for the profile (zero when parsing failed). */
|
|
1832
|
+
counts: CantProfileCounts;
|
|
1833
|
+
}
|
|
1899
1834
|
/**
|
|
1900
1835
|
* Summary header extracted from the first line of a Pi session JSONL file.
|
|
1901
1836
|
*
|
|
@@ -2058,6 +1993,12 @@ interface ModelListEntry {
|
|
|
2058
1993
|
* is a routing hint passed to the harness; concrete harnesses may use it
|
|
2059
1994
|
* to select an inner agent or simply record it for observability.
|
|
2060
1995
|
*
|
|
1996
|
+
* Per ADR-035 §D6, every spawn has a stable {@link taskId} and is
|
|
1997
|
+
* attributed to a parent session via {@link parentSessionId}. When the
|
|
1998
|
+
* caller provides {@link parentSessionPath}, the harness records a
|
|
1999
|
+
* `subagent_link` custom entry into that file so listing the parent
|
|
2000
|
+
* session surfaces its children automatically.
|
|
2001
|
+
*
|
|
2061
2002
|
* @public
|
|
2062
2003
|
*/
|
|
2063
2004
|
interface SubagentTask {
|
|
@@ -2065,6 +2006,42 @@ interface SubagentTask {
|
|
|
2065
2006
|
targetProviderId: string;
|
|
2066
2007
|
/** The prompt / instruction to give the spawned agent. */
|
|
2067
2008
|
prompt: string;
|
|
2009
|
+
/**
|
|
2010
|
+
* Stable task identifier used to derive the child session filename and
|
|
2011
|
+
* to correlate streamed events with their originating task.
|
|
2012
|
+
*
|
|
2013
|
+
* @remarks
|
|
2014
|
+
* When omitted, the harness generates a short id at spawn time so
|
|
2015
|
+
* legacy callers (pre-ADR-035 §D6) keep working. New callers SHOULD
|
|
2016
|
+
* always supply a deterministic value.
|
|
2017
|
+
*
|
|
2018
|
+
* @defaultValue undefined
|
|
2019
|
+
*/
|
|
2020
|
+
taskId?: string;
|
|
2021
|
+
/**
|
|
2022
|
+
* Identifier of the parent session that owns this subagent.
|
|
2023
|
+
*
|
|
2024
|
+
* @remarks
|
|
2025
|
+
* Used to compose the child session filename
|
|
2026
|
+
* (`subagent-{parentSessionId}-{taskId}.jsonl`) per ADR-035 §D6.
|
|
2027
|
+
* When omitted, the harness substitutes `"orphan"` so legacy callers
|
|
2028
|
+
* still produce a well-formed file path.
|
|
2029
|
+
*
|
|
2030
|
+
* @defaultValue undefined
|
|
2031
|
+
*/
|
|
2032
|
+
parentSessionId?: string;
|
|
2033
|
+
/**
|
|
2034
|
+
* Absolute path to the parent session JSONL file.
|
|
2035
|
+
*
|
|
2036
|
+
* @remarks
|
|
2037
|
+
* When supplied, the harness appends a {@link SubagentLinkEntry} as
|
|
2038
|
+
* a `custom` entry to this file at spawn time so listing the parent
|
|
2039
|
+
* surfaces its children automatically. When omitted, no link entry
|
|
2040
|
+
* is written and the parent session is not modified.
|
|
2041
|
+
*
|
|
2042
|
+
* @defaultValue undefined
|
|
2043
|
+
*/
|
|
2044
|
+
parentSessionPath?: string;
|
|
2068
2045
|
/**
|
|
2069
2046
|
* Working directory for the spawned agent.
|
|
2070
2047
|
* @defaultValue undefined
|
|
@@ -2076,18 +2053,136 @@ interface SubagentTask {
|
|
|
2076
2053
|
*/
|
|
2077
2054
|
env?: Record<string, string>;
|
|
2078
2055
|
/**
|
|
2079
|
-
* Abort signal. When it aborts, the harness will terminate the subagent
|
|
2056
|
+
* Abort signal. When it aborts, the harness will terminate the subagent
|
|
2057
|
+
* via the configured SIGTERM-then-SIGKILL cleanup sequence.
|
|
2080
2058
|
* @defaultValue undefined
|
|
2081
2059
|
*/
|
|
2082
2060
|
signal?: AbortSignal;
|
|
2083
2061
|
}
|
|
2084
2062
|
/**
|
|
2085
|
-
*
|
|
2063
|
+
* Per-call options that override harness-wide spawn defaults.
|
|
2064
|
+
*
|
|
2065
|
+
* @remarks
|
|
2066
|
+
* Introduced for ADR-035 §D6 streaming + cleanup semantics. Every field
|
|
2067
|
+
* is optional so callers that just want default behaviour can omit the
|
|
2068
|
+
* second argument entirely.
|
|
2069
|
+
*
|
|
2070
|
+
* @public
|
|
2071
|
+
*/
|
|
2072
|
+
interface SubagentSpawnOptions {
|
|
2073
|
+
/**
|
|
2074
|
+
* Streaming callback invoked once per parsed event from the child.
|
|
2075
|
+
*
|
|
2076
|
+
* @remarks
|
|
2077
|
+
* The harness fires this for every line of stdout (parsed as JSON when
|
|
2078
|
+
* possible), every line of stderr, the final exit, and the
|
|
2079
|
+
* `subagent_link` write. Callbacks are best-effort: throwing from the
|
|
2080
|
+
* callback is caught and recorded as a stderr line so the spawn loop
|
|
2081
|
+
* is never aborted by user code.
|
|
2082
|
+
*
|
|
2083
|
+
* @defaultValue undefined
|
|
2084
|
+
*/
|
|
2085
|
+
onStream?: (event: SubagentStreamEvent) => void;
|
|
2086
|
+
/**
|
|
2087
|
+
* Override the SIGTERM grace window before SIGKILL fires.
|
|
2088
|
+
*
|
|
2089
|
+
* @remarks
|
|
2090
|
+
* When omitted, the harness reads
|
|
2091
|
+
* `settings.json:pi.subagent.terminateGraceMs` (global scope) and
|
|
2092
|
+
* falls back to `5000` ms if absent or invalid. Tests use very small
|
|
2093
|
+
* values to keep cleanup checks fast.
|
|
2094
|
+
*
|
|
2095
|
+
* @defaultValue undefined
|
|
2096
|
+
*/
|
|
2097
|
+
terminateGraceMs?: number;
|
|
2098
|
+
/**
|
|
2099
|
+
* Environment variable overrides layered atop the task-level env.
|
|
2100
|
+
*
|
|
2101
|
+
* @remarks
|
|
2102
|
+
* Convenience hook for per-call secrets that should not live on the
|
|
2103
|
+
* task object itself. Merged after {@link SubagentTask.env} so
|
|
2104
|
+
* call-site keys win.
|
|
2105
|
+
*
|
|
2106
|
+
* @defaultValue undefined
|
|
2107
|
+
*/
|
|
2108
|
+
env?: Record<string, string>;
|
|
2109
|
+
/**
|
|
2110
|
+
* Working directory override that wins over {@link SubagentTask.cwd}.
|
|
2111
|
+
*
|
|
2112
|
+
* @remarks
|
|
2113
|
+
* Useful when the same task description is reused across multiple
|
|
2114
|
+
* working directories.
|
|
2115
|
+
*
|
|
2116
|
+
* @defaultValue undefined
|
|
2117
|
+
*/
|
|
2118
|
+
cwd?: string;
|
|
2119
|
+
}
|
|
2120
|
+
/**
|
|
2121
|
+
* One streaming event surfaced through {@link SubagentSpawnOptions.onStream}.
|
|
2122
|
+
*
|
|
2123
|
+
* @remarks
|
|
2124
|
+
* Discriminated by {@link kind}:
|
|
2125
|
+
*
|
|
2126
|
+
* - `"message"` — a successfully parsed JSON line from the child's
|
|
2127
|
+
* stdout. {@link payload} is the parsed object and {@link lineNumber}
|
|
2128
|
+
* is the 1-based line index within the child's stdout stream.
|
|
2129
|
+
* - `"stderr"` — a single line from the child's stderr stream. The
|
|
2130
|
+
* {@link payload} is `{ line: string }`. The harness NEVER injects
|
|
2131
|
+
* stderr into the parent LLM context per ADR-035 §D6.
|
|
2132
|
+
* - `"exit"` — the child has exited. {@link payload} is a
|
|
2133
|
+
* {@link SubagentExitResult}.
|
|
2134
|
+
* - `"link"` — the harness wrote a `subagent_link` custom entry to the
|
|
2135
|
+
* parent session. {@link payload} is the {@link SubagentLinkEntry}.
|
|
2136
|
+
*
|
|
2137
|
+
* @public
|
|
2138
|
+
*/
|
|
2139
|
+
interface SubagentStreamEvent {
|
|
2140
|
+
/** Event kind discriminator. */
|
|
2141
|
+
kind: 'message' | 'stderr' | 'exit' | 'link';
|
|
2142
|
+
/** Subagent identifier (matches {@link SubagentHandle.subagentId}). */
|
|
2143
|
+
subagentId: string;
|
|
2144
|
+
/**
|
|
2145
|
+
* 1-based line number within the child's stdout stream. Only set for
|
|
2146
|
+
* `"message"` events that originated from a parsed stdout line.
|
|
2147
|
+
* @defaultValue undefined
|
|
2148
|
+
*/
|
|
2149
|
+
lineNumber?: number;
|
|
2150
|
+
/** Event payload, shaped according to {@link kind}. */
|
|
2151
|
+
payload: unknown;
|
|
2152
|
+
}
|
|
2153
|
+
/**
|
|
2154
|
+
* Resolution value of {@link SubagentHandle.exitPromise}.
|
|
2155
|
+
*
|
|
2156
|
+
* @remarks
|
|
2157
|
+
* Captured exactly once when the child process exits. The promise NEVER
|
|
2158
|
+
* rejects — failure is encoded by a non-zero {@link code}, a non-null
|
|
2159
|
+
* {@link signal}, or partial output preserved in the child session file
|
|
2160
|
+
* at {@link childSessionPath}.
|
|
2161
|
+
*
|
|
2162
|
+
* @public
|
|
2163
|
+
*/
|
|
2164
|
+
interface SubagentExitResult {
|
|
2165
|
+
/**
|
|
2166
|
+
* Process exit code, or `null` when the child was terminated by a
|
|
2167
|
+
* signal before exiting normally.
|
|
2168
|
+
*/
|
|
2169
|
+
code: number | null;
|
|
2170
|
+
/** Terminating signal, or `null` when the child exited normally. */
|
|
2171
|
+
signal: NodeJS.Signals | null;
|
|
2172
|
+
/** Absolute path to the child session JSONL file on disk. */
|
|
2173
|
+
childSessionPath: string;
|
|
2174
|
+
/** Wall-clock duration from spawn to exit, in milliseconds. */
|
|
2175
|
+
durationMs: number;
|
|
2176
|
+
}
|
|
2177
|
+
/**
|
|
2178
|
+
* Final result of a subagent's execution (legacy v1 shape).
|
|
2086
2179
|
*
|
|
2087
2180
|
* @remarks
|
|
2088
|
-
*
|
|
2089
|
-
*
|
|
2090
|
-
*
|
|
2181
|
+
* Preserved for back-compat with pre-ADR-035 §D6 callers. New code
|
|
2182
|
+
* SHOULD await {@link SubagentHandle.exitPromise} (which resolves with
|
|
2183
|
+
* a richer {@link SubagentExitResult}) instead. The harness still
|
|
2184
|
+
* populates this field on every spawn so existing tests and callers
|
|
2185
|
+
* keep working.
|
|
2091
2186
|
*
|
|
2092
2187
|
* @public
|
|
2093
2188
|
*/
|
|
@@ -2110,18 +2205,87 @@ interface SubagentResult {
|
|
|
2110
2205
|
*
|
|
2111
2206
|
* @remarks
|
|
2112
2207
|
* Returned synchronously from {@link Harness.spawnSubagent}. The caller
|
|
2113
|
-
* may
|
|
2114
|
-
*
|
|
2208
|
+
* may:
|
|
2209
|
+
*
|
|
2210
|
+
* - Await {@link exitPromise} to collect the rich {@link SubagentExitResult}
|
|
2211
|
+
* (preferred path, ADR-035 §D6).
|
|
2212
|
+
* - Await {@link result} to collect the legacy {@link SubagentResult}
|
|
2213
|
+
* (preserved for back-compat).
|
|
2214
|
+
* - Invoke {@link terminate} (preferred) or {@link abort} (legacy) to
|
|
2215
|
+
* stop the child early via the configured SIGTERM-then-SIGKILL
|
|
2216
|
+
* cleanup sequence.
|
|
2217
|
+
* - Inspect {@link recentStderr} for the most recent stderr lines
|
|
2218
|
+
* captured by the harness — useful for post-mortem diagnostics
|
|
2219
|
+
* without injecting stderr into the parent LLM context.
|
|
2115
2220
|
*
|
|
2116
2221
|
* @public
|
|
2117
2222
|
*/
|
|
2118
2223
|
interface SubagentHandle {
|
|
2224
|
+
/**
|
|
2225
|
+
* Stable subagent identifier generated at spawn time.
|
|
2226
|
+
*
|
|
2227
|
+
* @remarks
|
|
2228
|
+
* Format: `sub-{taskId}-{shortRandom}`. Used to correlate
|
|
2229
|
+
* {@link SubagentStreamEvent} entries and `subagent_link` records
|
|
2230
|
+
* with this handle. Always defined (the harness never returns a
|
|
2231
|
+
* handle without one).
|
|
2232
|
+
*/
|
|
2233
|
+
subagentId: string;
|
|
2234
|
+
/** Task identifier from {@link SubagentTask.taskId} (or generated default). */
|
|
2235
|
+
taskId: string;
|
|
2236
|
+
/** Absolute path to the child session JSONL file on disk. */
|
|
2237
|
+
childSessionPath: string;
|
|
2119
2238
|
/** PID of the spawned process, or `null` if spawning did not yield one. */
|
|
2120
2239
|
pid: number | null;
|
|
2121
|
-
/**
|
|
2240
|
+
/** Wall-clock timestamp captured immediately after spawn. */
|
|
2241
|
+
startedAt: Date;
|
|
2242
|
+
/**
|
|
2243
|
+
* Promise resolving to the rich exit result once the child process
|
|
2244
|
+
* has fully terminated. NEVER rejects — failures are encoded in the
|
|
2245
|
+
* resolved value (non-zero code, non-null signal, partial output in
|
|
2246
|
+
* the session file).
|
|
2247
|
+
*/
|
|
2248
|
+
exitPromise: Promise<SubagentExitResult>;
|
|
2249
|
+
/**
|
|
2250
|
+
* Promise resolving to the legacy {@link SubagentResult} shape.
|
|
2251
|
+
*
|
|
2252
|
+
* @remarks
|
|
2253
|
+
* Preserved for back-compat. Resolves to the same exit code as
|
|
2254
|
+
* {@link exitPromise} plus the full captured stdout / stderr buffers
|
|
2255
|
+
* and a best-effort `parsed` field for callers that emit a single
|
|
2256
|
+
* JSON document.
|
|
2257
|
+
*/
|
|
2122
2258
|
result: Promise<SubagentResult>;
|
|
2123
|
-
/**
|
|
2259
|
+
/**
|
|
2260
|
+
* Terminate the subagent gracefully.
|
|
2261
|
+
*
|
|
2262
|
+
* @remarks
|
|
2263
|
+
* Sends SIGTERM, waits for the configured grace window, then sends
|
|
2264
|
+
* SIGKILL if the child is still alive. Idempotent — subsequent calls
|
|
2265
|
+
* after the first are no-ops. Returns once the cleanup sequence has
|
|
2266
|
+
* fully resolved.
|
|
2267
|
+
*/
|
|
2268
|
+
terminate(): Promise<void>;
|
|
2269
|
+
/**
|
|
2270
|
+
* Synchronously trigger the cleanup sequence (legacy v1 alias for
|
|
2271
|
+
* {@link terminate}).
|
|
2272
|
+
*
|
|
2273
|
+
* @remarks
|
|
2274
|
+
* Preserved so existing callers that use `handle.abort()` keep
|
|
2275
|
+
* working. Internally enqueues the same SIGTERM-then-SIGKILL flow as
|
|
2276
|
+
* {@link terminate} but does not return the resulting promise.
|
|
2277
|
+
*/
|
|
2124
2278
|
abort: () => void;
|
|
2279
|
+
/**
|
|
2280
|
+
* Snapshot of the most recent stderr lines captured for this child.
|
|
2281
|
+
*
|
|
2282
|
+
* @remarks
|
|
2283
|
+
* Bounded ring buffer (last 100 lines) so memory cannot grow without
|
|
2284
|
+
* bound under chatty stderr. Stderr is NEVER injected into the
|
|
2285
|
+
* parent LLM context — this accessor is intended for diagnostics and
|
|
2286
|
+
* post-mortem inspection only.
|
|
2287
|
+
*/
|
|
2288
|
+
recentStderr(): string[];
|
|
2125
2289
|
}
|
|
2126
2290
|
/**
|
|
2127
2291
|
* Contract every first-class harness must implement.
|
|
@@ -2209,16 +2373,25 @@ interface Harness {
|
|
|
2209
2373
|
* @remarks
|
|
2210
2374
|
* For Pi: invokes `child_process.spawn` with the provider's configured
|
|
2211
2375
|
* `capabilities.spawn.spawnCommand`, appending the task prompt as a
|
|
2212
|
-
* trailing positional argument. The returned handle lets the caller
|
|
2213
|
-
* completion
|
|
2376
|
+
* trailing positional argument. The returned handle lets the caller
|
|
2377
|
+
* await completion ({@link SubagentHandle.exitPromise}), terminate the
|
|
2378
|
+
* child via the SIGTERM-then-SIGKILL cleanup sequence
|
|
2379
|
+
* ({@link SubagentHandle.terminate}), and inspect recent stderr for
|
|
2380
|
+
* post-mortem diagnostics ({@link SubagentHandle.recentStderr}).
|
|
2381
|
+
*
|
|
2382
|
+
* Per ADR-035 §D6, this is the **only** canonical subagent spawn path
|
|
2383
|
+
* in CLEO. New callers MUST go through the harness instead of calling
|
|
2384
|
+
* `child_process.spawn` directly so session attribution, streaming,
|
|
2385
|
+
* and cleanup remain uniform.
|
|
2214
2386
|
*
|
|
2215
2387
|
* Optional — harnesses that cannot spawn other agents should omit this
|
|
2216
2388
|
* method. Callers MUST feature-check before invoking.
|
|
2217
2389
|
*
|
|
2218
2390
|
* @param task - Subagent task specification.
|
|
2391
|
+
* @param opts - Per-call streaming and cleanup overrides.
|
|
2219
2392
|
* @returns A live subagent handle.
|
|
2220
2393
|
*/
|
|
2221
|
-
spawnSubagent?(task: SubagentTask): Promise<SubagentHandle>;
|
|
2394
|
+
spawnSubagent?(task: SubagentTask, opts?: SubagentSpawnOptions): Promise<SubagentHandle>;
|
|
2222
2395
|
/**
|
|
2223
2396
|
* Configure which models are available in the harness's model picker.
|
|
2224
2397
|
*
|
|
@@ -2392,7 +2565,497 @@ interface Harness {
|
|
|
2392
2565
|
listThemes?(projectDir?: string): Promise<ThemeEntry[]>;
|
|
2393
2566
|
/** Remove a Pi theme by name from the given tier. */
|
|
2394
2567
|
removeTheme?(name: string, tier: HarnessTier, projectDir?: string): Promise<boolean>;
|
|
2568
|
+
/**
|
|
2569
|
+
* Install a CANT profile (`.cant` file) into the given tier.
|
|
2570
|
+
*
|
|
2571
|
+
* @remarks
|
|
2572
|
+
* Per ADR-035 §D5 (CANT single engine), CANT profiles are first-class
|
|
2573
|
+
* Pi assets consumed by the canonical `cant-bridge.ts` extension via
|
|
2574
|
+
* `/cant:load <file>` at runtime. This verb copies a source `.cant`
|
|
2575
|
+
* file into the requested tier so the bridge can discover it.
|
|
2576
|
+
*
|
|
2577
|
+
* Implementations MUST validate the source via cant-core's 42-rule
|
|
2578
|
+
* engine before copying — invalid `.cant` files are rejected. The
|
|
2579
|
+
* conflict-on-write rule from §D1 cross-cutting concerns applies:
|
|
2580
|
+
* existing targets cause an error unless `opts.force` is set.
|
|
2581
|
+
*
|
|
2582
|
+
* Optional on the interface because only first-class harnesses with a
|
|
2583
|
+
* native CANT bridge support this verb.
|
|
2584
|
+
*
|
|
2585
|
+
* @param sourcePath - Absolute path to the source `.cant` file on disk.
|
|
2586
|
+
* @param name - Profile name (used as the target file basename).
|
|
2587
|
+
* @param tier - Target tier (`project`/`user`/`global`).
|
|
2588
|
+
* @param projectDir - Project directory (required when `tier='project'`).
|
|
2589
|
+
* @param opts - Install options (see {@link HarnessInstallOptions}).
|
|
2590
|
+
*/
|
|
2591
|
+
installCantProfile?(sourcePath: string, name: string, tier: HarnessTier, projectDir?: string, opts?: HarnessInstallOptions): Promise<{
|
|
2592
|
+
targetPath: string;
|
|
2593
|
+
tier: HarnessTier;
|
|
2594
|
+
counts: CantProfileCounts;
|
|
2595
|
+
}>;
|
|
2596
|
+
/**
|
|
2597
|
+
* Remove a CANT profile by name from the given tier.
|
|
2598
|
+
*
|
|
2599
|
+
* @remarks
|
|
2600
|
+
* Missing files are tolerated silently so the verb is usable as an
|
|
2601
|
+
* idempotent "ensure absent" operation.
|
|
2602
|
+
*
|
|
2603
|
+
* @param name - Profile name (basename without `.cant`).
|
|
2604
|
+
* @param tier - Target tier to remove from.
|
|
2605
|
+
* @param projectDir - Project directory (required when `tier='project'`).
|
|
2606
|
+
* @returns `true` when a file was removed, `false` when none existed.
|
|
2607
|
+
*/
|
|
2608
|
+
removeCantProfile?(name: string, tier: HarnessTier, projectDir?: string): Promise<boolean>;
|
|
2609
|
+
/**
|
|
2610
|
+
* List CANT profiles across all tiers, precedence-ordered.
|
|
2611
|
+
*
|
|
2612
|
+
* @remarks
|
|
2613
|
+
* Walks every tier in {@link HarnessTier} precedence order
|
|
2614
|
+
* (project → user → global) and parses each `.cant` file to extract
|
|
2615
|
+
* its section counts. Higher-precedence tiers shadow lower-precedence
|
|
2616
|
+
* entries with the same name; the {@link CantProfileEntry.shadowedByHigherTier}
|
|
2617
|
+
* flag indicates shadowed copies so callers can warn about
|
|
2618
|
+
* cross-tier name collisions per ADR-035 §D1.
|
|
2619
|
+
*
|
|
2620
|
+
* @param projectDir - Project directory for the `project` tier. When
|
|
2621
|
+
* omitted the `project` tier is skipped rather than failing.
|
|
2622
|
+
*/
|
|
2623
|
+
listCantProfiles?(projectDir?: string): Promise<CantProfileEntry[]>;
|
|
2624
|
+
/**
|
|
2625
|
+
* Validate a `.cant` file via cant-core's 42-rule engine without
|
|
2626
|
+
* installing anything.
|
|
2627
|
+
*
|
|
2628
|
+
* @remarks
|
|
2629
|
+
* Pure helper used by `caamp pi cant validate <path>`. Reads the file,
|
|
2630
|
+
* parses it, runs the validator, and returns a structured
|
|
2631
|
+
* {@link ValidateCantProfileResult}. Never mutates state on disk.
|
|
2632
|
+
*
|
|
2633
|
+
* @param sourcePath - Absolute path to the `.cant` file on disk.
|
|
2634
|
+
*/
|
|
2635
|
+
validateCantProfile?(sourcePath: string): Promise<ValidateCantProfileResult>;
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
/**
|
|
2639
|
+
* CAAMP-wide configuration accessors.
|
|
2640
|
+
*
|
|
2641
|
+
* @remarks
|
|
2642
|
+
* This module is the single source of truth for CAAMP configuration values
|
|
2643
|
+
* that affect runtime behaviour across the package. Today it carries one
|
|
2644
|
+
* setting — {@link ExclusivityMode} — introduced by ADR-035 §D7 to control
|
|
2645
|
+
* how `resolveDefaultTargetProviders()` selects target providers at runtime
|
|
2646
|
+
* invocation time.
|
|
2647
|
+
*
|
|
2648
|
+
* The accessor pattern intentionally uses a layered resolution order so the
|
|
2649
|
+
* setting can be overridden by tests, by environment variables in CI, and by
|
|
2650
|
+
* future programmatic callers (e.g. a `caamp config set` subcommand) without
|
|
2651
|
+
* any of those layers needing to know about the others:
|
|
2652
|
+
*
|
|
2653
|
+
* 1. Programmatic override via {@link setExclusivityMode} (highest priority).
|
|
2654
|
+
* 2. Environment variable `CAAMP_EXCLUSIVITY_MODE`.
|
|
2655
|
+
* 3. Default value `'auto'`.
|
|
2656
|
+
*
|
|
2657
|
+
* The programmatic override exists primarily for tests and for future
|
|
2658
|
+
* `caamp config set` integration; production code should prefer the
|
|
2659
|
+
* environment variable when wiring CI or shell sessions.
|
|
2660
|
+
*
|
|
2661
|
+
* @packageDocumentation
|
|
2662
|
+
*/
|
|
2663
|
+
|
|
2664
|
+
/**
|
|
2665
|
+
* Default exclusivity mode used when no override is configured.
|
|
2666
|
+
*
|
|
2667
|
+
* @remarks
|
|
2668
|
+
* `auto` mirrors the v2026.4.5+ behaviour: Pi is preferred when installed,
|
|
2669
|
+
* but explicit non-Pi targets remain functional. This is the value the
|
|
2670
|
+
* accessor returns when neither {@link setExclusivityMode} nor the
|
|
2671
|
+
* `CAAMP_EXCLUSIVITY_MODE` environment variable is set.
|
|
2672
|
+
*
|
|
2673
|
+
* @public
|
|
2674
|
+
*/
|
|
2675
|
+
declare const DEFAULT_EXCLUSIVITY_MODE: ExclusivityMode;
|
|
2676
|
+
/**
|
|
2677
|
+
* Environment variable name read by {@link getExclusivityMode} when no
|
|
2678
|
+
* programmatic override is active.
|
|
2679
|
+
*
|
|
2680
|
+
* @remarks
|
|
2681
|
+
* Exported as a constant so tests and downstream tooling can refer to the
|
|
2682
|
+
* canonical name without typo risk. The variable accepts the same three
|
|
2683
|
+
* literal values as the {@link ExclusivityMode} type.
|
|
2684
|
+
*
|
|
2685
|
+
* @public
|
|
2686
|
+
*/
|
|
2687
|
+
declare const EXCLUSIVITY_MODE_ENV_VAR = "CAAMP_EXCLUSIVITY_MODE";
|
|
2688
|
+
/**
|
|
2689
|
+
* Error raised when {@link getExclusivityMode} resolves to `'force-pi'` but
|
|
2690
|
+
* Pi is not installed at the moment a runtime dispatch is requested.
|
|
2691
|
+
*
|
|
2692
|
+
* @remarks
|
|
2693
|
+
* Carries an `E_NOT_FOUND_RESOURCE`-shaped `code` so command-layer error
|
|
2694
|
+
* envelopes (LAFS) can map it to a stable category. Callers decide whether
|
|
2695
|
+
* to surface this as a process exit (typically code 4) or as a structured
|
|
2696
|
+
* envelope; the harness layer never calls `process.exit` itself.
|
|
2697
|
+
*
|
|
2698
|
+
* Lives next to the configuration accessor rather than in the harness
|
|
2699
|
+
* dispatcher so consumers that import the mode also pick up the matching
|
|
2700
|
+
* error type without a second module hop.
|
|
2701
|
+
*
|
|
2702
|
+
* @example
|
|
2703
|
+
* ```typescript
|
|
2704
|
+
* try {
|
|
2705
|
+
* const targets = resolveDefaultTargetProviders();
|
|
2706
|
+
* } catch (err) {
|
|
2707
|
+
* if (err instanceof PiRequiredError) {
|
|
2708
|
+
* process.exit(4);
|
|
2709
|
+
* }
|
|
2710
|
+
* throw err;
|
|
2711
|
+
* }
|
|
2712
|
+
* ```
|
|
2713
|
+
*
|
|
2714
|
+
* @public
|
|
2715
|
+
*/
|
|
2716
|
+
declare class PiRequiredError extends Error {
|
|
2717
|
+
/** LAFS-stable error code identifying this failure mode. */
|
|
2718
|
+
readonly code: "E_NOT_FOUND_RESOURCE";
|
|
2719
|
+
/**
|
|
2720
|
+
* Construct a new {@link PiRequiredError}.
|
|
2721
|
+
*
|
|
2722
|
+
* @param message - Human-readable failure description; defaults to a
|
|
2723
|
+
* stable string suitable for direct CLI display.
|
|
2724
|
+
*/
|
|
2725
|
+
constructor(message?: string);
|
|
2726
|
+
}
|
|
2727
|
+
/**
|
|
2728
|
+
* Type guard that narrows an arbitrary string to {@link ExclusivityMode}.
|
|
2729
|
+
*
|
|
2730
|
+
* @remarks
|
|
2731
|
+
* Used both internally and by callers that need to validate untrusted input
|
|
2732
|
+
* (e.g. CLI flag parsers, env var readers) before passing it through to
|
|
2733
|
+
* {@link setExclusivityMode}.
|
|
2734
|
+
*
|
|
2735
|
+
* @param value - Candidate value to validate.
|
|
2736
|
+
* @returns `true` when `value` is one of `'auto'`, `'force-pi'`, `'legacy'`.
|
|
2737
|
+
*
|
|
2738
|
+
* @example
|
|
2739
|
+
* ```typescript
|
|
2740
|
+
* if (isExclusivityMode(userInput)) {
|
|
2741
|
+
* setExclusivityMode(userInput);
|
|
2742
|
+
* }
|
|
2743
|
+
* ```
|
|
2744
|
+
*
|
|
2745
|
+
* @public
|
|
2746
|
+
*/
|
|
2747
|
+
declare function isExclusivityMode(value: string): value is ExclusivityMode;
|
|
2748
|
+
/**
|
|
2749
|
+
* Resolve the active CAAMP exclusivity mode using the layered precedence
|
|
2750
|
+
* documented in {@link DEFAULT_EXCLUSIVITY_MODE}.
|
|
2751
|
+
*
|
|
2752
|
+
* @remarks
|
|
2753
|
+
* Resolution order:
|
|
2754
|
+
*
|
|
2755
|
+
* 1. Programmatic override (set via {@link setExclusivityMode}).
|
|
2756
|
+
* 2. Environment variable `CAAMP_EXCLUSIVITY_MODE`.
|
|
2757
|
+
* 3. {@link DEFAULT_EXCLUSIVITY_MODE} (`'auto'`).
|
|
2758
|
+
*
|
|
2759
|
+
* Invalid environment variable values are silently ignored (resolution
|
|
2760
|
+
* falls through to the default) so a typo in CI does not crash the CLI.
|
|
2761
|
+
* The value is never cached — every call re-reads the environment so tests
|
|
2762
|
+
* that mutate `process.env` see consistent results without needing to
|
|
2763
|
+
* reset module state.
|
|
2764
|
+
*
|
|
2765
|
+
* @returns The currently effective exclusivity mode.
|
|
2766
|
+
*
|
|
2767
|
+
* @example
|
|
2768
|
+
* ```typescript
|
|
2769
|
+
* const mode = getExclusivityMode();
|
|
2770
|
+
* if (mode === 'force-pi') {
|
|
2771
|
+
* // ...
|
|
2772
|
+
* }
|
|
2773
|
+
* ```
|
|
2774
|
+
*
|
|
2775
|
+
* @public
|
|
2776
|
+
*/
|
|
2777
|
+
declare function getExclusivityMode(): ExclusivityMode;
|
|
2778
|
+
/**
|
|
2779
|
+
* Install a programmatic override for the exclusivity mode.
|
|
2780
|
+
*
|
|
2781
|
+
* @remarks
|
|
2782
|
+
* The override takes precedence over the environment variable for the
|
|
2783
|
+
* remainder of the process or until {@link resetExclusivityModeOverride}
|
|
2784
|
+
* is called. Intended for tests, for future `caamp config set` wiring, and
|
|
2785
|
+
* for short-lived runtime adjustments (e.g. a one-shot CLI flag).
|
|
2786
|
+
*
|
|
2787
|
+
* @param mode - Mode to install.
|
|
2788
|
+
*
|
|
2789
|
+
* @example
|
|
2790
|
+
* ```typescript
|
|
2791
|
+
* setExclusivityMode('force-pi');
|
|
2792
|
+
* try {
|
|
2793
|
+
* await runCommand();
|
|
2794
|
+
* } finally {
|
|
2795
|
+
* resetExclusivityModeOverride();
|
|
2796
|
+
* }
|
|
2797
|
+
* ```
|
|
2798
|
+
*
|
|
2799
|
+
* @public
|
|
2800
|
+
*/
|
|
2801
|
+
declare function setExclusivityMode(mode: ExclusivityMode): void;
|
|
2802
|
+
/**
|
|
2803
|
+
* Clear any programmatic override installed by {@link setExclusivityMode}.
|
|
2804
|
+
*
|
|
2805
|
+
* @remarks
|
|
2806
|
+
* After calling this, {@link getExclusivityMode} resumes reading from the
|
|
2807
|
+
* environment variable (and falls back to the default when the env var is
|
|
2808
|
+
* unset or invalid). Idempotent — safe to call when no override is active.
|
|
2809
|
+
*
|
|
2810
|
+
* @public
|
|
2811
|
+
*/
|
|
2812
|
+
declare function resetExclusivityModeOverride(): void;
|
|
2813
|
+
|
|
2814
|
+
/**
|
|
2815
|
+
* Format utility functions
|
|
2816
|
+
*/
|
|
2817
|
+
/**
|
|
2818
|
+
* Deep merge two objects, with `source` values winning on conflict.
|
|
2819
|
+
*
|
|
2820
|
+
* Recursively merges nested plain objects. Arrays and non-object values from
|
|
2821
|
+
* `source` overwrite `target` values.
|
|
2822
|
+
*
|
|
2823
|
+
* @param target - Base object to merge into
|
|
2824
|
+
* @param source - Object with values that take precedence
|
|
2825
|
+
* @returns A new merged object (does not mutate inputs)
|
|
2826
|
+
*
|
|
2827
|
+
* @remarks
|
|
2828
|
+
* Only plain objects are recursively merged. Arrays and primitive values from
|
|
2829
|
+
* `source` replace `target` values outright. Neither input is mutated.
|
|
2830
|
+
*
|
|
2831
|
+
* @example
|
|
2832
|
+
* ```typescript
|
|
2833
|
+
* const merged = deepMerge({ a: 1, b: { c: 2 } }, { b: { d: 3 } });
|
|
2834
|
+
* // { a: 1, b: { c: 2, d: 3 } }
|
|
2835
|
+
* ```
|
|
2836
|
+
*
|
|
2837
|
+
* @public
|
|
2838
|
+
*/
|
|
2839
|
+
declare function deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown>;
|
|
2840
|
+
/**
|
|
2841
|
+
* Get a nested value from an object using a dot-notation key path.
|
|
2842
|
+
*
|
|
2843
|
+
* @param obj - Object to traverse
|
|
2844
|
+
* @param keyPath - Dot-separated key path (e.g. `"mcpServers"` or `"a.b.c"`)
|
|
2845
|
+
* @returns The value at the key path, or `undefined` if not found
|
|
2846
|
+
*
|
|
2847
|
+
* @remarks
|
|
2848
|
+
* Splits the key path on `.` and walks the object tree. Returns `undefined`
|
|
2849
|
+
* at the first missing or non-object segment.
|
|
2850
|
+
*
|
|
2851
|
+
* @example
|
|
2852
|
+
* ```typescript
|
|
2853
|
+
* getNestedValue({ a: { b: { c: 42 } } }, "a.b.c"); // 42
|
|
2854
|
+
* getNestedValue({ a: 1 }, "a.b"); // undefined
|
|
2855
|
+
* ```
|
|
2856
|
+
*
|
|
2857
|
+
* @public
|
|
2858
|
+
*/
|
|
2859
|
+
declare function getNestedValue(obj: Record<string, unknown>, keyPath: string): unknown;
|
|
2860
|
+
/**
|
|
2861
|
+
* Ensure that the parent directories of a file path exist.
|
|
2862
|
+
*
|
|
2863
|
+
* Creates directories recursively if they do not exist.
|
|
2864
|
+
*
|
|
2865
|
+
* @param filePath - Absolute path to a file (parent directories will be created)
|
|
2866
|
+
*
|
|
2867
|
+
* @remarks
|
|
2868
|
+
* Uses `mkdir` with `recursive: true` so existing directories are not an error.
|
|
2869
|
+
*
|
|
2870
|
+
* @example
|
|
2871
|
+
* ```typescript
|
|
2872
|
+
* await ensureDir("/path/to/new/dir/file.json");
|
|
2873
|
+
* // /path/to/new/dir/ now exists
|
|
2874
|
+
* ```
|
|
2875
|
+
*
|
|
2876
|
+
* @public
|
|
2877
|
+
*/
|
|
2878
|
+
declare function ensureDir(filePath: string): Promise<void>;
|
|
2879
|
+
|
|
2880
|
+
/**
|
|
2881
|
+
* Provides format-agnostic config read, write, and remove operations that
|
|
2882
|
+
* dispatch to JSON/JSONC, YAML, or TOML handlers based on the specified
|
|
2883
|
+
* format.
|
|
2884
|
+
*
|
|
2885
|
+
* @packageDocumentation
|
|
2886
|
+
*/
|
|
2887
|
+
|
|
2888
|
+
/**
|
|
2889
|
+
* Read and parse a config file in the specified format.
|
|
2890
|
+
*
|
|
2891
|
+
* Dispatches to the appropriate format handler (JSON/JSONC, YAML, or TOML).
|
|
2892
|
+
*
|
|
2893
|
+
* @param filePath - Absolute path to the config file
|
|
2894
|
+
* @param format - Config file format
|
|
2895
|
+
* @returns Parsed config object
|
|
2896
|
+
* @throws If the file cannot be read or the format is unsupported
|
|
2897
|
+
*
|
|
2898
|
+
* @remarks
|
|
2899
|
+
* Supported formats: `"json"`, `"jsonc"`, `"yaml"`, `"toml"`. Throws for
|
|
2900
|
+
* any unrecognized format string.
|
|
2901
|
+
*
|
|
2902
|
+
* @example
|
|
2903
|
+
* ```typescript
|
|
2904
|
+
* const config = await readConfig("/path/to/config.json", "jsonc");
|
|
2905
|
+
* ```
|
|
2906
|
+
*
|
|
2907
|
+
* @public
|
|
2908
|
+
*/
|
|
2909
|
+
declare function readConfig(filePath: string, format: ConfigFormat): Promise<Record<string, unknown>>;
|
|
2910
|
+
/**
|
|
2911
|
+
* Write a server entry to a config file, preserving existing content.
|
|
2912
|
+
*
|
|
2913
|
+
* Dispatches to the appropriate format handler. For JSONC files, comments are
|
|
2914
|
+
* preserved using `jsonc-parser`.
|
|
2915
|
+
*
|
|
2916
|
+
* @param filePath - Absolute path to the config file
|
|
2917
|
+
* @param format - Config file format
|
|
2918
|
+
* @param key - Dot-notation key path to the servers section (e.g. `"mcpServers"`)
|
|
2919
|
+
* @param serverName - Name/key for the server entry
|
|
2920
|
+
* @param serverConfig - Server configuration object to write
|
|
2921
|
+
* @throws If the format is unsupported
|
|
2922
|
+
*
|
|
2923
|
+
* @remarks
|
|
2924
|
+
* For JSONC files, comments and formatting are preserved using `jsonc-parser`.
|
|
2925
|
+
* For YAML and TOML, the file is fully re-serialized after deep-merging.
|
|
2926
|
+
*
|
|
2927
|
+
* @example
|
|
2928
|
+
* ```typescript
|
|
2929
|
+
* await writeConfig("/path/to/config.json", "jsonc", "mcpServers", "my-server", config);
|
|
2930
|
+
* ```
|
|
2931
|
+
*
|
|
2932
|
+
* @public
|
|
2933
|
+
*/
|
|
2934
|
+
declare function writeConfig(filePath: string, format: ConfigFormat, key: string, serverName: string, serverConfig: unknown): Promise<void>;
|
|
2935
|
+
/**
|
|
2936
|
+
* Remove a server entry from a config file in the specified format.
|
|
2937
|
+
*
|
|
2938
|
+
* @param filePath - Absolute path to the config file
|
|
2939
|
+
* @param format - Config file format
|
|
2940
|
+
* @param key - Dot-notation key path to the servers section
|
|
2941
|
+
* @param serverName - Name/key of the server entry to remove
|
|
2942
|
+
* @returns `true` if the entry was removed, `false` otherwise
|
|
2943
|
+
* @throws If the format is unsupported
|
|
2944
|
+
*
|
|
2945
|
+
* @remarks
|
|
2946
|
+
* Delegates to the format-specific removal function. Returns `false` when the
|
|
2947
|
+
* file does not exist or the entry is not found.
|
|
2948
|
+
*
|
|
2949
|
+
* @example
|
|
2950
|
+
* ```typescript
|
|
2951
|
+
* const removed = await removeConfig("/path/to/config.json", "jsonc", "mcpServers", "my-server");
|
|
2952
|
+
* ```
|
|
2953
|
+
*
|
|
2954
|
+
* @public
|
|
2955
|
+
*/
|
|
2956
|
+
declare function removeConfig(filePath: string, format: ConfigFormat, key: string, serverName: string): Promise<boolean>;
|
|
2957
|
+
|
|
2958
|
+
/**
|
|
2959
|
+
* Skill installer - canonical + symlink model
|
|
2960
|
+
*
|
|
2961
|
+
* Skills are stored once in a canonical location (.agents/skills/<name>/)
|
|
2962
|
+
* and symlinked to each target agent's skills directory.
|
|
2963
|
+
*/
|
|
2964
|
+
|
|
2965
|
+
/**
|
|
2966
|
+
* Result of installing a skill to the canonical location and linking to agents.
|
|
2967
|
+
*
|
|
2968
|
+
* @example
|
|
2969
|
+
* ```typescript
|
|
2970
|
+
* const result = await installSkill(sourcePath, "my-skill", providers, true);
|
|
2971
|
+
* if (result.success) {
|
|
2972
|
+
* console.log(`Installed to ${result.canonicalPath}`);
|
|
2973
|
+
* console.log(`Linked to: ${result.linkedAgents.join(", ")}`);
|
|
2974
|
+
* }
|
|
2975
|
+
* ```
|
|
2976
|
+
*
|
|
2977
|
+
* @public
|
|
2978
|
+
*/
|
|
2979
|
+
interface SkillInstallResult {
|
|
2980
|
+
/** Skill name. */
|
|
2981
|
+
name: string;
|
|
2982
|
+
/** Absolute path to the canonical installation directory. */
|
|
2983
|
+
canonicalPath: string;
|
|
2984
|
+
/** Provider IDs that were successfully linked. */
|
|
2985
|
+
linkedAgents: string[];
|
|
2986
|
+
/** Error messages from failed link operations. */
|
|
2987
|
+
errors: string[];
|
|
2988
|
+
/** Whether at least one agent was successfully linked. */
|
|
2989
|
+
success: boolean;
|
|
2395
2990
|
}
|
|
2991
|
+
/**
|
|
2992
|
+
* Install a skill from a local path to the canonical location and link to agents.
|
|
2993
|
+
*
|
|
2994
|
+
* @remarks
|
|
2995
|
+
* Copies the skill directory to the canonical skills directory and creates symlinks
|
|
2996
|
+
* (or copies on Windows) from each provider's skills directory to the canonical path.
|
|
2997
|
+
*
|
|
2998
|
+
* @param sourcePath - Local path to the skill directory to install
|
|
2999
|
+
* @param skillName - Name for the installed skill
|
|
3000
|
+
* @param providers - Target providers to link the skill to
|
|
3001
|
+
* @param isGlobal - Whether to link to global or project skill directories
|
|
3002
|
+
* @param projectDir - Project directory (defaults to `process.cwd()`)
|
|
3003
|
+
* @returns Install result with linked agents and any errors
|
|
3004
|
+
*
|
|
3005
|
+
* @example
|
|
3006
|
+
* ```typescript
|
|
3007
|
+
* const result = await installSkill("/tmp/my-skill", "my-skill", providers, true, "/my/project");
|
|
3008
|
+
* if (result.success) {
|
|
3009
|
+
* console.log(`Linked to: ${result.linkedAgents.join(", ")}`);
|
|
3010
|
+
* }
|
|
3011
|
+
* ```
|
|
3012
|
+
*
|
|
3013
|
+
* @public
|
|
3014
|
+
*/
|
|
3015
|
+
declare function installSkill(sourcePath: string, skillName: string, providers: Provider[], isGlobal: boolean, projectDir?: string): Promise<SkillInstallResult>;
|
|
3016
|
+
/**
|
|
3017
|
+
* Remove a skill from the canonical location and all agent symlinks.
|
|
3018
|
+
*
|
|
3019
|
+
* @remarks
|
|
3020
|
+
* Removes symlinks from each provider's skills directory and then removes the
|
|
3021
|
+
* canonical copy from the centralized canonical skills directory.
|
|
3022
|
+
*
|
|
3023
|
+
* @param skillName - Name of the skill to remove
|
|
3024
|
+
* @param providers - Providers to unlink the skill from
|
|
3025
|
+
* @param isGlobal - Whether to target global or project skill directories
|
|
3026
|
+
* @param projectDir - Project directory (defaults to `process.cwd()`)
|
|
3027
|
+
* @returns Object with arrays of successfully removed provider IDs and error messages
|
|
3028
|
+
*
|
|
3029
|
+
* @example
|
|
3030
|
+
* ```typescript
|
|
3031
|
+
* const { removed, errors } = await removeSkill("my-skill", providers, true, "/my/project");
|
|
3032
|
+
* console.log(`Removed from: ${removed.join(", ")}`);
|
|
3033
|
+
* ```
|
|
3034
|
+
*
|
|
3035
|
+
* @public
|
|
3036
|
+
*/
|
|
3037
|
+
declare function removeSkill(skillName: string, providers: Provider[], isGlobal: boolean, projectDir?: string): Promise<{
|
|
3038
|
+
removed: string[];
|
|
3039
|
+
errors: string[];
|
|
3040
|
+
}>;
|
|
3041
|
+
/**
|
|
3042
|
+
* List all skills installed in the canonical skills directory.
|
|
3043
|
+
*
|
|
3044
|
+
* @remarks
|
|
3045
|
+
* Returns the directory names of all skills, which correspond to skill names.
|
|
3046
|
+
* Includes both regular directories and symlinks in the canonical location.
|
|
3047
|
+
*
|
|
3048
|
+
* @returns Array of skill names
|
|
3049
|
+
*
|
|
3050
|
+
* @example
|
|
3051
|
+
* ```typescript
|
|
3052
|
+
* const skills = await listCanonicalSkills();
|
|
3053
|
+
* // ["my-skill", "another-skill"]
|
|
3054
|
+
* ```
|
|
3055
|
+
*
|
|
3056
|
+
* @public
|
|
3057
|
+
*/
|
|
3058
|
+
declare function listCanonicalSkills(): Promise<string[]>;
|
|
2396
3059
|
|
|
2397
3060
|
/**
|
|
2398
3061
|
* Pi coding agent harness.
|
|
@@ -2470,19 +3133,118 @@ declare class PiHarness implements Harness {
|
|
|
2470
3133
|
/** {@inheritDoc Harness.removeInstructions} */
|
|
2471
3134
|
removeInstructions(scope: HarnessScope): Promise<void>;
|
|
2472
3135
|
/**
|
|
2473
|
-
*
|
|
3136
|
+
* Spawn a subagent through Pi's configured `spawnCommand` and return a
|
|
3137
|
+
* live handle bound to the canonical streaming, attribution, and
|
|
3138
|
+
* cleanup contract.
|
|
3139
|
+
*
|
|
3140
|
+
* @remarks
|
|
3141
|
+
* Per ADR-035 §D6 this is the **only** sanctioned subagent spawn path
|
|
3142
|
+
* in CLEO. All historical direct `child_process.spawn` callers in
|
|
3143
|
+
* subagent contexts (including the `cant-bridge.ts` Pi extension and
|
|
3144
|
+
* the legacy CLEO orchestrator paths) MUST migrate to this method so
|
|
3145
|
+
* the contract below holds uniformly. A custom biome rule banning
|
|
3146
|
+
* raw `spawn()` from subagent code is planned for v3 cleanup but is
|
|
3147
|
+
* intentionally NOT enforced in v2 to keep the migration incremental.
|
|
3148
|
+
*
|
|
3149
|
+
* **Streaming semantics** — Pi's `--mode json` produces line-delimited
|
|
3150
|
+
* JSON on stdout. The harness:
|
|
3151
|
+
*
|
|
3152
|
+
* - Line-buffers stdout, parses each line as JSON, and forwards a
|
|
3153
|
+
* `{ kind: 'message', subagentId, lineNumber, payload }`
|
|
3154
|
+
* {@link SubagentStreamEvent} via {@link SubagentSpawnOptions.onStream}.
|
|
3155
|
+
* Non-parseable lines increment a warning counter (recorded in the
|
|
3156
|
+
* child session as `{ type: 'raw' }`) but never crash the loop.
|
|
3157
|
+
* - Line-buffers stderr separately, forwards each line as
|
|
3158
|
+
* `{ kind: 'stderr', subagentId, payload: { line } }`, and stores
|
|
3159
|
+
* it in a 100-line ring buffer accessible via
|
|
3160
|
+
* {@link SubagentHandle.recentStderr}. Stderr is **never** injected
|
|
3161
|
+
* into the parent LLM context per ADR-035 §D6.
|
|
3162
|
+
* - Emits a final `{ kind: 'exit', subagentId, payload: SubagentExitResult }`
|
|
3163
|
+
* when the child terminates.
|
|
3164
|
+
*
|
|
3165
|
+
* **Session attribution** — Every spawn produces a child session JSONL
|
|
3166
|
+
* file at
|
|
3167
|
+
* `~/.pi/agent/sessions/subagents/subagent-{parentSessionId}-{taskId}.jsonl`.
|
|
3168
|
+
* The header line records the subagentId, taskId, and parent linkage.
|
|
3169
|
+
* When {@link SubagentTask.parentSessionPath} is supplied, a
|
|
3170
|
+
* {@link SubagentLinkEntry} is appended to the parent session file as
|
|
3171
|
+
* a JSONL line so listing the parent surfaces its children.
|
|
3172
|
+
*
|
|
3173
|
+
* **Exit propagation** — {@link SubagentHandle.exitPromise} resolves
|
|
3174
|
+
* with `{ code, signal, childSessionPath, durationMs }` exactly once
|
|
3175
|
+
* when the child exits. The promise NEVER rejects: failure is
|
|
3176
|
+
* encoded by a non-zero `code`, a non-null `signal`, or partial
|
|
3177
|
+
* output preserved in the child session file.
|
|
3178
|
+
*
|
|
3179
|
+
* **Cleanup** — {@link SubagentHandle.terminate} sends SIGTERM, waits
|
|
3180
|
+
* the configured grace window, then sends SIGKILL if the child is
|
|
3181
|
+
* still alive. The grace window is sourced from
|
|
3182
|
+
* {@link SubagentSpawnOptions.terminateGraceMs} when supplied,
|
|
3183
|
+
* otherwise from `settings.json:pi.subagent.terminateGraceMs`,
|
|
3184
|
+
* otherwise from {@link DEFAULT_TERMINATE_GRACE_MS}. A
|
|
3185
|
+
* `subagent_exit` entry with reason `terminated` is appended to the
|
|
3186
|
+
* child session file when cleanup runs.
|
|
3187
|
+
*
|
|
3188
|
+
* **Concurrency** — Use the static helpers
|
|
3189
|
+
* {@link PiHarness.raceSubagents} and
|
|
3190
|
+
* {@link PiHarness.settleAllSubagents} to compose `parallel: race`
|
|
3191
|
+
* and `parallel: settle` constructs from CANT workflows over multiple
|
|
3192
|
+
* handles.
|
|
3193
|
+
*
|
|
3194
|
+
* **Orphan handling** — On the first spawn the harness registers a
|
|
3195
|
+
* process-wide `'exit'` handler that terminates every still-active
|
|
3196
|
+
* subagent so a parent crash never strands children.
|
|
3197
|
+
*
|
|
3198
|
+
* Throws immediately when the provider entry is missing a
|
|
3199
|
+
* `spawnCommand` so callers see configuration errors early rather
|
|
3200
|
+
* than at child-exit time.
|
|
3201
|
+
*
|
|
3202
|
+
* @param task - Subagent task specification.
|
|
3203
|
+
* @param opts - Per-call streaming and cleanup overrides.
|
|
3204
|
+
* @returns A live subagent handle.
|
|
3205
|
+
*/
|
|
3206
|
+
spawnSubagent(task: SubagentTask, opts?: SubagentSpawnOptions): Promise<SubagentHandle>;
|
|
3207
|
+
/**
|
|
3208
|
+
* Race a set of subagent handles, returning the first one that exits.
|
|
3209
|
+
*
|
|
3210
|
+
* @remarks
|
|
3211
|
+
* Maps CANT's `parallel: race` construct (per ADR-035 §D6) onto the
|
|
3212
|
+
* canonical {@link spawnSubagent} contract. The losing handles are
|
|
3213
|
+
* gracefully terminated via {@link SubagentHandle.terminate} once the
|
|
3214
|
+
* first settles so no straggler children outlive the race.
|
|
3215
|
+
*
|
|
3216
|
+
* @param handles - Subagent handles to race.
|
|
3217
|
+
* @returns The {@link SubagentExitResult} of the first child to exit.
|
|
3218
|
+
* @throws When `handles` is empty (caller bug — a race over zero
|
|
3219
|
+
* children has no winner).
|
|
3220
|
+
*/
|
|
3221
|
+
static raceSubagents(handles: SubagentHandle[]): Promise<SubagentExitResult>;
|
|
3222
|
+
/**
|
|
3223
|
+
* Settle a set of subagent handles, returning a parallel array of
|
|
3224
|
+
* results.
|
|
2474
3225
|
*
|
|
2475
3226
|
* @remarks
|
|
2476
|
-
*
|
|
2477
|
-
*
|
|
2478
|
-
*
|
|
2479
|
-
*
|
|
2480
|
-
*
|
|
3227
|
+
* Maps CANT's `parallel: settle` construct (per ADR-035 §D6) onto the
|
|
3228
|
+
* canonical {@link spawnSubagent} contract. Because
|
|
3229
|
+
* {@link SubagentHandle.exitPromise} never rejects, every entry in
|
|
3230
|
+
* the returned array is `{ status: 'fulfilled', value: ... }` under
|
|
3231
|
+
* normal operation; the `PromiseSettledResult` shape is preserved
|
|
3232
|
+
* for forward compatibility with future failure modes.
|
|
3233
|
+
*
|
|
3234
|
+
* @param handles - Subagent handles to settle.
|
|
3235
|
+
* @returns Parallel array of settled exit results, one per input.
|
|
3236
|
+
*/
|
|
3237
|
+
static settleAllSubagents(handles: SubagentHandle[]): Promise<PromiseSettledResult<SubagentExitResult>[]>;
|
|
3238
|
+
/**
|
|
3239
|
+
* Per-line stdout dispatcher used by the streaming buffer flusher.
|
|
2481
3240
|
*
|
|
2482
|
-
*
|
|
2483
|
-
*
|
|
3241
|
+
* @remarks
|
|
3242
|
+
* Extracted as a private method so the line-handling logic stays
|
|
3243
|
+
* close to {@link spawnSubagent} but does not bloat the parent
|
|
3244
|
+
* function. Skips empty lines (a leading newline produces a zero-
|
|
3245
|
+
* length entry that has no semantic meaning).
|
|
2484
3246
|
*/
|
|
2485
|
-
|
|
3247
|
+
private handleStdoutLine;
|
|
2486
3248
|
/** {@inheritDoc Harness.readSettings} */
|
|
2487
3249
|
readSettings(scope: HarnessScope): Promise<unknown>;
|
|
2488
3250
|
/** {@inheritDoc Harness.writeSettings} */
|
|
@@ -2543,6 +3305,47 @@ declare class PiHarness implements Harness {
|
|
|
2543
3305
|
listThemes(projectDir?: string): Promise<ThemeEntry[]>;
|
|
2544
3306
|
/** {@inheritDoc Harness.removeTheme} */
|
|
2545
3307
|
removeTheme(name: string, tier: HarnessTier, projectDir?: string): Promise<boolean>;
|
|
3308
|
+
/**
|
|
3309
|
+
* {@inheritDoc Harness.installCantProfile}
|
|
3310
|
+
*
|
|
3311
|
+
* @remarks
|
|
3312
|
+
* Validates the source via {@link validateCantProfile} before copying so
|
|
3313
|
+
* we never persist a `.cant` file the runtime bridge cannot load. The
|
|
3314
|
+
* target layout is `<tier-root>/cant/<name>.cant`, resolved through
|
|
3315
|
+
* {@link resolveTierDir} so the project/user/global hierarchy stays
|
|
3316
|
+
* consistent with the other Wave-1 verbs.
|
|
3317
|
+
*/
|
|
3318
|
+
installCantProfile(sourcePath: string, name: string, tier: HarnessTier, projectDir?: string, opts?: HarnessInstallOptions): Promise<{
|
|
3319
|
+
targetPath: string;
|
|
3320
|
+
tier: HarnessTier;
|
|
3321
|
+
counts: CantProfileCounts;
|
|
3322
|
+
}>;
|
|
3323
|
+
/** {@inheritDoc Harness.removeCantProfile} */
|
|
3324
|
+
removeCantProfile(name: string, tier: HarnessTier, projectDir?: string): Promise<boolean>;
|
|
3325
|
+
/**
|
|
3326
|
+
* {@inheritDoc Harness.listCantProfiles}
|
|
3327
|
+
*
|
|
3328
|
+
* @remarks
|
|
3329
|
+
* Walks every tier in {@link TIER_PRECEDENCE} order, parsing each
|
|
3330
|
+
* discovered `.cant` file via cant-core to extract a
|
|
3331
|
+
* {@link CantProfileCounts} bag. Higher-precedence tiers shadow
|
|
3332
|
+
* lower-precedence entries with the same name; shadowed entries
|
|
3333
|
+
* still appear in the result but carry the
|
|
3334
|
+
* `shadowedByHigherTier` flag so callers can render the precedence
|
|
3335
|
+
* story without losing visibility of the duplicate.
|
|
3336
|
+
*/
|
|
3337
|
+
listCantProfiles(projectDir?: string): Promise<CantProfileEntry[]>;
|
|
3338
|
+
/**
|
|
3339
|
+
* {@inheritDoc Harness.validateCantProfile}
|
|
3340
|
+
*
|
|
3341
|
+
* @remarks
|
|
3342
|
+
* Pure validator. Reads the file, runs `parseDocument` to derive
|
|
3343
|
+
* counts (when parsing succeeds) and `validateDocument` to collect
|
|
3344
|
+
* the 42-rule diagnostic feed. The two calls are kept independent so
|
|
3345
|
+
* we can still report counts for files that pass parsing but fail a
|
|
3346
|
+
* lint rule.
|
|
3347
|
+
*/
|
|
3348
|
+
validateCantProfile(sourcePath: string): Promise<ValidateCantProfileResult>;
|
|
2546
3349
|
}
|
|
2547
3350
|
|
|
2548
3351
|
/**
|
|
@@ -2624,42 +3427,52 @@ declare function getPrimaryHarness(): Harness | null;
|
|
|
2624
3427
|
declare function getAllHarnesses(): Harness[];
|
|
2625
3428
|
/**
|
|
2626
3429
|
* Resolve the default set of target providers when the user has not passed
|
|
2627
|
-
* `--agent
|
|
3430
|
+
* `--agent`, honouring the active {@link ExclusivityMode}.
|
|
2628
3431
|
*
|
|
2629
3432
|
* @remarks
|
|
2630
|
-
* Resolution policy
|
|
3433
|
+
* Resolution policy is layered. The active {@link ExclusivityMode} (read
|
|
3434
|
+
* via {@link getExclusivityMode}) selects which branch of the matrix runs:
|
|
2631
3435
|
*
|
|
2632
|
-
*
|
|
2633
|
-
*
|
|
2634
|
-
*
|
|
2635
|
-
*
|
|
2636
|
-
*
|
|
2637
|
-
* `"primary"` or `"high"`. This restores the legacy "detected high-tier
|
|
2638
|
-
* providers" fallback that CAAMP has always used when no primary
|
|
2639
|
-
* harness is available.
|
|
2640
|
-
* 3. If the priority filter yields an empty list (e.g. in tests that stub
|
|
2641
|
-
* providers without a `priority` field, or in fresh installs with only
|
|
2642
|
-
* medium/low-tier providers detected), fall back to the full installed
|
|
2643
|
-
* provider list so that commands retain a valid target.
|
|
3436
|
+
* | Mode | Pi installed | Pi absent |
|
|
3437
|
+
* |---|---|---|
|
|
3438
|
+
* | `'auto'` (default) | Returns `[piProvider]`. Explicit non-Pi targets emit a one-time deprecation warning per process. | Falls back to installed primary/high-tier providers (legacy v2026.4.5 behaviour) and emits a one-time boot warning. |
|
|
3439
|
+
* | `'force-pi'` | Returns `[piProvider]`. | Throws {@link PiRequiredError}. |
|
|
3440
|
+
* | `'legacy'` | Returns the full installed provider list in priority order (matches pre-exclusivity behaviour). | Same. |
|
|
2644
3441
|
*
|
|
2645
|
-
*
|
|
2646
|
-
*
|
|
2647
|
-
*
|
|
2648
|
-
*
|
|
3442
|
+
* **Install paths are unaffected.** Per ADR-035 §D7, this helper governs
|
|
3443
|
+
* RUNTIME INVOCATION dispatch only. Skill and instruction install
|
|
3444
|
+
* dispatchers ({@link dispatchInstallSkillAcrossProviders},
|
|
3445
|
+
* {@link dispatchRemoveSkillAcrossProviders}) intentionally do not call
|
|
3446
|
+
* this function — they target every requested provider directly so that
|
|
3447
|
+
* users in `force-pi` mode can still `caamp skills install foo --agent
|
|
3448
|
+
* claude-code` while Pi is being installed.
|
|
2649
3449
|
*
|
|
3450
|
+
* The helper is intentionally defensive: registry/detection exceptions
|
|
3451
|
+
* are caught and treated as "Pi unknown" so stubbed test environments
|
|
3452
|
+
* that do not wire the full registry still behave sensibly.
|
|
3453
|
+
*
|
|
3454
|
+
* @param options - Optional explicit provider selection (e.g. from
|
|
3455
|
+
* `--agent`) used by `auto`-mode deprecation warning detection. Omit to
|
|
3456
|
+
* request the implicit default resolution.
|
|
2650
3457
|
* @returns Ordered list of providers to target by default.
|
|
3458
|
+
* @throws {@link PiRequiredError} when mode is `'force-pi'` and Pi is not
|
|
3459
|
+
* installed.
|
|
2651
3460
|
*
|
|
2652
3461
|
* @example
|
|
2653
3462
|
* ```typescript
|
|
3463
|
+
* // Implicit default — used by `caamp skills list` and friends.
|
|
2654
3464
|
* const targets = resolveDefaultTargetProviders();
|
|
2655
|
-
*
|
|
2656
|
-
*
|
|
2657
|
-
*
|
|
3465
|
+
*
|
|
3466
|
+
* // Explicit user selection — emits a deprecation warning in `auto` mode
|
|
3467
|
+
* // when the selection excludes Pi and Pi is installed.
|
|
3468
|
+
* const explicit = resolveDefaultTargetProviders({
|
|
3469
|
+
* explicit: [getProvider('claude-code')!],
|
|
3470
|
+
* });
|
|
2658
3471
|
* ```
|
|
2659
3472
|
*
|
|
2660
3473
|
* @public
|
|
2661
3474
|
*/
|
|
2662
|
-
declare function resolveDefaultTargetProviders(): Provider[];
|
|
3475
|
+
declare function resolveDefaultTargetProviders(options?: ResolveDefaultTargetProvidersOptions): Provider[];
|
|
2663
3476
|
|
|
2664
3477
|
/**
|
|
2665
3478
|
* All hook event categories (8 total).
|
|
@@ -7099,4 +7912,4 @@ declare function parseSource(input: string): ParsedSource;
|
|
|
7099
7912
|
*/
|
|
7100
7913
|
declare function isMarketplaceScoped(input: string): boolean;
|
|
7101
7914
|
|
|
7102
|
-
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 InstallMcpServerOptions, type InstallMcpServerResult, type InstructionUpdateSummary, 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, 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 RemoveMcpServerOptions, type RemoveMcpServerResult, 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, 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, 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, installMcpServer, installSkill, isCaampOwnedSkill, isMarketplaceScoped, isQuiet, isVerbose, listAllMcpServers, listCanonicalSkills, listMcpServers, loadLibraryFromModule, normalizeRecommendationCriteria, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, recommendSkills, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, removeConfig, removeInjection, removeMcpServer, removeMcpServerFromAll, removeSkill, removeSkillFromLock, resetDetectionCache, resolveAlias, resolveDefaultTargetProviders, resolveMcpConfigPath, resolveNativeEvent, resolveProviderSkillsDirs, resolveRegistryTemplatePath, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setQuiet, setVerbose, shouldOverrideSkill, supportsHook, toCanonical, toNative, toNativeBatch, toSarif, tokenizeCriteriaValue, translateToAll, updateInstructionsSingleOperation, validateInstructionIntegrity, validateRecommendationCriteria, validateSkill, writeConfig };
|
|
7915
|
+
export { type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, CANONICAL_HOOK_EVENTS, 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 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 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 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 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 SystemInfo, type TransportType, type ValidateCantProfileResult, type ValidationIssue, type ValidationResult, _resetPlatformPathsCache, buildHookMatrix, buildInjectionContent, buildLibraryFromFiles, buildSkillsMap, catalog, checkAllInjections, checkAllSkillIntegrity, checkAllSkillUpdates, checkInjection, checkSkillIntegrity, checkSkillUpdate, clearRegisteredLibrary, 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, getProviderCapabilities, getProviderCount, getProviderHookProfile, 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, 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, writeConfig };
|