/**
 * Per-action LLM emit hook — Phase 3 of the L3 redesign.
 *
 * Builds an `LlmEmitFn` (the dependency-injection seam exposed by
 * `per-action-emitter.ts`) that loads `realize-action.prompt.yaml`,
 * calls `runPrompt` with the assembled per-action context, runs the
 * structural validator over the LLM output, and surgically retries
 * once on parse failure (DR3-aligned).
 *
 * Three quality gates run on every LLM emission:
 *   1. Markdown extraction — pull the ```typescript fenced block out of
 *      the LLM response. Empty / missing block → null (caller falls
 *      through to γ stub).
 *   2. Structural preservation (DR3) — every pre-baked snippet must
 *      appear verbatim in the body. A rewritten snippet is a loud
 *      failure; we throw with a diff so the user knows the LLM
 *      misbehaved.
 *   3. esbuild parse check — the body must be syntactically valid TS.
 *      On parse failure we run ONE surgical retry with the parse error
 *      fed back as a userPrefix; if it fails again we return null and
 *      the caller emits the γ stub.
 *
 * The realize-action.prompt.yaml asset (Phase 2 deliverable) lives in
 * `@specverse/assets/prompts/core/standard/default/realize-action.prompt.yaml`
 * once that package is republished. Until then, we fall back to a
 * filesystem path under specverse-self/assets/ so Phase 3 doesn't have
 * to wait on a registry roundtrip.
 */
import { runPrompt as runPromptFn, type PromptYaml } from '../ai/prompt-runner.js';
import type { LlmEmitFn } from './per-action-emitter.js';
/** Options for {@link createRealizeActionLlmEmit}. */
export interface CreateRealizeActionLlmEmitOptions {
    /** Override `runPrompt` for tests. */
    runPromptOverride?: typeof runPromptFn;
    /** Override `loadPrompt` for tests; default is loadPrompt('realize-action'). */
    loadPromptOverride?: () => PromptYaml;
    /** Override the parse-check for tests. Must return null on success
     *  and an error message string on failure. */
    parseCheckOverride?: (code: string) => Promise<string | null>;
    /** Override the model passed to runPrompt (rare). */
    model?: any;
    /** Per-call timeout. Default 5min — same as microcall-orchestrator. */
    timeoutMs?: number;
    /** Disable the surgical retry (tests). */
    disableSurgicalRetry?: boolean;
    /**
     * Available clients string passed into the prompt's `availableClients`
     * variable. Caller (the realize runner) builds this from the
     * component's `import:` block + the action's `uses:`. When omitted,
     * the prompt receives a "(none)" placeholder.
     */
    availableClients?: string;
    /** Sibling-action signatures string. Same convention. */
    siblingActions?: string;
    /** Cross-method process context string. Same convention. */
    processContext?: string;
}
/**
 * Build an {@link LlmEmitFn} for use in per-action realize emission.
 *
 * The returned function:
 *   1. Builds the prompt input from the per-action emitter's request.
 *   2. Calls runPrompt({ operation: 'realize-action', ... }).
 *   3. Extracts the ```typescript block from the response.
 *   4. Runs the structural validator (DR3); throws on rewrite.
 *   5. Runs an esbuild parse check; surgical-retries once on failure.
 *   6. Returns the body string, or null when all attempts fail (caller
 *      falls through to γ stub).
 */
export declare function createRealizeActionLlmEmit(opts?: CreateRealizeActionLlmEmitOptions): LlmEmitFn;
/**
 * Filesystem fallback for realize-action.prompt.yaml when the installed
 * @specverse/assets package predates Phase 2's prompt addition.
 *
 * Searches a small fixed set of candidate paths relative to the engines
 * package's installed location and the worktree layout used in
 * specverse-self repo. Returns null when none are found; runPrompt then
 * surfaces the canonical "prompt file not found" error.
 */
export declare function loadRealizeActionPromptFromFallback(): PromptYaml | null;
/**
 * Pull the first ```typescript fenced block out of an LLM response.
 * Tolerates plain ``` (no language tag) when the body starts with
 * recognisably-TS content. Returns null if no block is found.
 */
export declare function extractTypescriptBlock(text: string): string | null;
//# sourceMappingURL=per-action-llm-emit.d.ts.map