/** * `kern migrate [dir]` - in-place migrations of .kern sources. * * `literal-const` * Detects `const name=X ... handler <<< >>>` * and rewrites to `const name=X ... value=...`. Primitive literals use the * compact `value=42` form; strings and expressions use `value={{ ... }}` so * generated TypeScript stays byte-equivalent to the original handler body. * * `fn-expr` * Detects `fn name=X ... handler <<< >>>` and * rewrites to `fn name=X ... expr={{ ... }}`. The compiler emits the expr * body verbatim inside the function, matching the original handler output. * * Dry-run by default; `--write` commits edits. */ import { type GapCategory, isInlineSafeExpression, isInlineSafeLiteral } from '@kernlang/core'; interface LiteralConstHit { headerLine: number; literal: string; valueAttr: string; } interface LiteralConstResult { hits: LiteralConstHit[]; output: string; /** Optional — handlers/decls the rewriter declined to touch, with reasons * the author can act on. Only the native-handlers rewriter populates * this today; the line-based migrations (literal-const, fn-expr, * class-body) leave it undefined. */ skipped?: Array<{ headerLine: number; endLine: number; reason: string; }>; } /** * Line-based migration: matches the exact shape emitted by historical * importers and by hand-written audiofacets files: * * const name=X type=T [more props] <- header, no trailing handler attr * handler <<< * * >>> * * Indentation is tolerated (any whitespace), but the handler MUST be * single-line content sandwiched by `<<<` and `>>>` with no other children. * If the const header already contains `value=`, the handler is left alone. */ declare function rewriteLiteralConsts(source: string): LiteralConstResult; /** * Line-based migration for single-line `fn` handler bodies. Matches: * * [indent]fn name=X [props...] <- header, no handler= attr, no expr= attr * [deeper] handler <<< * [deeper] <- preserved verbatim (incl. `return`, `;`) * [deeper] >>> * * Rewrites to `fn name=X ... expr={{ }}`. The codegen in * generateFunction emits the expr verbatim inside the function body, so the * compiled TypeScript is byte-identical to the handler form. * * Shares the same safety guards as rewriteLiteralConsts: * - handler must be a child of the fn (strictly deeper indent), * - no `}}` in the body (would close the expr block early), * - header must not already carry expr= or handler=, * - header must not contain an inline `#` or `//` comment, * - body must not be empty after trim, * - handler must have exactly ONE body line (no multi-line blocks). */ declare function rewriteFnExpr(source: string): LiteralConstResult; export interface MigrationDef { /** Canonical name — also the CLI subcommand. */ name: string; /** Category this migration services. Today always `migratable`. */ category: GapCategory; /** One-line description shown in help + `list` output. */ summary: string; /** Pure rewriter — takes source, returns new source + per-hit breakdown. */ rewrite: (source: string, opts?: { canonicalizeBraces?: boolean; }) => LiteralConstResult; } export declare const MIGRATIONS: Record; export declare function runMigrate(args: string[]): void; export declare const __test__: { isInlineSafeLiteral: typeof isInlineSafeLiteral; isInlineSafeExpression: typeof isInlineSafeExpression; rewriteLiteralConsts: typeof rewriteLiteralConsts; rewriteFnExpr: typeof rewriteFnExpr; }; export {};