import type { AgencyNode, AgencyProgram } from "../../types.js";
import type { TsNode } from "../../ir/tsIR.js";
/**
 * Two helpers for the orchestration phase of `TypeScriptBuilder.build()`:
 *
 *   1. {@link partitionProgram} — single pass over the program nodes
 *      that sorts them into the buckets the output assembly cares
 *      about (static-var init, global init, top-level declarations).
 *   2. {@link assembleSections} — concatenates the already-built
 *      pieces (imports, builtins, type aliases, init functions,
 *      generated statements, sourcemap) into the final TsNode in the
 *      correct, fixed order.
 *
 * Both are functions, not classes — they hold no state of their own;
 * the builder still owns all of the shared scratch state. Pulling
 * them out makes `build()` read declaratively as
 * "partition → assemble" rather than ~180 lines of inline glue.
 */
export type PartitionDeps = {
    processNode: (node: AgencyNode) => TsNode;
    processNodeInGlobalInit: (node: AgencyNode) => TsNode;
    buildHandlerArrow: (handlerName: string) => TsNode;
    isTopLevelDeclaration: (node: AgencyNode) => boolean;
    moduleId: string;
    /**
     * Optional per-phase initialization plan from `compileClosure`. When
     * present, local var assignments are emitted in `localOrder` rather
     * than source order, ensuring cross-module dependencies (Example 1
     * from `agent-init-design.md`) resolve before reads. Bare top-level
     * statements stay in source order.
     *
     * When absent (legacy callers that bypass `compileClosure`), partition
     * falls back to source order. The lazy isInitialized guards remain the
     * safety net for that path.
     */
    staticOrder?: string[];
    globalOrder?: string[];
};
export type ProgramPartition = {
    /** Names of `static` variables declared at module level. */
    staticVarNames: Set<string>;
    /** Subset of `staticVarNames` that are `export`-ed. */
    exportedStaticVarNames: Set<string>;
    /** Statements that initialize static variables, run once. */
    staticInitStatements: TsNode[];
    /** Statements that initialize global variables / run top-level code per execution. */
    globalInitStatements: TsNode[];
    /** Top-level declarations (functions, graph nodes, type aliases, classes). */
    topLevelStatements: TsNode[];
    /**
     * Top-level `callback(...)` registration calls. Kept separate from
     * `globalInitStatements` so the codegen can emit them inside a
     * rerunnable `__registerTopLevelCallbacks(__ctx)` helper that fires on
     * every fresh run AND every resume. Globals are checkpointed and
     * restored on resume; the `topLevelCallbacks` array on the runtime
     * context is not — so the callbacks must be re-registered on every
     * resume cycle.
     *
     * Critical ordering: resume paths (`respondToInterrupts`,
     * `rewindFrom`) call `registerTopLevelCallbacks(execCtx)` BEFORE
     * `restoreState(...)`. The `_callbackImpl` stdlib helper routes a
     * registration to `ctx.topLevelCallbacks` only when the state stack is
     * empty (i.e., the call is happening at module-init / top-level
     * position); once `restoreState` has rebuilt a non-empty stack, the
     * same registration call would be misrouted as a scoped callback on
     * the wrong frame. If you change the order of these two calls, every
     * top-level callback registered after the first interrupt cycle will
     * either silently land on a foreign frame or not fire at all.
     */
    topLevelCallbackStatements: TsNode[];
};
/**
 * Walk the program once and route each node into the right bucket:
 *
 *   - `static` assignments (and `with handler { static x = ... }`)
 *     contribute names + frozen init statements.
 *   - `global` assignments (and their `with handler` form) contribute
 *     `__ctx.globals.set(...)` calls.
 *   - Top-level declarations (per `isTopLevelDeclaration`) become
 *     module-scope generated statements.
 *   - Anything else (bare expressions, function calls, …) goes into
 *     `__initializeGlobals` so it can access `__ctx`.
 */
export declare function partitionProgram(program: AgencyProgram, deps: PartitionDeps): ProgramPartition;
export type AssembleSectionsOpts = {
    moduleId: string;
    preprocess: TsNode[];
    importStatements: TsNode[];
    /** Raw string output of `generateImports()`. Already-rendered template. */
    generatedImports: string;
    /** Raw string output of `generateBuiltins()`. Already-rendered template. */
    generatedBuiltins: string;
    toolRegistrations: TsNode[];
    typeAliases: TsNode[];
    staticVarNames: Set<string>;
    exportedStaticVarNames: Set<string>;
    staticInitStatements: TsNode[];
    globalInitStatements: TsNode[];
    topLevelCallbackStatements: TsNode[];
    generatedStatements: TsNode[];
    postprocess: TsNode[];
    /** JSON-stringified source map, embedded into the generated module. */
    sourceMapJson: string;
    /**
     * Per-phase cross-module dependencies sourced from the topsort plan.
     * For each entry, the generated `__initializeStatic` /
     * `__initializeGlobals` body awaits the corresponding function on
     * that source module before running its own assignments. Together with
     * `reorderTagged` (which orders local statements by topsort) this is
     * what makes Example 1 (`fooStatic = barStatic + "!"`) yield "hello!"
     * instead of throwing the read-before-init trap.
     *
     * Empty / absent when the legacy callers bypass `compileClosure`.
     */
    staticAwaitModules?: {
        localImport: string;
        sourceModuleId: string;
    }[];
    globalAwaitModules?: {
        localImport: string;
        sourceModuleId: string;
    }[];
    /**
     * Absolute moduleId used as the registry key for
     * `__registerStaticInit` / `__registerGlobalsInit`. Falls back to
     * `moduleId` when the plan didn't supply one (legacy callers); in
     * that case cross-module awaits won't find this module's init in the
     * registry, but the lazy isInitialized guard still keeps things
     * correct for same-module flows.
     */
    registryModuleId?: string;
    /**
     * Plan-driven local init orders. Used purely for the human-readable
     * banner comments above `__initializeStatic` / `__initializeGlobals`
     * — the actual order is already baked into `staticInitStatements` /
     * `globalInitStatements` by `reorderTagged` during partition.
     */
    staticLocalOrder?: string[];
    globalLocalOrder?: string[];
};
/**
 * Concatenate the per-section outputs into the final generated module,
 * in the canonical order:
 *
 *   preprocess
 *   importStatements
 *   generated imports (template)
 *   generated builtins (template)
 *   tool registrations
 *   type aliases
 *   static-var declarations + __initializeStatic + __getStaticVars (if any)
 *   __initializeGlobals
 *   generated statements
 *   postprocess
 *   __sourceMap export
 */
export declare function assembleSections(opts: AssembleSectionsOpts): TsNode;
