//#region src/types.d.ts /** * Result of executing a single command */ interface ReplResult { stdout: string; stderr: string; exitCode: number | null; } /** * File-level options passed to plugin factory * Includes all frontmatter options and collected file= blocks */ interface FileOpts { /** Absolute path to the .spec.md file */ path: string; /** All file= blocks: filename → content */ files: Map; /** Frontmatter options (excluding 'plugin' field) */ [key: string]: unknown; } /** * Block-level options passed to plugin.block() * Pre-merged: frontmatter + section + fence options */ interface BlockOpts { /** Block language: console, sh, bash, json, etc. */ type: string; /** Raw block content */ content: string; /** Heading path: ['Setup', 'Basic'] */ heading: string[]; /** If file="...", the filename (block already added to files) */ file?: string; /** Pre-merged options from all levels */ [key: string]: unknown; } /** * Function to execute a single command * Returns stdout, stderr, and exit code * Return null to indicate "not handled" (falls back to next handler) */ type ExecFn = (cmd: string) => Promise; /** * Plugin interface for custom command execution */ interface Plugin { /** * Called for each code block * Return ExecFn to handle block, null to skip (file= blocks, unsupported types) */ block(opts: BlockOpts): ExecFn | null; /** Optional lifecycle hooks */ beforeAll?(): Promise; afterAll?(): Promise; beforeEach?(): Promise; afterEach?(): Promise; } /** * Plugin factory function * Takes file-level options, returns plugin instance */ type PluginFactory = (opts: FileOpts) => Plugin | Promise; //#endregion export { PluginFactory as a, Plugin as i, ExecFn as n, ReplResult as o, FileOpts as r, BlockOpts as t };