/** * Loading a lexicon's plugin so completeness checks can look at what it * actually registers (#1342). * * `check-lexicon`'s checks were almost all existence assertions over the * directory: `src/lsp/completions.ts exists`, `At least 1 lint rule in * src/lint/rules/`. A file with the right name is not the contract — the * contract is the member the plugin exposes, because that is what core * dispatches through. helm is the proof: it ships `src/lsp/completions.ts` and * `src/lsp/hover.ts`, both with passing tests, exports `helmCompletions` and * `helmHover` from its index, and never sets `completionProvider` or * `hoverProvider` on the plugin. `cli/lsp/server.ts` dispatches through exactly * those fields, so helm's LSP support is unreachable in an editor — while tier 1 * (the files) and tier 2 (the tests) both passed. * * Resolution is directory-local rather than by package name: `chant dev * check-lexicon ` should work on a lexicon that is not installed, and * `loadPlugin` in ../plugins.ts imports `@intentius/chant-lexicon-`, * which requires it to be. */ import { type LexiconPlugin } from "../../lexicon.js"; export interface LoadedLexicon { /** The plugin, when the package exported one. */ plugin?: LexiconPlugin; /** Why loading failed, for a check's `detail`. */ error?: string; /** The entry point that was imported, for diagnostics. */ entry?: string; } /** * The module a lexicon package presents to consumers. * * Tier 1 requires `exports["."].default` to be `./src/index.ts`, so that is the * first choice — it is the module core itself imports. The fallbacks keep this * usable on a lexicon that has not reached that check yet. */ export declare function pluginEntryFor(dir: string): string | undefined; /** * Import a lexicon directory and return the `LexiconPlugin` it exports. * * Never throws: a lexicon that cannot be loaded is a finding, not a crash, and * every caller reports it as a failed check rather than aborting the run. */ export declare function loadLexiconFromDir(dir: string): Promise; /** Whether the plugin exposes a callable member under `name`. */ export declare function registers(plugin: LexiconPlugin | undefined, name: keyof LexiconPlugin): boolean; /** * Call a plugin member that returns a list, treating a throw as an empty list. * * A member that throws is not a registration — it is worse than an absent one, * and the check that counts its results should fail rather than the whole run. */ export declare function safeList(fn: (() => T[]) | undefined): { items: T[]; error?: string; }; //# sourceMappingURL=check-lexicon-plugin.d.ts.map