/** * Extension orchestration pipeline. * * Discovers, loads, merges, sorts, and runs setup for every extension * contributed by the four sources (config, package, project, local-file). * Invoked once by `bootstrap()` after config resolution. * * @module extensions/orchestrate */ import * as defaultDiscovery from "./discovery.js"; import { loadExtensionFactory as defaultLoadFactory } from "./factory-loader.js"; import { ExtensionLoader } from "./loader.js"; import type { ExtensionConfigEntry, ExtensionLogger, ResolvedExtension } from "./types.js"; /** * Options for `orchestrateExtensions`. * * The `discovery` and `loadFactory` fields are test seams — they are not * part of the stable public API and default to the real implementations. */ export interface OrchestrateOptions { projectDir: string; config: { extensions?: ExtensionConfigEntry[]; }; logger: ExtensionLogger; /** Contracts to seed into the registry after teardown, before setup(). */ primeContracts?: Record; /** Built-in extensions shipped with the framework. Lowest priority — any * project, package, or config extension with the same name overrides them. * Users can disable them via `{ name: "ext-llm-anthropic", enabled: false }`. */ builtinExtensions?: ResolvedExtension[]; /** Per-extension setup() timeout in milliseconds. Defaults to 30 000 ms. * Pass `0` to disable. */ setupTimeoutMs?: number; /** * @internal Release process-global resources owned by the previous * generation after its teardown and before candidate setup begins. */ beforeActivate?: () => void | Promise; /** * @internal Override discovery functions in tests. * * This is a trusted injection seam, not an untrusted-data boundary. A custom * implementation controls import targets directly and must return ordinary * data objects, not live or revoked Proxies. */ discovery?: { discoverPackageExtensions: typeof defaultDiscovery.discoverPackageExtensions; discoverProjectExtensions: typeof defaultDiscovery.discoverProjectExtensions; discoverLocalExtensions: typeof defaultDiscovery.discoverLocalExtensions; mergeExtensions: typeof defaultDiscovery.mergeExtensions; }; /** @internal Override factory loading in tests. */ loadFactory?: typeof defaultLoadFactory; } /** * Run the full extension pipeline against a resolved project config. * * Pipeline: * 1. Split `config.extensions` into resolved entries and disable directives. * 2. Discover extensions from package, project, and local sources. * 3. Omit explicit-only discovered extensions and skip loading factories * for package- and project-source extensions whose names appear in the * disable set (local-file names are not reliable pre-load and are * filtered after `mergeExtensions`). * 4. Dynamic-import factories for every remaining discovered path. * 5. Merge sources honoring priority `config > package > project > local-file`. * 6. Construct an `ExtensionLoader` and run `setupAll`. * * On factory error during `setup()`, `ExtensionLoader.setupAll` performs * partial rollback internally. The error is re-thrown unchanged so callers * can surface the extension name to the user. */ export declare function orchestrateExtensions(options: OrchestrateOptions): Promise; //# sourceMappingURL=orchestrate.d.ts.map