/** * What a file in a vigiles-owned source directory IS — decided in ONE place. * * `.vigiles/hooks/` and `.vigiles/providers/` hold several kinds of file side by * side: the programs `vigiles compile` turns into wiring, the tests that exercise * them, type declarations, and the `.json` stamp `compile` writes next to each * hook. Discovery used to ask "does it end in a runnable extension?" and treat * every yes as a hook (#278): a `task-list-nudge.harness.mjs` beside its * `task-list-nudge.hook.ts` was compiled as a hook and failed the build. The * obvious patch — subtract the names that bit (`.harness.`, `.test.`) — is a list * of what a hook is NOT, and a list of that kind is open: the next helper file * somebody colocates is the next report. * * So a hook is defined by what it IS. A file's kind comes from ONE marker, the * LAST dot-separated segment before the extension (`guard.hook.mjs` → `hook`), * looked up in ONE table ({@link MARKERS}). Because exactly one segment decides, * a name has exactly one kind; because the table is closed, every consumer can * `switch` over {@link SourceKind} exhaustively and the compiler names the next * one that forgets a case. A runnable file whose marker is not in the table is * `unclaimed` — a kind of its own, not an absence — so a renamed-away hook is a * reported fact rather than a silent hole. * * The patterns test discovery uses (`vigiles test`, `vigiles eval`, the coverage * defaults, the browser twin) are DERIVED from the same table. They used to be * five hand-kept copies of one fact: `*.harness.*` and `*.eval.*` are tests. * * Pure and import-free on purpose. `hook-install.ts` imports this and is reached * from the hook runtime, where every module is a per-call cost, and the browser * twin of coverage detection needs it too — nothing here may touch `node:*`. */ /** * Every extension Node executes directly. `.mts`/`.cts` are real (TS 4.7+) and * Node 22 strips their types with no toolchain — measured, not assumed. */ export declare const RUNNABLE_EXTS: readonly ["mjs", "cjs", "js", "mts", "cts", "ts"]; /** Which vigiles test runner takes a file: `vigiles test` or `vigiles eval`. */ export type TestTier = "harness" | "eval"; /** * The closed union of what a file in a source directory can be. Exactly one per * name; see {@link classifySource}. */ export type SourceKind = /** A compiled-hook program: `guard.hook.mjs`. */ { readonly kind: "hook"; } /** A registered context provider: `k8s.provider.mjs`. */ | { readonly kind: "provider"; } /** A vigiles test: `guard.harness.mjs` (`vigiles test`) or `guard.eval.mjs` (`vigiles eval`). */ | { readonly kind: "vigiles-test"; readonly test: TestTier; } /** A type declaration: `x.d.ts`, `x.d.mts`, `x.d.cts`. */ | { readonly kind: "declaration"; } /** The `.json` sidecar `compile` writes beside a source: `guard.hook.mjs.json`. */ | { readonly kind: "stamp"; } /** Not a runnable source at all: `README.md`, `.gitkeep`, a stray `.json`. */ | { readonly kind: "non-source"; } /** * A runnable file whose name carries no marker vigiles knows: `guard.mjs` * (a hook from before the marker), `util.ts`, `guard.test.ts`. Nobody's — and * therefore never compiled, and never silently ignored either. */ | { readonly kind: "unclaimed"; }; /** The markers that name a file a vigiles consumer COMPILES (as opposed to runs or ignores). */ export type CompilableMarker = "hook" | "provider"; /** * The kind of a file, from its BASENAME. Total: every string has an answer, and * the answer is one member of {@link SourceKind}. * * Order matters and is the whole algorithm: a declaration is a declaration even * when its infix says `hook` (`x.hook.d.ts`); a `.json` beside a source is its * stamp; then the last infix is looked up. Case-sensitive, like the file systems * these names mostly live on. */ export declare function classifySource(filename: string): SourceKind; /** * Is this basename an eval script — the PAID tier, the one that spends real * model calls? It decides which of two runners owns a test file, and has been * wrong in both directions: * * - As the full suffix `.eval.mjs`: `foo.eval.ts` fell into the free branch and * would have spent real model calls on every push. * - As the bare INFIX `.eval.`: `parser.eval.test.ts`, an ordinary deterministic * test, was credited to the paid tier and dropped from the free one — though * `vigiles eval` cannot discover that name at all. * * The answer that is wrong in neither direction is the runner's own: `.eval.` * followed by a runnable extension AT THE END of the name, which is exactly what * the last-infix rule of {@link classifySource} says. * * @param filename a BASENAME — callers strip the directory with their own path * helper (`node:path` on disk, `posix-path` in the browser twin). */ export declare function isEvalScript(filename: string): boolean; /** Is this basename a vigiles test of either tier? */ export declare function isVigilesTest(filename: string): boolean; /** The glob `vigiles test` / `vigiles eval` discover a tier's scripts with. */ export declare function testGlob(tier: TestTier): string; /** The patterns coverage credits tests with by default — one per tier, from the table. */ export declare const DEFAULT_TEST_GLOBS: readonly string[]; /** The last path segment, whichever separator precedes it. */ export declare const baseName: (path: string) => string; /** Everything up to and including the last separator, or "" when there is none. */ export declare const dirName: (path: string) => string; /** * `guard.mjs` → `guard.hook.mjs`: the name a file must carry to be claimed as * `marker`. Keeps the directory. The inverse of {@link preMarkerName}. */ export declare function markedName(path: string, marker: CompilableMarker): string; /** * `guard.hook.mjs` → `guard.mjs`: the name a file carried before the marker * existed, or `undefined` when the name has no such marker. Used to recognise * the wiring an older vigiles wrote for the same file. */ export declare function preMarkerName(path: string, marker: CompilableMarker): string | undefined; //# sourceMappingURL=source-kinds.d.ts.map