import { AgencyConfig } from "../config.js";
import type { CompilationUnit, ImportedFunctionSignature } from "../compilationUnit.js";
import { AgencyNode, AgencyProgram, FunctionCall, FunctionDefinition, IfElse, WhileLoop } from "../types.js";
import { MessageThread } from "../types/messageThread.js";
export declare class TypescriptPreprocessor {
    program: AgencyProgram;
    protected config: AgencyConfig;
    protected functionDefinitions: Record<string, FunctionDefinition>;
    protected importedFunctions: Record<string, ImportedFunctionSignature>;
    protected graphNodeDefinitions: Record<string, AgencyNode>;
    constructor(program: AgencyProgram, config?: AgencyConfig, info?: CompilationUnit);
    /**
     * Move standalone `tag` nodes onto the next attach-target node
     * (function / graphNode / assignment / functionCall / typeAlias).
     * Public so consumers like the doc generator can run the same
     * tag-attachment that the full `preprocess()` pipeline runs without
     * also running every downstream transform.
     */
    attachTags(): void;
    attachDocComments(): void;
    /**
     * Look up the BlockType for a function's block parameter by function name.
     * Checks both local function definitions and imported function signatures.
     */
    private findBlockType;
    /**
     * Copy type annotations from a BlockType onto block params that lack them.
     */
    private applyBlockType;
    /**
     * Walk the AST and propagate block type annotations from function definitions
     * onto direct block arguments that lack type annotations.
     * e.g. map([1,2,3]) as x { ... } — copies param types from map's block type onto x.
     *
     * Note: blocks inside named args (e.g. fn.partial(func: \x -> x)) are not yet
     * handled — the preprocessor would need valueAccess chain resolution to find
     * the receiver function. The builder falls back to 'any' for untyped block params.
     */
    propagateBlockTypes(): void;
    preprocess(): AgencyProgram;
    /**
     * Walk every function and graph-node body and desugar `parallel { ... }`
     * blocks into the existing `fork` primitive. Also inlines any `seq { ... }`
     * blocks that appear outside a parallel block (where they have no runtime
     * effect). See lib/preprocessors/parallelDesugar.ts.
     */
    protected desugarParallelBlocks(): void;
    protected isVarUsedInBody(variableName: string, nodeToExclude: AgencyNode, body: AgencyNode[]): boolean;
    protected getFunctionDefinitions(): void;
    protected getGraphNodeDefinitions(): void;
    protected collectSkills(): void;
    protected collectSkillsInFunction(body: AgencyNode[]): void;
    protected findChildren(body: AgencyNode[], type: string): AgencyNode[];
    protected isBuiltinFunction(functionName: string): boolean;
    private prettifyName;
    renderMermaid(): string[];
    protected extractFunctionCalls(body: AgencyNode[]): FunctionCall[];
    protected groupCallsByAsync(calls: FunctionCall[]): {
        type: "sync" | "async";
        calls: FunctionCall[];
    }[];
    protected topologicalSortFunctions(): FunctionDefinition[];
    protected addAwaitPendingCalls(): void;
    protected _addAwaitPendingCalls(body: AgencyNode[]): AgencyNode[];
    /**
     * Recursively collect all async variables defined in this body and nested non-function bodies.
     * Does not descend into function or graphNode bodies as they have their own scope.
     */
    protected _collectAsyncVariablesInScope(body: AgencyNode[], asyncVarToAssignment: Record<string, AgencyNode>): void;
    /**
     * Find the first usage of a variable in this scope (across all bodies).
     * Returns the path to the body and the index within that body.
     */
    protected _findFirstUsageInScope(body: AgencyNode[], varName: string, assignmentNode: AgencyNode, bodyPath?: number[]): {
        bodyPath: number[];
        indexInBody: number;
    } | null;
    /**
     * Check if a node uses a variable directly (not in nested bodies).
     */
    protected _nodeUsesVariableDirectly(node: AgencyNode, varName: string): boolean;
    /**
     * Insert awaitPending calls at the appropriate locations in the body.
     */
    protected _insertAwaitPendingCalls(body: AgencyNode[], locationToVars: Record<string, string[]>, currentPath?: number[]): AgencyNode[];
    protected nodeHasBody(node: AgencyNode): node is FunctionDefinition | AgencyNode | IfElse | WhileLoop | MessageThread;
    protected _nodeUsesVariable(node: AgencyNode, varName: string): boolean;
    /**
     * Filter out nodes based on excludeNodeTypes config
     */
    protected filterExcludedNodeTypes(): void;
    /**
     * Recursively filter nodes by type, handling all node structures
     */
    protected filterNodesByType(nodes: AgencyNode[], excludeSet: Set<string>): AgencyNode[];
    /**
     * Filter out builtin function calls based on excludeBuiltinFunctions config
     */
    protected filterExcludedBuiltinFunctions(): void;
    /**
     * Recursively filter builtin function calls
     */
    protected filterBuiltinFunctionCalls(nodes: AgencyNode[], excludeSet: Set<string>): AgencyNode[];
    /**
     * Validate fetch calls against allowed/disallowed domains
     */
    protected validateFetchDomains(): void;
    /**
     * Validate a single fetch call's domain
     */
    protected _validateFetchCall(node: FunctionCall, effectiveAllowed: Set<string> | null, disallowedSet: Set<string>): void;
    /**
     * Extract domain from URL string
     */
    protected _extractDomain(url: string): string | null;
    /**
     * Validate that no async function calls appear inside loops.
     * Async calls inside loops can't be properly serialized for interrupt
     * resumption because multiple iterations share the same step block,
     * causing branch key collisions.
     */
    protected validateNoAsyncInLoops(): void;
    /**
     * Get the scope name for a function-like node (function or graphNode).
     */
    private getScopeName;
    /**
     * Resolve variable scopes by annotating AST nodes with their scope.
     * After this pass, every VariableNameLiteral, InterpolationSegment, and Assignment
     * will have a `scope` property indicating whether the variable is global, local, or args.
     */
    protected resolveVariableScopes(): void;
}
