/**
 * `module-functions` adapter — surfaces module-level exported functions
 * as synthetic service classes via the candidate-step pipeline.
 *
 * Why this exists: PowerSync / hand-rolled Drizzle / Supabase-queries
 * style codebases keep their business logic in modules of exported
 * async functions:
 *
 *   // db/queries/smc-rounds.ts
 *   export async function smcCreateRound(db, params) { ... }
 *   export async function smcGetRound(db, id) { ... }
 *   export async function smcUpdateRoundStatus(db, id, status) { ... }
 *
 * The class walker only sees classes — module functions are invisible
 * to it. But GitNexus traces cross-method call flows AND captures
 * function terminals as `Process` nodes (`Function:<filePath>:<fnName>`).
 * That signal is already in `facts.processes` at the point the
 * orchestrator finishes structural extraction.
 *
 * This adapter consumes the process terminals, groups them by file,
 * and synthesizes one service class per file — exactly mirroring the
 * `express-routes` pattern. The synthetic class body feeds into the
 * existing `extractCandidateSteps` classifier, so module-function
 * services get pre-classified timelines just like real class methods.
 *
 * Phase 0 of `2026-05-13-NORMALISE-PHASE.md`.
 *
 * Filed in proposal section §3.
 */
export interface ModuleFunctionTerminal {
    /** Function name (suitable as a yaml key — preserved verbatim from source). */
    methodName: string;
    /** Whether the function is declared async. */
    isAsync: boolean;
    /** Function body between matching braces, no wrapping. */
    body: string;
    /** Source line range of the full declaration (export keyword → closing brace). */
    sourceLineRange: [number, number];
}
/**
 * Parse a `Function:<filePath>:<fnName>` terminalId. Returns null if
 * the ID doesn't match (e.g. it's a class method).
 *
 * Examples:
 *   "Function:db/queries/smc-rounds.ts:smcCreateRound" → { filePath, functionName }
 *   "Method:UserController:create" → null
 */
export declare function parseFunctionTerminalId(id: string): {
    filePath: string;
    functionName: string;
} | null;
/**
 * Walk `facts.processes`-shaped input for function terminals. Returns a
 * map: filePath → Set<functionName>. Skips:
 *   - Non-Function: terminals (class methods, etc.)
 *   - Files outside common source extensions
 *   - Files in node_modules / dist / build output
 */
export declare function groupTerminalsByFile(processes: Array<{
    terminalId: string;
}>): Map<string, Set<string>>;
/**
 * Find an exported top-level function in source. Handles four common
 * declaration shapes:
 *
 *   export async function <name>(...) { ... }
 *   export function <name>(...) { ... }
 *   export const <name> = async (...) => { ... }
 *   export const <name> = (...) => { ... }
 *
 * Returns null if not found or if the declaration's body can't be
 * isolated (single-expression arrow `=> expr` without a brace block).
 */
export declare function findExportedFunctionBody(source: string, fnName: string): ModuleFunctionTerminal | null;
/**
 * Wrap a list of module functions in a synthetic class body. The output
 * is suitable for `walkMethodBodies` / `extractCandidateSteps` to
 * consume. Each function becomes a `<methodName>(...) { <body> }` member.
 *
 * Mirrors `synthesizeControllerClass` in `express-routes.ts`.
 */
export declare function synthesizeServiceClass(serviceName: string, functions: ModuleFunctionTerminal[]): string;
/**
 * Detect signals that a TS/JS module is client-side (React Native,
 * browser SPA, etc.) and therefore should NOT be classified as a Node
 * backend service by the module-functions synthesiser.
 *
 * Motivation (2026-05-15, surfaced by the idle-meta × marrbox cell of
 * the 9-cell comparison matrix): idle_meta is a React Native app.
 * Its `TokenStorageService.ts` uses `AsyncStorage` (RN client storage,
 * not available in Node). The module-functions synthesiser turned it
 * into a backend service with `TARGET RUNTIME: Node.js`, and realize
 * emitted code that would have crashed at runtime. marrbox correctly
 * refused (STUB002, "AsyncStorage not available in Node.js runtime")
 * and the verifier surfaced the spec gap — but the *upstream* fix is
 * to not extract client-side modules as backend services in the first
 * place.
 *
 * Detection is conservative: only flag when STRONG client-only signals
 * are present. Plain React (used dual-side in Next.js etc.) is NOT a
 * signal on its own. Detected signals are returned alongside the bool
 * so callers can surface them in diagnostics.
 */
export declare function detectClientSideModule(sourceText: string): {
    client: boolean;
    signals: string[];
};
/**
 * Derive a service class name from a file path.
 *
 *   "db/queries/smc-rounds.ts" → "SmcRoundsService"
 *   "lib/round-guards.ts"      → "RoundGuardsService"
 *   "providers/AuthProvider.tsx" → "AuthProviderService"
 *
 * The file basename (no extension) is split on `-`, `_`, `.`, `/` and
 * each segment is PascalCased. `Service` suffix is appended unless the
 * derived name already ends in `Service` / `Controller`.
 */
export declare function deriveServiceName(filePath: string): string;
//# sourceMappingURL=module-functions.d.ts.map