@automigrate/cli 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js","../src/index.ts","../src/commands/config.ts","../src/state.ts","../src/commands/init.ts","../../engine/src/ingestion/index.ts","../../engine/src/llm/index.ts","../../engine/src/planning/index.ts","../../engine/src/execution/index.ts","../../../node_modules/.pnpm/diff@9.0.0/node_modules/diff/libesm/diff/base.js","../../../node_modules/.pnpm/diff@9.0.0/node_modules/diff/libesm/diff/line.js","../../engine/src/verification/index.ts","../../engine/src/orchestrator/index.ts","../src/targets.ts","../src/commands/rollback.ts","../src/workspace.ts","../src/commands/run.ts","../src/buildInfo.ts","../src/patch.ts","../../../node_modules/.pnpm/diff@8.0.4/node_modules/diff/libesm/diff/base.js","../../../node_modules/.pnpm/diff@8.0.4/node_modules/diff/libesm/diff/line.js","../../../node_modules/.pnpm/diff@8.0.4/node_modules/diff/libesm/patch/create.js","../src/commands/status.ts"],"sourcesContent":["// A simple implementation of make-array\nfunction makeArray (subject) {\n return Array.isArray(subject)\n ? subject\n : [subject]\n}\n\nconst UNDEFINED = undefined\nconst EMPTY = ''\nconst SPACE = ' '\nconst ESCAPE = '\\\\'\nconst REGEX_TEST_BLANK_LINE = /^\\s+$/\nconst REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\\\]|^)\\\\$/\nconst REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\\\!/\nconst REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\\\#/\nconst REGEX_SPLITALL_CRLF = /\\r?\\n/g\n\n// Invalid:\n// - /foo,\n// - ./foo,\n// - ../foo,\n// - .\n// - ..\n// Valid:\n// - .foo\nconst REGEX_TEST_INVALID_PATH = /^\\.{0,2}\\/|^\\.{1,2}$/\n\nconst REGEX_TEST_TRAILING_SLASH = /\\/$/\n\nconst SLASH = '/'\n\n// Do not use ternary expression here, since \"istanbul ignore next\" is buggy\nlet TMP_KEY_IGNORE = 'node-ignore'\n/* istanbul ignore else */\nif (typeof Symbol !== 'undefined') {\n TMP_KEY_IGNORE = Symbol.for('node-ignore')\n}\nconst KEY_IGNORE = TMP_KEY_IGNORE\n\nconst define = (object, key, value) => {\n Object.defineProperty(object, key, {value})\n return value\n}\n\nconst REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g\n\nconst RETURN_FALSE = () => false\n\n// Sanitize the range of a regular expression\n// The cases are complicated, see test cases for details\nconst sanitizeRange = range => range.replace(\n REGEX_REGEXP_RANGE,\n (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0)\n ? match\n // Invalid range (out of order) which is ok for gitignore rules but\n // fatal for JavaScript regular expression, so eliminate it.\n : EMPTY\n)\n\n// See fixtures #59\nconst cleanRangeBackSlash = slashes => {\n const {length} = slashes\n return slashes.slice(0, length - length % 2)\n}\n\n// > If the pattern ends with a slash,\n// > it is removed for the purpose of the following description,\n// > but it would only find a match with a directory.\n// > In other words, foo/ will match a directory foo and paths underneath it,\n// > but will not match a regular file or a symbolic link foo\n// > (this is consistent with the way how pathspec works in general in Git).\n// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'\n// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call\n// you could use option `mark: true` with `glob`\n\n// '`foo/`' should not continue with the '`..`'\nconst REPLACERS = [\n\n [\n // Remove BOM\n // TODO:\n // Other similar zero-width characters?\n /^\\uFEFF/,\n () => EMPTY\n ],\n\n // > Trailing spaces are ignored unless they are quoted with backslash (\"\\\")\n [\n // (a\\ ) -> (a )\n // (a ) -> (a)\n // (a ) -> (a)\n // (a \\ ) -> (a )\n /((?:\\\\\\\\)*?)(\\\\?\\s+)$/,\n (_, m1, m2) => m1 + (\n m2.indexOf('\\\\') === 0\n ? SPACE\n : EMPTY\n )\n ],\n\n // Replace (\\ ) with ' '\n // (\\ ) -> ' '\n // (\\\\ ) -> '\\\\ '\n // (\\\\\\ ) -> '\\\\ '\n [\n /(\\\\+?)\\s/g,\n (_, m1) => {\n const {length} = m1\n return m1.slice(0, length - length % 2) + SPACE\n }\n ],\n\n // Escape metacharacters\n // which is written down by users but means special for regular expressions.\n\n // > There are 12 characters with special meanings:\n // > - the backslash \\,\n // > - the caret ^,\n // > - the dollar sign $,\n // > - the period or dot .,\n // > - the vertical bar or pipe symbol |,\n // > - the question mark ?,\n // > - the asterisk or star *,\n // > - the plus sign +,\n // > - the opening parenthesis (,\n // > - the closing parenthesis ),\n // > - and the opening square bracket [,\n // > - the opening curly brace {,\n // > These special characters are often called \"metacharacters\".\n [\n /[\\\\$.|*+(){^]/g,\n match => `\\\\${match}`\n ],\n\n [\n // > a question mark (?) matches a single character\n /(?!\\\\)\\?/g,\n () => '[^/]'\n ],\n\n // leading slash\n [\n\n // > A leading slash matches the beginning of the pathname.\n // > For example, \"/*.c\" matches \"cat-file.c\" but not \"mozilla-sha1/sha1.c\".\n // A leading slash matches the beginning of the pathname\n /^\\//,\n () => '^'\n ],\n\n // replace special metacharacter slash after the leading slash\n [\n /\\//g,\n () => '\\\\/'\n ],\n\n [\n // > A leading \"**\" followed by a slash means match in all directories.\n // > For example, \"**/foo\" matches file or directory \"foo\" anywhere,\n // > the same as pattern \"foo\".\n // > \"**/foo/bar\" matches file or directory \"bar\" anywhere that is directly\n // > under directory \"foo\".\n // Notice that the '*'s have been replaced as '\\\\*'\n /^\\^*\\\\\\*\\\\\\*\\\\\\//,\n\n // '**/foo' <-> 'foo'\n () => '^(?:.*\\\\/)?'\n ],\n\n // starting\n [\n // there will be no leading '/'\n // (which has been replaced by section \"leading slash\")\n // If starts with '**', adding a '^' to the regular expression also works\n /^(?=[^^])/,\n function startingReplacer () {\n // If has a slash `/` at the beginning or middle\n return !/\\/(?!$)/.test(this)\n // > Prior to 2.22.1\n // > If the pattern does not contain a slash /,\n // > Git treats it as a shell glob pattern\n // Actually, if there is only a trailing slash,\n // git also treats it as a shell glob pattern\n\n // After 2.22.1 (compatible but clearer)\n // > If there is a separator at the beginning or middle (or both)\n // > of the pattern, then the pattern is relative to the directory\n // > level of the particular .gitignore file itself.\n // > Otherwise the pattern may also match at any level below\n // > the .gitignore level.\n ? '(?:^|\\\\/)'\n\n // > Otherwise, Git treats the pattern as a shell glob suitable for\n // > consumption by fnmatch(3)\n : '^'\n }\n ],\n\n // two globstars\n [\n // Use lookahead assertions so that we could match more than one `'/**'`\n /\\\\\\/\\\\\\*\\\\\\*(?=\\\\\\/|$)/g,\n\n // Zero, one or several directories\n // should not use '*', or it will be replaced by the next replacer\n\n // Check if it is not the last `'/**'`\n (_, index, str) => index + 6 < str.length\n\n // case: /**/\n // > A slash followed by two consecutive asterisks then a slash matches\n // > zero or more directories.\n // > For example, \"a/**/b\" matches \"a/b\", \"a/x/b\", \"a/x/y/b\" and so on.\n // '/**/'\n ? '(?:\\\\/[^\\\\/]+)*'\n\n // case: /**\n // > A trailing `\"/**\"` matches everything inside.\n\n // #21: everything inside but it should not include the current folder\n : '\\\\/.+'\n ],\n\n // normal intermediate wildcards\n [\n // Never replace escaped '*'\n // ignore rule '\\*' will match the path '*'\n\n // 'abc.*/' -> go\n // 'abc.*' -> skip this rule,\n // coz trailing single wildcard will be handed by [trailing wildcard]\n /(^|[^\\\\]+)(\\\\\\*)+(?=.+)/g,\n\n // '*.js' matches '.js'\n // '*.js' doesn't match 'abc'\n (_, p1, p2) => {\n // 1.\n // > An asterisk \"*\" matches anything except a slash.\n // 2.\n // > Other consecutive asterisks are considered regular asterisks\n // > and will match according to the previous rules.\n const unescaped = p2.replace(/\\\\\\*/g, '[^\\\\/]*')\n return p1 + unescaped\n }\n ],\n\n [\n // unescape, revert step 3 except for back slash\n // For example, if a user escape a '\\\\*',\n // after step 3, the result will be '\\\\\\\\\\\\*'\n /\\\\\\\\\\\\(?=[$.|*+(){^])/g,\n () => ESCAPE\n ],\n\n [\n // '\\\\\\\\' -> '\\\\'\n /\\\\\\\\/g,\n () => ESCAPE\n ],\n\n [\n // > The range notation, e.g. [a-zA-Z],\n // > can be used to match one of the characters in a range.\n\n // `\\` is escaped by step 3\n /(\\\\)?\\[([^\\]/]*?)(\\\\*)($|\\])/g,\n (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE\n // '\\\\[bar]' -> '\\\\\\\\[bar\\\\]'\n ? `\\\\[${range}${cleanRangeBackSlash(endEscape)}${close}`\n : close === ']'\n ? endEscape.length % 2 === 0\n // A normal case, and it is a range notation\n // '[bar]'\n // '[bar\\\\\\\\]'\n ? `[${sanitizeRange(range)}${endEscape}]`\n // Invalid range notaton\n // '[bar\\\\]' -> '[bar\\\\\\\\]'\n : '[]'\n : '[]'\n ],\n\n // ending\n [\n // 'js' will not match 'js.'\n // 'ab' will not match 'abc'\n /(?:[^*])$/,\n\n // WTF!\n // https://git-scm.com/docs/gitignore\n // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)\n // which re-fixes #24, #38\n\n // > If there is a separator at the end of the pattern then the pattern\n // > will only match directories, otherwise the pattern can match both\n // > files and directories.\n\n // 'js*' will not match 'a.js'\n // 'js/' will not match 'a.js'\n // 'js' will match 'a.js' and 'a.js/'\n match => /\\/$/.test(match)\n // foo/ will not match 'foo'\n ? `${match}$`\n // foo matches 'foo' and 'foo/'\n : `${match}(?=$|\\\\/$)`\n ]\n]\n\nconst REGEX_REPLACE_TRAILING_WILDCARD = /(^|\\\\\\/)?\\\\\\*$/\nconst MODE_IGNORE = 'regex'\nconst MODE_CHECK_IGNORE = 'checkRegex'\nconst UNDERSCORE = '_'\n\nconst TRAILING_WILD_CARD_REPLACERS = {\n [MODE_IGNORE] (_, p1) {\n const prefix = p1\n // '\\^':\n // '/*' does not match EMPTY\n // '/*' does not match everything\n\n // '\\\\\\/':\n // 'abc/*' does not match 'abc/'\n ? `${p1}[^/]+`\n\n // 'a*' matches 'a'\n // 'a*' matches 'aa'\n : '[^/]*'\n\n return `${prefix}(?=$|\\\\/$)`\n },\n\n [MODE_CHECK_IGNORE] (_, p1) {\n // When doing `git check-ignore`\n const prefix = p1\n // '\\\\\\/':\n // 'abc/*' DOES match 'abc/' !\n ? `${p1}[^/]*`\n\n // 'a*' matches 'a'\n // 'a*' matches 'aa'\n : '[^/]*'\n\n return `${prefix}(?=$|\\\\/$)`\n }\n}\n\n// @param {pattern}\nconst makeRegexPrefix = pattern => REPLACERS.reduce(\n (prev, [matcher, replacer]) =>\n prev.replace(matcher, replacer.bind(pattern)),\n pattern\n)\n\nconst isString = subject => typeof subject === 'string'\n\n// > A blank line matches no files, so it can serve as a separator for readability.\nconst checkPattern = pattern => pattern\n && isString(pattern)\n && !REGEX_TEST_BLANK_LINE.test(pattern)\n && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern)\n\n // > A line starting with # serves as a comment.\n && pattern.indexOf('#') !== 0\n\nconst splitPattern = pattern => pattern\n.split(REGEX_SPLITALL_CRLF)\n.filter(Boolean)\n\nclass IgnoreRule {\n constructor (\n pattern,\n mark,\n body,\n ignoreCase,\n negative,\n prefix\n ) {\n this.pattern = pattern\n this.mark = mark\n this.negative = negative\n\n define(this, 'body', body)\n define(this, 'ignoreCase', ignoreCase)\n define(this, 'regexPrefix', prefix)\n }\n\n get regex () {\n const key = UNDERSCORE + MODE_IGNORE\n\n if (this[key]) {\n return this[key]\n }\n\n return this._make(MODE_IGNORE, key)\n }\n\n get checkRegex () {\n const key = UNDERSCORE + MODE_CHECK_IGNORE\n\n if (this[key]) {\n return this[key]\n }\n\n return this._make(MODE_CHECK_IGNORE, key)\n }\n\n _make (mode, key) {\n const str = this.regexPrefix.replace(\n REGEX_REPLACE_TRAILING_WILDCARD,\n\n // It does not need to bind pattern\n TRAILING_WILD_CARD_REPLACERS[mode]\n )\n\n const regex = this.ignoreCase\n ? new RegExp(str, 'i')\n : new RegExp(str)\n\n return define(this, key, regex)\n }\n}\n\nconst createRule = ({\n pattern,\n mark\n}, ignoreCase) => {\n let negative = false\n let body = pattern\n\n // > An optional prefix \"!\" which negates the pattern;\n if (body.indexOf('!') === 0) {\n negative = true\n body = body.substr(1)\n }\n\n body = body\n // > Put a backslash (\"\\\") in front of the first \"!\" for patterns that\n // > begin with a literal \"!\", for example, `\"\\!important!.txt\"`.\n .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!')\n // > Put a backslash (\"\\\") in front of the first hash for patterns that\n // > begin with a hash.\n .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#')\n\n const regexPrefix = makeRegexPrefix(body)\n\n return new IgnoreRule(\n pattern,\n mark,\n body,\n ignoreCase,\n negative,\n regexPrefix\n )\n}\n\nclass RuleManager {\n constructor (ignoreCase) {\n this._ignoreCase = ignoreCase\n this._rules = []\n }\n\n _add (pattern) {\n // #32\n if (pattern && pattern[KEY_IGNORE]) {\n this._rules = this._rules.concat(pattern._rules._rules)\n this._added = true\n return\n }\n\n if (isString(pattern)) {\n pattern = {\n pattern\n }\n }\n\n if (checkPattern(pattern.pattern)) {\n const rule = createRule(pattern, this._ignoreCase)\n this._added = true\n this._rules.push(rule)\n }\n }\n\n // @param {Array<string> | string | Ignore} pattern\n add (pattern) {\n this._added = false\n\n makeArray(\n isString(pattern)\n ? splitPattern(pattern)\n : pattern\n ).forEach(this._add, this)\n\n return this._added\n }\n\n // Test one single path without recursively checking parent directories\n //\n // - checkUnignored `boolean` whether should check if the path is unignored,\n // setting `checkUnignored` to `false` could reduce additional\n // path matching.\n // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`\n\n // @returns {TestResult} true if a file is ignored\n test (path, checkUnignored, mode) {\n let ignored = false\n let unignored = false\n let matchedRule\n\n this._rules.forEach(rule => {\n const {negative} = rule\n\n // | ignored : unignored\n // -------- | ---------------------------------------\n // negative | 0:0 | 0:1 | 1:0 | 1:1\n // -------- | ------- | ------- | ------- | --------\n // 0 | TEST | TEST | SKIP | X\n // 1 | TESTIF | SKIP | TEST | X\n\n // - SKIP: always skip\n // - TEST: always test\n // - TESTIF: only test if checkUnignored\n // - X: that never happen\n if (\n unignored === negative && ignored !== unignored\n || negative && !ignored && !unignored && !checkUnignored\n ) {\n return\n }\n\n const matched = rule[mode].test(path)\n\n if (!matched) {\n return\n }\n\n ignored = !negative\n unignored = negative\n\n matchedRule = negative\n ? UNDEFINED\n : rule\n })\n\n const ret = {\n ignored,\n unignored\n }\n\n if (matchedRule) {\n ret.rule = matchedRule\n }\n\n return ret\n }\n}\n\nconst throwError = (message, Ctor) => {\n throw new Ctor(message)\n}\n\nconst checkPath = (path, originalPath, doThrow) => {\n if (!isString(path)) {\n return doThrow(\n `path must be a string, but got \\`${originalPath}\\``,\n TypeError\n )\n }\n\n // We don't know if we should ignore EMPTY, so throw\n if (!path) {\n return doThrow(`path must not be empty`, TypeError)\n }\n\n // Check if it is a relative path\n if (checkPath.isNotRelative(path)) {\n const r = '`path.relative()`d'\n return doThrow(\n `path should be a ${r} string, but got \"${originalPath}\"`,\n RangeError\n )\n }\n\n return true\n}\n\nconst isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path)\n\ncheckPath.isNotRelative = isNotRelative\n\n// On windows, the following function will be replaced\n/* istanbul ignore next */\ncheckPath.convert = p => p\n\n\nclass Ignore {\n constructor ({\n ignorecase = true,\n ignoreCase = ignorecase,\n allowRelativePaths = false\n } = {}) {\n define(this, KEY_IGNORE, true)\n\n this._rules = new RuleManager(ignoreCase)\n this._strictPathCheck = !allowRelativePaths\n this._initCache()\n }\n\n _initCache () {\n // A cache for the result of `.ignores()`\n this._ignoreCache = Object.create(null)\n\n // A cache for the result of `.test()`\n this._testCache = Object.create(null)\n }\n\n add (pattern) {\n if (this._rules.add(pattern)) {\n // Some rules have just added to the ignore,\n // making the behavior changed,\n // so we need to re-initialize the result cache\n this._initCache()\n }\n\n return this\n }\n\n // legacy\n addPattern (pattern) {\n return this.add(pattern)\n }\n\n // @returns {TestResult}\n _test (originalPath, cache, checkUnignored, slices) {\n const path = originalPath\n // Supports nullable path\n && checkPath.convert(originalPath)\n\n checkPath(\n path,\n originalPath,\n this._strictPathCheck\n ? throwError\n : RETURN_FALSE\n )\n\n return this._t(path, cache, checkUnignored, slices)\n }\n\n checkIgnore (path) {\n // If the path doest not end with a slash, `.ignores()` is much equivalent\n // to `git check-ignore`\n if (!REGEX_TEST_TRAILING_SLASH.test(path)) {\n return this.test(path)\n }\n\n const slices = path.split(SLASH).filter(Boolean)\n slices.pop()\n\n if (slices.length) {\n const parent = this._t(\n slices.join(SLASH) + SLASH,\n this._testCache,\n true,\n slices\n )\n\n if (parent.ignored) {\n return parent\n }\n }\n\n return this._rules.test(path, false, MODE_CHECK_IGNORE)\n }\n\n _t (\n // The path to be tested\n path,\n\n // The cache for the result of a certain checking\n cache,\n\n // Whether should check if the path is unignored\n checkUnignored,\n\n // The path slices\n slices\n ) {\n if (path in cache) {\n return cache[path]\n }\n\n if (!slices) {\n // path/to/a.js\n // ['path', 'to', 'a.js']\n slices = path.split(SLASH).filter(Boolean)\n }\n\n slices.pop()\n\n // If the path has no parent directory, just test it\n if (!slices.length) {\n return cache[path] = this._rules.test(path, checkUnignored, MODE_IGNORE)\n }\n\n const parent = this._t(\n slices.join(SLASH) + SLASH,\n cache,\n checkUnignored,\n slices\n )\n\n // If the path contains a parent directory, check the parent first\n return cache[path] = parent.ignored\n // > It is not possible to re-include a file if a parent directory of\n // > that file is excluded.\n ? parent\n : this._rules.test(path, checkUnignored, MODE_IGNORE)\n }\n\n ignores (path) {\n return this._test(path, this._ignoreCache, false).ignored\n }\n\n createFilter () {\n return path => !this.ignores(path)\n }\n\n filter (paths) {\n return makeArray(paths).filter(this.createFilter())\n }\n\n // @returns {TestResult}\n test (path) {\n return this._test(path, this._testCache, true)\n }\n}\n\nconst factory = options => new Ignore(options)\n\nconst isPathValid = path =>\n checkPath(path && checkPath.convert(path), path, RETURN_FALSE)\n\n/* istanbul ignore next */\nconst setupWindows = () => {\n /* eslint no-control-regex: \"off\" */\n const makePosix = str => /^\\\\\\\\\\?\\\\/.test(str)\n || /[\"<>|\\u0000-\\u001F]+/u.test(str)\n ? str\n : str.replace(/\\\\/g, '/')\n\n checkPath.convert = makePosix\n\n // 'C:\\\\foo' <- 'C:\\\\foo' has been converted to 'C:/'\n // 'd:\\\\foo'\n const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\\//i\n checkPath.isNotRelative = path =>\n REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path)\n || isNotRelative(path)\n}\n\n\n// Windows\n// --------------------------------------------------------------\n/* istanbul ignore next */\nif (\n // Detect `process` so that it can run in browsers.\n typeof process !== 'undefined'\n && process.platform === 'win32'\n) {\n setupWindows()\n}\n\n// COMMONJS_EXPORTS ////////////////////////////////////////////////////////////\n\nmodule.exports = factory\n\n// Although it is an anti-pattern,\n// it is still widely misused by a lot of libraries in github\n// Ref: https://github.com/search?q=ignore.default%28%29&type=code\nfactory.default = factory\n\nmodule.exports.isPathValid = isPathValid\n\n// For testing purposes\ndefine(module.exports, Symbol.for('setupWindows'), setupWindows)\n","#!/usr/bin/env node\nimport { readFile } from 'node:fs/promises';\nimport { Command } from 'commander';\nimport { setKeyCommand } from './commands/config.js';\nimport { initCommand } from './commands/init.js';\nimport { rollbackCommand } from './commands/rollback.js';\nimport { runCommand } from './commands/run.js';\nimport { statusCommand } from './commands/status.js';\n\nconst pkg = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')) as {\n version: string;\n};\n\nconst program = new Command();\n\nprogram\n .name('automigrate')\n .description('Autonomous codebase migration agent — plan, transform, verify')\n .version(pkg.version);\n\nprogram\n .command('init')\n .description('Detect the stack in the current directory and suggest migration targets')\n .action(initCommand);\n\nprogram\n .command('run')\n .description('Run a full migration: plan, execute, verify')\n .option('--target <from-to>', 'migration target, e.g. javascript-to-typescript')\n .option('--dry-run', 'plan only, print the plan, do not execute')\n .option('--resume', 'resume the last failed migration from its checkpoint')\n .action(runCommand);\n\nprogram\n .command('rollback')\n .description('Restore original files from the pre-migration backup and remove /migrated')\n .option('--job <id>', 'job id to roll back (defaults to the most recent)')\n .action(rollbackCommand);\n\nprogram.command('status').description('Show the last 5 migration jobs').action(statusCommand);\n\nconst config = program.command('config').description('Manage AutoMigrate configuration');\nconfig\n .command('set-key <apiKey>')\n .description('Save the Anthropic API key to ~/.automigrate/config.json')\n .action(setKeyCommand);\n\nawait program.parseAsync();\n","/**\n * `automigrate config set-key <apiKey>` — store the API key in\n * ~/.automigrate/config.json (chmod 600).\n */\nimport chalk from 'chalk';\nimport { readConfig, stateDir, writeConfig } from '../state.js';\n\nexport async function setKeyCommand(apiKey: string): Promise<void> {\n const config = await readConfig();\n await writeConfig({ ...config, apiKey });\n const masked = apiKey.length > 8 ? `${apiKey.slice(0, 4)}…${apiKey.slice(-4)}` : '****';\n console.log(`${chalk.green('Saved')} API key ${masked} to ${stateDir()}/config.json`);\n}\n","/**\n * Global CLI state in ~/.automigrate/ (overridable via AUTOMIGRATE_HOME):\n * config.json — API key, default ignore patterns\n * jobs.json — past migration job summaries for this machine\n * backup/{job_id}/ — original files backed up before migration\n * checkpoints/{id}.json — engine checkpoints for resumability\n * A per-project .automigrate-lock file prevents concurrent migrations.\n */\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { MigrationStatus } from '@automigrate/engine';\n\nexport interface CliConfig {\n apiKey?: string;\n ignorePaths?: string[];\n}\n\nexport interface JobRecord {\n id: string;\n createdAt: string;\n rootPath: string;\n target: string;\n status: MigrationStatus;\n filesChanged: number;\n linesAdded: number;\n linesRemoved: number;\n tokensUsed: number;\n testPassRate: number | null;\n confidenceScore: number | null;\n error?: string;\n /**\n * Workspace-relative paths the migration creates when applied: planned\n * creations and rename targets (a rename is delete source + create target).\n * Rollback removes them so an applied migration fully reverts. Shared with\n * the extension, which appends accepted creates/renames as they land.\n */\n createdFiles?: string[];\n}\n\nexport function stateDir(): string {\n return process.env.AUTOMIGRATE_HOME ?? path.join(os.homedir(), '.automigrate');\n}\n\nexport function backupDir(jobId: string): string {\n return path.join(stateDir(), 'backup', jobId);\n}\n\nexport function checkpointPath(jobId: string): string {\n return path.join(stateDir(), 'checkpoints', `${jobId}.json`);\n}\n\nexport function newJobId(): string {\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport async function readConfig(): Promise<CliConfig> {\n const parsed = await readJson(path.join(stateDir(), 'config.json'));\n return (parsed ?? {}) as CliConfig;\n}\n\nexport async function writeConfig(config: CliConfig): Promise<void> {\n const filePath = path.join(stateDir(), 'config.json');\n await fs.mkdir(stateDir(), { recursive: true });\n await fs.writeFile(filePath, JSON.stringify(config, null, 2), 'utf8');\n // The config holds the API key — owner read/write only.\n await fs.chmod(filePath, 0o600);\n}\n\nexport async function readJobs(): Promise<JobRecord[]> {\n const parsed = await readJson(path.join(stateDir(), 'jobs.json'));\n return Array.isArray(parsed) ? (parsed as JobRecord[]) : [];\n}\n\n/** Inserts or updates a job record by id. */\nexport async function saveJob(job: JobRecord): Promise<void> {\n const jobs = await readJobs();\n const index = jobs.findIndex((j) => j.id === job.id);\n if (index === -1) jobs.push(job);\n else jobs[index] = job;\n await fs.mkdir(stateDir(), { recursive: true });\n await fs.writeFile(path.join(stateDir(), 'jobs.json'), JSON.stringify(jobs, null, 2), 'utf8');\n}\n\nexport async function acquireLock(rootPath: string): Promise<void> {\n const lockPath = path.join(rootPath, '.automigrate-lock');\n try {\n await fs.writeFile(lockPath, String(process.pid), { flag: 'wx' });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n throw new Error(\n `Another migration appears to be running in this directory (${lockPath} exists). ` +\n 'Remove the lock file if that migration is no longer active.',\n );\n }\n throw error;\n }\n}\n\nexport async function releaseLock(rootPath: string): Promise<void> {\n await fs.rm(path.join(rootPath, '.automigrate-lock'), { force: true });\n}\n\nasync function readJson(filePath: string): Promise<unknown> {\n try {\n return JSON.parse(await fs.readFile(filePath, 'utf8')) as unknown;\n } catch {\n return null;\n }\n}\n","/**\n * `automigrate init` — detect the stack, suggest migration targets, and\n * write automigrate.config.json.\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { readCodebase } from '@automigrate/engine';\nimport { suggestTargets } from '../targets.js';\n\nexport async function initCommand(): Promise<void> {\n const rootPath = process.cwd();\n const spinner = ora('Analyzing codebase…').start();\n const manifest = await readCodebase(rootPath, { ignorePaths: ['migrated'] });\n spinner.succeed(\n `Analyzed ${manifest.files.length} files (${manifest.totalLines.toLocaleString('en-US')} lines)`,\n );\n\n const stack = manifest.detectedStack;\n console.log(`\\n${chalk.bold('Detected stack')}`);\n console.log(` Language: ${chalk.cyan(stack.primaryLanguage)}`);\n console.log(\n ` Frameworks: ${stack.frameworks.length > 0 ? stack.frameworks.join(', ') : chalk.dim('none detected')}`,\n );\n console.log(` Build tool: ${stack.buildTool ?? chalk.dim('none detected')}`);\n console.log(` Test framework: ${stack.testFramework ?? chalk.dim('none detected')}`);\n console.log(` Package manager: ${stack.packageManager ?? chalk.dim('none detected')}`);\n\n const suggestions = suggestTargets(stack);\n console.log(`\\n${chalk.bold('Suggested migration targets')}`);\n if (suggestions.length === 0) {\n console.log(chalk.dim(' No specific suggestions — any <from>-to-<to> target works.'));\n } else {\n for (const target of suggestions) console.log(` ${chalk.green('→')} ${target}`);\n }\n\n const configPath = path.join(rootPath, 'automigrate.config.json');\n try {\n await fs.readFile(configPath, 'utf8');\n console.log(chalk.dim(`\\nautomigrate.config.json already exists — left unchanged.`));\n } catch {\n const config = { target: suggestions[0] ?? '', ignorePaths: [] };\n await fs.writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`, 'utf8');\n console.log(`\\nWrote ${chalk.cyan('automigrate.config.json')}`);\n }\n console.log(\n chalk.dim('Next: automigrate run --dry-run (review the plan), then automigrate run.'),\n );\n}\n","/**\n * Ingestion layer.\n *\n * Reads a codebase from disk, builds a file manifest with token estimates,\n * and detects the stack from ecosystem config files. This is step 1 of the\n * 3-pass migration pipeline — its output (CodebaseManifest) feeds the\n * planning agent (Pass 1).\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport ignore, { type Ignore } from 'ignore';\n\nexport interface FileEntry {\n /** Absolute path on disk. */\n path: string;\n /** Path relative to the codebase root, POSIX separators. */\n relativePath: string;\n /** Lower-cased extension including the dot, e.g. '.ts'. Empty if none. */\n extension: string;\n content: string;\n lines: number;\n /** Estimated token count (chars / 4). */\n tokens: number;\n /** Size in bytes. */\n size: number;\n}\n\nexport interface StackInfo {\n primaryLanguage: string;\n frameworks: string[];\n buildTool: string | null;\n testFramework: string | null;\n packageManager: string | null;\n}\n\nexport interface CodebaseManifest {\n rootPath: string;\n files: FileEntry[];\n totalLines: number;\n totalTokens: number;\n detectedStack: StackInfo;\n /** ISO 8601 timestamp of when the manifest was built. */\n timestamp: string;\n}\n\nexport interface IngestionOptions {\n /** Extra ignore patterns, gitignore syntax. */\n ignorePaths?: string[];\n /** Files larger than this are skipped. Default: 5. */\n maxFileSizeMB?: number;\n /** When set, only files with these extensions are ingested ('.ts' or 'ts'). */\n includeExtensions?: string[];\n}\n\nconst DEFAULT_IGNORE_PATTERNS = [\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'vendor',\n 'coverage',\n // AutoMigrate's own artifacts — a re-run must never re-ingest prior output.\n 'automigrate.config.json',\n '.automigrate-checkpoint.json',\n '.automigrate-checkpoint.json.repair-*',\n '.automigrate-lock',\n '.automigrateignore',\n 'migrated',\n 'output.patch',\n];\nconst IGNORE_FILES = ['.gitignore', '.automigrateignore'];\nconst DEFAULT_MAX_FILE_SIZE_MB = 5;\nconst BINARY_CHECK_BYTES = 8000;\n\n/**\n * Rough token estimate: ~4 characters per token. Good enough for planning\n * and context-window budgeting; exact counts come from the API at run time.\n */\nexport function estimateTokens(content: string): number {\n return Math.ceil(content.length / 4);\n}\n\n/**\n * Reads all source files under dirPath, respecting .gitignore,\n * .automigrateignore, and default ignore patterns.\n */\nexport async function readCodebase(\n dirPath: string,\n options: IngestionOptions = {},\n): Promise<CodebaseManifest> {\n const rootPath = path.resolve(dirPath);\n const ig = ignore();\n ig.add(DEFAULT_IGNORE_PATTERNS);\n for (const name of IGNORE_FILES) {\n const content = await readOptionalFile(path.join(rootPath, name));\n if (content !== null) ig.add(content);\n }\n if (options.ignorePaths !== undefined) ig.add(options.ignorePaths);\n\n const files = await collectFiles(rootPath, ig, options);\n return {\n rootPath,\n files,\n totalLines: files.reduce((sum, f) => sum + f.lines, 0),\n totalTokens: files.reduce((sum, f) => sum + f.tokens, 0),\n detectedStack: detectStack(files),\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Detects the stack from ecosystem config files in the manifest.\n * Checks package.json, pyproject.toml, go.mod, pubspec.yaml, Cargo.toml,\n * and composer.json (in that priority order), falling back to extension\n * frequency when no config file is present.\n */\nexport function detectStack(manifest: FileEntry[]): StackInfo {\n const byPath = new Map(manifest.map((f) => [f.relativePath, f]));\n\n const packageJson = byPath.get('package.json');\n if (packageJson !== undefined) return detectNodeStack(packageJson, byPath);\n\n const pyproject = byPath.get('pyproject.toml');\n if (pyproject !== undefined) return detectPythonStack(pyproject, byPath);\n\n const goMod = byPath.get('go.mod');\n if (goMod !== undefined) return detectGoStack(goMod);\n\n const pubspec = byPath.get('pubspec.yaml');\n if (pubspec !== undefined) return detectDartStack(pubspec);\n\n const cargo = byPath.get('Cargo.toml');\n if (cargo !== undefined) return detectRustStack(cargo);\n\n const composer = byPath.get('composer.json');\n if (composer !== undefined) return detectPhpStack(composer);\n\n return detectFromExtensions(manifest);\n}\n\nasync function readOptionalFile(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n}\n\nasync function collectFiles(\n rootPath: string,\n ig: Ignore,\n options: IngestionOptions,\n): Promise<FileEntry[]> {\n const maxBytes = (options.maxFileSizeMB ?? DEFAULT_MAX_FILE_SIZE_MB) * 1024 * 1024;\n const includeExtensions = options.includeExtensions?.map(normalizeExtension);\n const files: FileEntry[] = [];\n\n async function walk(dir: string): Promise<void> {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const absPath = path.join(dir, entry.name);\n const relPath = path.relative(rootPath, absPath).split(path.sep).join('/');\n\n if (entry.isSymbolicLink()) continue;\n if (entry.isDirectory()) {\n if (ig.ignores(relPath) || ig.ignores(`${relPath}/`)) continue;\n await walk(absPath);\n continue;\n }\n if (!entry.isFile()) continue;\n if (ig.ignores(relPath)) continue;\n\n const extension = path.extname(entry.name).toLowerCase();\n if (includeExtensions !== undefined && !includeExtensions.includes(extension)) continue;\n\n const stat = await fs.stat(absPath);\n if (stat.size > maxBytes) continue;\n\n const buffer = Buffer.from(await fs.readFile(absPath));\n if (isBinary(buffer)) continue;\n\n const content = buffer.toString('utf8');\n files.push({\n path: absPath,\n relativePath: relPath,\n extension,\n content,\n lines: countLines(content),\n tokens: estimateTokens(content),\n size: stat.size,\n });\n }\n }\n\n await walk(rootPath);\n files.sort((a, b) => a.relativePath.localeCompare(b.relativePath));\n return files;\n}\n\nfunction normalizeExtension(ext: string): string {\n const lower = ext.toLowerCase();\n return lower.startsWith('.') ? lower : `.${lower}`;\n}\n\nfunction countLines(content: string): number {\n if (content === '') return 0;\n const segments = content.split('\\n').length;\n return content.endsWith('\\n') ? segments - 1 : segments;\n}\n\nfunction isBinary(buffer: Buffer): boolean {\n return buffer.subarray(0, BINARY_CHECK_BYTES).includes(0);\n}\n\n// --- Per-ecosystem stack detection ---\n\nconst NODE_FRAMEWORK_DEPS: Record<string, string> = {\n next: 'next.js',\n react: 'react',\n vue: 'vue',\n '@angular/core': 'angular',\n svelte: 'svelte',\n express: 'express',\n hono: 'hono',\n fastify: 'fastify',\n '@nestjs/core': 'nestjs',\n};\nconst NODE_BUILD_TOOLS = ['vite', 'webpack', 'rollup', 'esbuild', 'tsup', 'parcel'];\nconst NODE_TEST_FRAMEWORKS = ['vitest', 'jest', 'mocha', 'ava', 'jasmine'];\n\nfunction detectNodeStack(pkgEntry: FileEntry, byPath: Map<string, FileEntry>): StackInfo {\n let pkg: Record<string, unknown> = {};\n try {\n pkg = JSON.parse(pkgEntry.content) as Record<string, unknown>;\n } catch {\n // Malformed package.json — fall through with empty deps.\n }\n const deps: Record<string, unknown> = {\n ...(pkg.dependencies as Record<string, unknown> | undefined),\n ...(pkg.devDependencies as Record<string, unknown> | undefined),\n };\n const has = (name: string): boolean => name in deps;\n\n const frameworks = Object.entries(NODE_FRAMEWORK_DEPS)\n .filter(([dep]) => has(dep))\n .map(([, name]) => name);\n\n let packageManager: string | null = null;\n if (typeof pkg.packageManager === 'string') {\n packageManager = pkg.packageManager.split('@')[0] ?? null;\n } else if (byPath.has('pnpm-lock.yaml')) {\n packageManager = 'pnpm';\n } else if (byPath.has('yarn.lock')) {\n packageManager = 'yarn';\n } else if (byPath.has('bun.lockb') || byPath.has('bun.lock')) {\n packageManager = 'bun';\n } else if (byPath.has('package-lock.json')) {\n packageManager = 'npm';\n }\n\n return {\n primaryLanguage: has('typescript') || byPath.has('tsconfig.json') ? 'typescript' : 'javascript',\n frameworks,\n buildTool: NODE_BUILD_TOOLS.find(has) ?? null,\n testFramework: NODE_TEST_FRAMEWORKS.find(has) ?? null,\n packageManager,\n };\n}\n\nfunction detectPythonStack(pyproject: FileEntry, byPath: Map<string, FileEntry>): StackInfo {\n const content = pyproject.content;\n let packageManager = 'pip';\n if (content.includes('[tool.poetry]')) packageManager = 'poetry';\n else if (byPath.has('uv.lock') || content.includes('[tool.uv]')) packageManager = 'uv';\n\n return {\n primaryLanguage: 'python',\n frameworks: ['django', 'flask', 'fastapi'].filter((f) => content.includes(f)),\n buildTool: null,\n testFramework: content.includes('pytest') ? 'pytest' : null,\n packageManager,\n };\n}\n\nconst GO_FRAMEWORK_MODULES: Record<string, string> = {\n 'github.com/gin-gonic/gin': 'gin',\n 'github.com/labstack/echo': 'echo',\n 'github.com/gofiber/fiber': 'fiber',\n};\n\nfunction detectGoStack(goMod: FileEntry): StackInfo {\n const frameworks = Object.entries(GO_FRAMEWORK_MODULES)\n .filter(([module]) => goMod.content.includes(module))\n .map(([, name]) => name);\n return {\n primaryLanguage: 'go',\n frameworks,\n buildTool: 'go',\n testFramework: 'go test',\n packageManager: 'go modules',\n };\n}\n\nfunction detectDartStack(pubspec: FileEntry): StackInfo {\n const isFlutter = /\\bflutter\\s*:/.test(pubspec.content);\n return {\n primaryLanguage: 'dart',\n frameworks: isFlutter ? ['flutter'] : [],\n buildTool: null,\n testFramework: isFlutter ? 'flutter test' : 'dart test',\n packageManager: 'pub',\n };\n}\n\nconst RUST_FRAMEWORK_CRATES = ['axum', 'actix-web', 'rocket'];\n\nfunction detectRustStack(cargo: FileEntry): StackInfo {\n return {\n primaryLanguage: 'rust',\n frameworks: RUST_FRAMEWORK_CRATES.filter((c) => cargo.content.includes(c)),\n buildTool: 'cargo',\n testFramework: 'cargo test',\n packageManager: 'cargo',\n };\n}\n\nfunction detectPhpStack(composer: FileEntry): StackInfo {\n let parsed: Record<string, unknown> = {};\n try {\n parsed = JSON.parse(composer.content) as Record<string, unknown>;\n } catch {\n // Malformed composer.json — fall through with empty deps.\n }\n const deps = {\n ...(parsed.require as Record<string, unknown> | undefined),\n ...(parsed['require-dev'] as Record<string, unknown> | undefined),\n };\n const depNames = Object.keys(deps);\n\n const frameworks: string[] = [];\n if (depNames.includes('laravel/framework')) frameworks.push('laravel');\n if (depNames.some((d) => d.startsWith('symfony/'))) frameworks.push('symfony');\n\n return {\n primaryLanguage: 'php',\n frameworks,\n buildTool: null,\n testFramework: depNames.includes('phpunit/phpunit') ? 'phpunit' : null,\n packageManager: 'composer',\n };\n}\n\nconst EXTENSION_LANGUAGES: Record<string, string> = {\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n '.py': 'python',\n '.go': 'go',\n '.rs': 'rust',\n '.dart': 'dart',\n '.php': 'php',\n '.rb': 'ruby',\n '.java': 'java',\n '.cs': 'csharp',\n};\n\nfunction detectFromExtensions(manifest: FileEntry[]): StackInfo {\n const counts = new Map<string, number>();\n for (const file of manifest) {\n const language = EXTENSION_LANGUAGES[file.extension];\n if (language !== undefined) counts.set(language, (counts.get(language) ?? 0) + 1);\n }\n let primaryLanguage = 'unknown';\n let best = 0;\n for (const [language, count] of counts) {\n if (count > best) {\n primaryLanguage = language;\n best = count;\n }\n }\n return {\n primaryLanguage,\n frameworks: [],\n buildTool: null,\n testFramework: null,\n packageManager: null,\n };\n}\n","/**\n * LLM adapter layer.\n *\n * The engine never calls a model SDK directly — every pass goes through the\n * LLMAdapter interface so models are swappable per pass and per plan tier\n * (Fable 5 for complex execution, Sonnet for planning/verification, Ollama\n * for self-hosted; see the cost-model strategy doc). Adding a provider means\n * implementing one interface, not refactoring the engine.\n */\nimport Anthropic from '@anthropic-ai/sdk';\n\n/** Fable 5 — used for complex transformation work (Pass 2). */\nexport const FABLE_MODEL = 'claude-opus-4-8';\n/** Opus 4.8 — used for planning/verification passes. */\nexport const OPUS_MODEL = 'claude-opus-4-8';\n/** Sonnet — planned cost-saving option for planning/verification passes. */\nexport const SONNET_MODEL = 'claude-sonnet-4-6';\n\nexport interface LLMRequest {\n systemPrompt: string;\n userPrompt: string;\n maxTokens: number;\n /** Called with each streamed text chunk as it arrives. */\n onText?: (chunk: string) => void;\n}\n\nexport interface LLMResponse {\n text: string;\n inputTokens: number;\n outputTokens: number;\n /** The model that actually served the request. */\n model: string;\n}\n\nexport interface LLMAdapter {\n readonly model: string;\n complete(request: LLMRequest): Promise<LLMResponse>;\n}\n\nexport interface AnthropicAdapterOptions {\n apiKey: string;\n /** Defaults to OPUS_MODEL. */\n model?: string;\n}\n\nexport class AnthropicAdapter implements LLMAdapter {\n readonly model: string;\n private readonly client: Anthropic;\n\n constructor(options: AnthropicAdapterOptions) {\n this.model = options.model ?? OPUS_MODEL;\n this.client = new Anthropic({ apiKey: options.apiKey });\n }\n\n async complete(request: LLMRequest): Promise<LLMResponse> {\n const stream = this.client.messages.stream({\n model: this.model,\n max_tokens: request.maxTokens,\n system: request.systemPrompt,\n messages: [{ role: 'user', content: request.userPrompt }],\n });\n if (request.onText !== undefined) stream.on('text', request.onText);\n\n const message = await stream.finalMessage();\n const text = message.content.map((block) => (block.type === 'text' ? block.text : '')).join('');\n return {\n text,\n inputTokens: message.usage.input_tokens,\n outputTokens: message.usage.output_tokens,\n model: message.model,\n };\n }\n}\n\nexport function createFableAdapter(apiKey: string): LLMAdapter {\n return new AnthropicAdapter({ apiKey, model: FABLE_MODEL });\n}\n\nexport function createOpusAdapter(apiKey: string): LLMAdapter {\n return new AnthropicAdapter({ apiKey, model: OPUS_MODEL });\n}\n\nexport function createSonnetAdapter(apiKey: string): LLMAdapter {\n return new AnthropicAdapter({ apiKey, model: SONNET_MODEL });\n}\n","/**\n * Planning agent — Pass 1 of the 3-pass migration pipeline.\n *\n * Sends the full codebase to the model and gets back a structured\n * MigrationPlan. Codebases over the context limit are split into sliding-\n * window batches with token overlap so cross-file dependencies near batch\n * boundaries stay visible; the per-batch plans are merged afterwards.\n */\nimport type { CodebaseManifest, FileEntry } from '../ingestion/index.js';\nimport { AnthropicAdapter, type LLMAdapter } from '../llm/index.js';\nimport type { MigrationTarget } from '../types.js';\n\nexport const PLANNING_MAX_OUTPUT_TOKENS = 8000;\nexport const PLANNING_CONTEXT_LIMIT_TOKENS = 800_000;\nexport const PLANNING_BATCH_OVERLAP_TOKENS = 50_000;\n\nexport type ChangeComplexity = 'low' | 'medium' | 'high';\n\nexport interface FilePlanEntry {\n /** Source path — the stable identity of the file throughout the pipeline. */\n path: string;\n /**\n * Where the transformed file is written, relative to the output dir.\n * Differs from `path` only for renames (e.g. low.js → low.ts). Optional\n * for backward compatibility with version:1 checkpoints; consumers must\n * treat a missing value as `path`.\n */\n outputPath?: string;\n complexity: ChangeComplexity;\n description: string;\n}\n\n/** The path a transformed file is written to: outputPath, falling back to path. */\nexport function planOutputPath(entry: FilePlanEntry): string {\n return entry.outputPath ?? entry.path;\n}\n\nexport interface DependencyChange {\n name: string;\n action: 'add' | 'remove' | 'update';\n currentVersion: string | null;\n targetVersion: string | null;\n}\n\nexport interface BreakingChange {\n description: string;\n severity: ChangeComplexity;\n affectedFiles: string[];\n}\n\nexport interface MigrationPlan {\n summary: string;\n migrationTarget: MigrationTarget;\n estimatedEffort: 'hours' | 'days' | 'weeks';\n riskLevel: 'low' | 'medium' | 'high';\n filesToModify: FilePlanEntry[];\n filesToCreate: FilePlanEntry[];\n filesToDelete: string[];\n dependencyChanges: DependencyChange[];\n breakingChanges: BreakingChange[];\n tokenBudgetEstimate: number;\n}\n\nexport interface PlanningProgress {\n /** 0-based index of the batch currently streaming. */\n batchIndex: number;\n batchCount: number;\n /** Characters of plan output streamed so far for this batch. */\n charsStreamed: number;\n}\n\nexport interface PlanMigrationOptions {\n /** Override the model adapter (used for tests and model routing). */\n adapter?: LLMAdapter;\n onProgress?: (progress: PlanningProgress) => void;\n /** Token budget per batch. Default: PLANNING_CONTEXT_LIMIT_TOKENS. */\n contextLimitTokens?: number;\n /** Sliding-window overlap between batches. Default: PLANNING_BATCH_OVERLAP_TOKENS. */\n overlapTokens?: number;\n}\n\n/** Thrown when the model response cannot be parsed into a MigrationPlan. */\nexport class PlanningError extends Error {\n readonly rawResponse: string;\n\n constructor(message: string, rawResponse: string) {\n super(message);\n this.name = 'PlanningError';\n this.rawResponse = rawResponse;\n }\n}\n\nexport async function planMigration(\n manifest: CodebaseManifest,\n migrationTarget: MigrationTarget,\n apiKey: string,\n options: PlanMigrationOptions = {},\n): Promise<MigrationPlan> {\n const adapter = options.adapter ?? new AnthropicAdapter({ apiKey });\n const limit = options.contextLimitTokens ?? PLANNING_CONTEXT_LIMIT_TOKENS;\n const overlap = options.overlapTokens ?? PLANNING_BATCH_OVERLAP_TOKENS;\n\n const batches = buildBatches(manifest.files, limit, overlap);\n const systemPrompt = buildSystemPrompt(migrationTarget);\n const plans: MigrationPlan[] = [];\n\n for (let batchIndex = 0; batchIndex < batches.length; batchIndex++) {\n const batch = batches[batchIndex]!;\n let charsStreamed = 0;\n options.onProgress?.({ batchIndex, batchCount: batches.length, charsStreamed });\n\n const response = await adapter.complete({\n systemPrompt,\n userPrompt: buildUserPrompt(manifest, migrationTarget, batch, batchIndex, batches.length),\n maxTokens: PLANNING_MAX_OUTPUT_TOKENS,\n onText: (chunk) => {\n charsStreamed += chunk.length;\n options.onProgress?.({ batchIndex, batchCount: batches.length, charsStreamed });\n },\n });\n plans.push(parsePlanResponse(response.text, migrationTarget));\n }\n\n return mergePlans(plans, migrationTarget);\n}\n\n/**\n * Splits files into batches of at most limitTokens, where each batch after\n * the first is seeded with the trailing files of the previous batch (at\n * least overlapTokens worth) to preserve cross-file dependency awareness.\n * A single file larger than the limit gets a batch of its own — files are\n * never split.\n */\nexport function buildBatches(\n files: FileEntry[],\n limitTokens: number,\n overlapTokens: number,\n): FileEntry[][] {\n const totalTokens = files.reduce((sum, f) => sum + f.tokens, 0);\n if (totalTokens <= limitTokens || files.length === 0) return [files];\n\n const batches: FileEntry[][] = [];\n let current: FileEntry[] = [];\n let currentTokens = 0;\n let newInCurrent = 0;\n\n for (const file of files) {\n if (newInCurrent > 0 && currentTokens + file.tokens > limitTokens) {\n batches.push(current);\n const seed: FileEntry[] = [];\n let seedTokens = 0;\n for (let i = current.length - 1; i >= 0 && seedTokens < overlapTokens; i--) {\n const overlapFile = current[i]!;\n seed.unshift(overlapFile);\n seedTokens += overlapFile.tokens;\n }\n current = seed;\n currentTokens = seedTokens;\n newInCurrent = 0;\n }\n current.push(file);\n currentTokens += file.tokens;\n newInCurrent++;\n }\n batches.push(current);\n return batches;\n}\n\nfunction buildSystemPrompt(target: MigrationTarget): string {\n return [\n `You are a senior software engineer producing a migration plan for a ${target.type} migration from \"${target.from}\" to \"${target.to}\".`,\n 'You will receive the full contents of a codebase. Read every file and trace cross-file dependencies before planning.',\n '',\n 'Respond with a single raw JSON object and nothing else — no markdown fences, no preamble, no commentary.',\n 'The JSON object must have exactly these fields:',\n '- \"summary\": string — one-paragraph description of the migration approach',\n `- \"migrationTarget\": { \"from\": \"${target.from}\", \"to\": \"${target.to}\", \"type\": \"${target.type}\" }`,\n '- \"estimatedEffort\": \"hours\" | \"days\" | \"weeks\"',\n '- \"riskLevel\": \"low\" | \"medium\" | \"high\"',\n '- \"filesToModify\": array of { \"path\": string, \"outputPath\": string, \"complexity\": \"low\" | \"medium\" | \"high\", \"description\": string }',\n '- \"filesToCreate\": array of { \"path\": string, \"complexity\": \"low\" | \"medium\" | \"high\", \"description\": string } — new config files, type definition files, etc.',\n '- \"filesToDelete\": array of string paths — obsolete configs, deprecated files',\n '',\n 'Path rules for filesToModify:',\n '- \"path\" is always the existing source file. \"outputPath\" is where the transformed file lands.',\n '- A rename (e.g. converting src/app.js to src/app.ts) is ONE filesToModify entry with \"path\" set to the source and \"outputPath\" set to the new name. Do NOT also list the source in filesToDelete and do NOT list the new name in filesToCreate.',\n '- For in-place modifications, set \"outputPath\" equal to \"path\" (or omit it).',\n '- filesToDelete is only for files genuinely removed with no replacement.',\n '- \"dependencyChanges\": array of { \"name\": string, \"action\": \"add\" | \"remove\" | \"update\", \"currentVersion\": string | null, \"targetVersion\": string | null }',\n '- \"breakingChanges\": array of { \"description\": string, \"severity\": \"low\" | \"medium\" | \"high\", \"affectedFiles\": string[] }',\n '- \"tokenBudgetEstimate\": number — estimated output tokens the execution phase will need',\n '',\n 'Order filesToModify so that files others depend on come first. Flag every breaking change you can identify, including test coverage gaps.',\n ].join('\\n');\n}\n\nfunction buildUserPrompt(\n manifest: CodebaseManifest,\n target: MigrationTarget,\n batch: FileEntry[],\n batchIndex: number,\n batchCount: number,\n): string {\n const header = [\n `Migration target: ${target.from} -> ${target.to} (${target.type})`,\n `Detected stack: ${JSON.stringify(manifest.detectedStack)}`,\n `Codebase: ${manifest.files.length} files, ${manifest.totalLines} lines, ~${manifest.totalTokens} tokens.`,\n ];\n if (batchCount > 1) {\n header.push(\n `NOTE: the codebase exceeds the context budget, so it is split into ${batchCount} overlapping batches. ` +\n `This is batch ${batchIndex + 1} of ${batchCount} (${batch.length} files). ` +\n 'Plan only for the files in this batch; overlapping files from the previous batch are included for cross-file context.',\n );\n }\n const files = batch.map((f) => `<file path=\"${f.relativePath}\">\\n${f.content}\\n</file>`);\n return [...header, '', ...files].join('\\n');\n}\n\nfunction parsePlanResponse(text: string, migrationTarget: MigrationTarget): MigrationPlan {\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start === -1 || end <= start) {\n throw new PlanningError('No JSON object found in planning response', text);\n }\n let raw: unknown;\n try {\n raw = JSON.parse(text.slice(start, end + 1));\n } catch (error) {\n throw new PlanningError(\n `Planning response is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n text,\n );\n }\n return normalizePlan(raw, migrationTarget, text);\n}\n\nfunction normalizePlan(\n raw: unknown,\n migrationTarget: MigrationTarget,\n rawText: string,\n): MigrationPlan {\n if (typeof raw !== 'object' || raw === null) {\n throw new PlanningError('Planning response JSON is not an object', rawText);\n }\n const obj = raw as Record<string, unknown>;\n\n const estimatedEffort = obj.estimatedEffort;\n if (estimatedEffort !== 'hours' && estimatedEffort !== 'days' && estimatedEffort !== 'weeks') {\n throw new PlanningError(`Invalid estimatedEffort: ${JSON.stringify(estimatedEffort)}`, rawText);\n }\n const riskLevel = obj.riskLevel;\n if (riskLevel !== 'low' && riskLevel !== 'medium' && riskLevel !== 'high') {\n throw new PlanningError(`Invalid riskLevel: ${JSON.stringify(riskLevel)}`, rawText);\n }\n\n return sanitizePlan({\n summary: typeof obj.summary === 'string' ? obj.summary : '',\n migrationTarget,\n estimatedEffort,\n riskLevel,\n filesToModify: normalizeFilePlanEntries(obj.filesToModify),\n filesToCreate: normalizeFilePlanEntries(obj.filesToCreate),\n filesToDelete: asStringArray(obj.filesToDelete),\n dependencyChanges: normalizeDependencyChanges(obj.dependencyChanges),\n breakingChanges: normalizeBreakingChanges(obj.breakingChanges),\n tokenBudgetEstimate:\n typeof obj.tokenBudgetEstimate === 'number' && Number.isFinite(obj.tokenBudgetEstimate)\n ? obj.tokenBudgetEstimate\n : 0,\n });\n}\n\n/**\n * Removes double-emits the model can produce despite the prompt rules: a\n * rename's source listed in filesToDelete, or its target listed in\n * filesToCreate. Without this the same logical file is counted twice and\n * delete counts drift between runs.\n */\nfunction sanitizePlan(plan: MigrationPlan): MigrationPlan {\n const modifySources = new Set(plan.filesToModify.map((e) => e.path));\n const modifyOutputs = new Set(plan.filesToModify.map(planOutputPath));\n return {\n ...plan,\n filesToCreate: plan.filesToCreate.filter(\n (e) => !modifyOutputs.has(e.path) && !modifySources.has(e.path),\n ),\n filesToDelete: plan.filesToDelete.filter((p) => !modifySources.has(p) && !modifyOutputs.has(p)),\n };\n}\n\nfunction isComplexity(value: unknown): value is ChangeComplexity {\n return value === 'low' || value === 'medium' || value === 'high';\n}\n\nfunction asStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === 'string');\n}\n\nfunction normalizeFilePlanEntries(value: unknown): FilePlanEntry[] {\n if (!Array.isArray(value)) return [];\n const entries: FilePlanEntry[] = [];\n for (const item of value) {\n if (typeof item !== 'object' || item === null) continue;\n const record = item as Record<string, unknown>;\n if (typeof record.path !== 'string' || record.path === '') continue;\n entries.push({\n path: record.path,\n outputPath:\n typeof record.outputPath === 'string' && record.outputPath !== ''\n ? record.outputPath\n : record.path,\n complexity: isComplexity(record.complexity) ? record.complexity : 'medium',\n description: typeof record.description === 'string' ? record.description : '',\n });\n }\n return entries;\n}\n\nfunction normalizeDependencyChanges(value: unknown): DependencyChange[] {\n if (!Array.isArray(value)) return [];\n const changes: DependencyChange[] = [];\n for (const item of value) {\n if (typeof item !== 'object' || item === null) continue;\n const record = item as Record<string, unknown>;\n if (typeof record.name !== 'string' || record.name === '') continue;\n const action = record.action;\n if (action !== 'add' && action !== 'remove' && action !== 'update') continue;\n changes.push({\n name: record.name,\n action,\n currentVersion: typeof record.currentVersion === 'string' ? record.currentVersion : null,\n targetVersion: typeof record.targetVersion === 'string' ? record.targetVersion : null,\n });\n }\n return changes;\n}\n\nfunction normalizeBreakingChanges(value: unknown): BreakingChange[] {\n if (!Array.isArray(value)) return [];\n const changes: BreakingChange[] = [];\n for (const item of value) {\n if (typeof item !== 'object' || item === null) continue;\n const record = item as Record<string, unknown>;\n if (typeof record.description !== 'string' || record.description === '') continue;\n changes.push({\n description: record.description,\n severity: isComplexity(record.severity) ? record.severity : 'medium',\n affectedFiles: asStringArray(record.affectedFiles),\n });\n }\n return changes;\n}\n\nconst COMPLEXITY_RANK: Record<ChangeComplexity, number> = { low: 0, medium: 1, high: 2 };\nconst EFFORT_RANK: Record<MigrationPlan['estimatedEffort'], number> = {\n hours: 0,\n days: 1,\n weeks: 2,\n};\n\nfunction mergePlans(plans: MigrationPlan[], migrationTarget: MigrationTarget): MigrationPlan {\n const first = plans[0];\n if (first === undefined) {\n throw new PlanningError('No plans produced', '');\n }\n if (plans.length === 1) return first;\n\n const modify = new Map<string, FilePlanEntry>();\n const create = new Map<string, FilePlanEntry>();\n const dependencyChanges = new Map<string, DependencyChange>();\n const breakingChanges = new Map<string, BreakingChange>();\n const filesToDelete = new Set<string>();\n let estimatedEffort: MigrationPlan['estimatedEffort'] = 'hours';\n let riskLevel: MigrationPlan['riskLevel'] = 'low';\n let tokenBudgetEstimate = 0;\n\n for (const plan of plans) {\n for (const entry of plan.filesToModify) {\n const existing = modify.get(entry.path);\n if (\n existing === undefined ||\n COMPLEXITY_RANK[entry.complexity] > COMPLEXITY_RANK[existing.complexity]\n ) {\n modify.set(entry.path, entry);\n }\n }\n for (const entry of plan.filesToCreate) {\n if (!create.has(entry.path)) create.set(entry.path, entry);\n }\n for (const file of plan.filesToDelete) filesToDelete.add(file);\n for (const change of plan.dependencyChanges) {\n dependencyChanges.set(`${change.name}:${change.action}`, change);\n }\n for (const change of plan.breakingChanges) {\n breakingChanges.set(change.description, change);\n }\n if (EFFORT_RANK[plan.estimatedEffort] > EFFORT_RANK[estimatedEffort]) {\n estimatedEffort = plan.estimatedEffort;\n }\n if (COMPLEXITY_RANK[plan.riskLevel] > COMPLEXITY_RANK[riskLevel]) {\n riskLevel = plan.riskLevel;\n }\n tokenBudgetEstimate += plan.tokenBudgetEstimate;\n }\n\n // Re-sanitize: a rename's modify entry and its stray delete/create\n // double-emit can arrive in different batches, so the per-batch pass\n // cannot catch them.\n return sanitizePlan({\n summary: plans.map((p, i) => `[Batch ${i + 1}/${plans.length}] ${p.summary}`).join('\\n'),\n migrationTarget,\n estimatedEffort,\n riskLevel,\n filesToModify: [...modify.values()],\n filesToCreate: [...create.values()],\n filesToDelete: [...filesToDelete],\n dependencyChanges: [...dependencyChanges.values()],\n breakingChanges: [...breakingChanges.values()],\n tokenBudgetEstimate,\n });\n}\n","/**\n * Execution agent — Pass 2 of the 3-pass migration pipeline.\n *\n * Takes the MigrationPlan from Pass 1 and transforms files batch by batch:\n * high-complexity files solo, medium in groups of 5, low in groups of 10.\n * Transformed files are written to a separate output directory (originals\n * are never touched) and checkpoint state is saved after every batch so a\n * failed run can resume from where it stopped.\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { diffLines } from 'diff';\nimport type { CodebaseManifest, FileEntry } from '../ingestion/index.js';\nimport { AnthropicAdapter, type LLMAdapter, type LLMResponse } from '../llm/index.js';\nimport { planOutputPath, type FilePlanEntry, type MigrationPlan } from '../planning/index.js';\n\nexport const EXECUTION_MAX_OUTPUT_TOKENS = 64_000;\nexport const MEDIUM_BATCH_SIZE = 5;\nexport const LOW_BATCH_SIZE = 10;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_RETRY_BASE_DELAY_MS = 1000;\n\nexport type ExecutionStage = 'preparing' | 'transforming' | 'writing' | 'complete' | 'failed';\n\nexport interface MigrationProgress {\n stage: ExecutionStage;\n currentFile: string | null;\n filesComplete: number;\n filesTotal: number;\n tokensUsed: number;\n}\n\nexport type ProgressCallback = (progress: MigrationProgress) => void;\n\nexport interface ExecutionResult {\n filesModified: number;\n filesCreated: number;\n filesDeleted: number;\n linesAdded: number;\n linesRemoved: number;\n tokensUsed: number;\n /** Files the model failed to return (input for the self-repair loop in Pass 3). */\n failedFiles: string[];\n checkpointPath: string;\n outputDir: string;\n}\n\nexport interface ExecutionBatchEntry {\n plan: FilePlanEntry;\n action: 'modify' | 'create';\n}\n\nexport interface ExecutionBatch {\n entries: ExecutionBatchEntry[];\n}\n\n/** Checkpoint state persisted to disk after every batch. */\nexport interface ExecutionCheckpoint {\n version: 1;\n rootPath: string;\n outputDir: string;\n plan: MigrationPlan;\n batchStatus: ('pending' | 'complete')[];\n completedFiles: string[];\n failedFiles: string[];\n filesModified: number;\n filesCreated: number;\n linesAdded: number;\n linesRemoved: number;\n tokensUsed: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ExecutionOptions {\n /** Override the model adapter (used for tests and model routing). */\n adapter?: LLMAdapter;\n /** Where transformed files are written. Default: <rootPath>/migrated. */\n outputDir?: string;\n /** Default: <rootPath>/.automigrate-checkpoint.json. */\n checkpointPath?: string;\n /** Retries per batch on adapter failure, with exponential backoff. Default: 3. */\n maxRetries?: number;\n /** Base backoff delay in ms. Default: 1000. */\n retryBaseDelayMs?: number;\n /** Default: EXECUTION_MAX_OUTPUT_TOKENS. */\n maxOutputTokens?: number;\n}\n\n/** Thrown when a batch fails after all retries. The checkpoint survives for resume. */\nexport class ExecutionError extends Error {\n readonly checkpointPath: string;\n\n constructor(message: string, checkpointPath: string) {\n super(message);\n this.name = 'ExecutionError';\n this.checkpointPath = checkpointPath;\n }\n}\n\nexport async function executeMigration(\n manifest: CodebaseManifest,\n plan: MigrationPlan,\n apiKey: string,\n onProgress: ProgressCallback,\n options: ExecutionOptions = {},\n): Promise<ExecutionResult> {\n const outputDir = options.outputDir ?? path.join(manifest.rootPath, 'migrated');\n const checkpointPath =\n options.checkpointPath ?? path.join(manifest.rootPath, '.automigrate-checkpoint.json');\n const now = new Date().toISOString();\n const checkpoint: ExecutionCheckpoint = {\n version: 1,\n rootPath: manifest.rootPath,\n outputDir,\n plan,\n batchStatus: buildExecutionBatches(plan).map(() => 'pending'),\n completedFiles: [],\n failedFiles: [],\n filesModified: 0,\n filesCreated: 0,\n linesAdded: 0,\n linesRemoved: 0,\n tokensUsed: 0,\n createdAt: now,\n updatedAt: now,\n };\n return runExecution(manifest, checkpoint, checkpointPath, apiKey, onProgress, options);\n}\n\n/**\n * Resumes a partially completed migration from its checkpoint. Batches\n * already marked complete are skipped; stats accumulate across runs.\n * outputDir is taken from the checkpoint, not from options.\n */\nexport async function resumeMigration(\n checkpointPath: string,\n manifest: CodebaseManifest,\n apiKey: string,\n onProgress: ProgressCallback,\n options: ExecutionOptions = {},\n): Promise<ExecutionResult> {\n const checkpoint = JSON.parse(await fs.readFile(checkpointPath, 'utf8')) as ExecutionCheckpoint;\n return runExecution(manifest, checkpoint, checkpointPath, apiKey, onProgress, options);\n}\n\n/**\n * Groups plan entries into execution batches: high-complexity files first\n * (solo), then medium in groups of MEDIUM_BATCH_SIZE, then low in groups of\n * LOW_BATCH_SIZE. Files to create are batched alongside files to modify.\n */\nexport function buildExecutionBatches(plan: MigrationPlan): ExecutionBatch[] {\n const entries: ExecutionBatchEntry[] = [\n ...plan.filesToModify.map((entry) => ({ plan: entry, action: 'modify' as const })),\n ...plan.filesToCreate.map((entry) => ({ plan: entry, action: 'create' as const })),\n ];\n const high = entries.filter((e) => e.plan.complexity === 'high');\n const medium = entries.filter((e) => e.plan.complexity === 'medium');\n const low = entries.filter((e) => e.plan.complexity === 'low');\n\n const batches: ExecutionBatch[] = [];\n for (const entry of high) batches.push({ entries: [entry] });\n for (const group of chunk(medium, MEDIUM_BATCH_SIZE)) batches.push({ entries: group });\n for (const group of chunk(low, LOW_BATCH_SIZE)) batches.push({ entries: group });\n return batches;\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const groups: T[][] = [];\n for (let i = 0; i < items.length; i += size) groups.push(items.slice(i, i + size));\n return groups;\n}\n\n/** Parses <transformed_file path=\"...\">content</transformed_file> blocks. */\nexport function parseTransformedFiles(text: string): Map<string, string> {\n const blocks = new Map<string, string>();\n const pattern = /<transformed_file path=\"([^\"]+)\">([\\s\\S]*?)<\\/transformed_file>/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(text)) !== null) {\n let content = match[2]!;\n // The model emits a newline right after the opening tag; strip exactly\n // that one so file content starts at column 0. The trailing newline\n // before the closing tag is the file's own final newline — keep it.\n if (content.startsWith('\\n')) content = content.slice(1);\n blocks.set(match[1]!, content);\n }\n return blocks;\n}\n\nasync function runExecution(\n manifest: CodebaseManifest,\n checkpoint: ExecutionCheckpoint,\n checkpointPath: string,\n apiKey: string,\n onProgress: ProgressCallback,\n options: ExecutionOptions,\n): Promise<ExecutionResult> {\n const adapter = options.adapter ?? new AnthropicAdapter({ apiKey });\n const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n const retryBaseDelayMs = options.retryBaseDelayMs ?? DEFAULT_RETRY_BASE_DELAY_MS;\n const maxOutputTokens = options.maxOutputTokens ?? EXECUTION_MAX_OUTPUT_TOKENS;\n\n const batches = buildExecutionBatches(checkpoint.plan);\n const filesTotal = batches.reduce((sum, b) => sum + b.entries.length, 0);\n const originals = new Map(manifest.files.map((f) => [f.relativePath, f]));\n const completedSet = new Set(checkpoint.completedFiles);\n const systemPrompt = buildSystemPrompt(checkpoint.plan);\n\n const emit = (stage: ExecutionStage, currentFile: string | null): void => {\n onProgress({\n stage,\n currentFile,\n filesComplete: checkpoint.completedFiles.length,\n filesTotal,\n tokensUsed: checkpoint.tokensUsed,\n });\n };\n\n emit('preparing', null);\n try {\n for (let i = 0; i < batches.length; i++) {\n if (checkpoint.batchStatus[i] === 'complete') continue;\n const batch = batches[i]!;\n emit('transforming', batch.entries[0]!.plan.path);\n\n const response = await completeWithRetry(\n adapter,\n {\n systemPrompt,\n userPrompt: buildBatchPrompt(checkpoint.plan, batch, originals),\n maxTokens: maxOutputTokens,\n },\n maxRetries,\n retryBaseDelayMs,\n );\n checkpoint.tokensUsed += response.inputTokens + response.outputTokens;\n\n const blocks = parseTransformedFiles(response.text);\n for (const entry of batch.entries) {\n // Skip files already written by a previous partially-completed run of\n // this batch, so a mid-batch failure + resume cannot double-count.\n // Identity keys (completedFiles/failedFiles/originals) use the stable\n // SOURCE path; only the block lookup and write target use outputPath.\n if (completedSet.has(entry.plan.path)) continue;\n const outputPath = planOutputPath(entry.plan);\n // Prefer the requested output path, but fall back to the source path\n // so a model response keyed on the wrong side of a rename cannot\n // silently drop the file.\n const content = blocks.get(outputPath) ?? blocks.get(entry.plan.path);\n const targetPath =\n content === undefined ? null : safeOutputPath(checkpoint.outputDir, outputPath);\n if (content === undefined || targetPath === null) {\n if (!checkpoint.failedFiles.includes(entry.plan.path)) {\n checkpoint.failedFiles.push(entry.plan.path);\n }\n continue;\n }\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\n await fs.writeFile(targetPath, content, 'utf8');\n\n const original = originals.get(entry.plan.path);\n const { added, removed } = countDiffLines(original?.content ?? '', content);\n checkpoint.linesAdded += added;\n checkpoint.linesRemoved += removed;\n if (entry.action === 'modify') checkpoint.filesModified++;\n else checkpoint.filesCreated++;\n checkpoint.completedFiles.push(entry.plan.path);\n completedSet.add(entry.plan.path);\n checkpoint.failedFiles = checkpoint.failedFiles.filter((p) => p !== entry.plan.path);\n emit('writing', entry.plan.path);\n }\n\n checkpoint.batchStatus[i] = 'complete';\n await saveCheckpoint(checkpointPath, checkpoint);\n }\n } catch (error) {\n await saveCheckpoint(checkpointPath, checkpoint);\n emit('failed', null);\n const message = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Migration execution failed (progress saved to checkpoint): ${message}`,\n checkpointPath,\n );\n }\n\n emit('complete', null);\n const deletedLines = checkpoint.plan.filesToDelete.reduce(\n (sum, filePath) => sum + (originals.get(filePath)?.lines ?? 0),\n 0,\n );\n return {\n filesModified: checkpoint.filesModified,\n filesCreated: checkpoint.filesCreated,\n filesDeleted: checkpoint.plan.filesToDelete.length,\n linesAdded: checkpoint.linesAdded,\n linesRemoved: checkpoint.linesRemoved + deletedLines,\n tokensUsed: checkpoint.tokensUsed,\n failedFiles: [...checkpoint.failedFiles],\n checkpointPath,\n outputDir: checkpoint.outputDir,\n };\n}\n\nfunction buildSystemPrompt(plan: MigrationPlan): string {\n const { from, to, type } = plan.migrationTarget;\n return [\n `You are a senior software engineer executing an approved migration plan: a ${type} migration from \"${from}\" to \"${to}\".`,\n 'Transform each requested file completely and return EVERY requested file in this exact format:',\n '<transformed_file path=\"exact/requested/OUTPUT/path\">',\n '...full transformed file content...',\n '</transformed_file>',\n '',\n 'Rules:',\n '- Return every requested file exactly once. Each file request states \"read from <source path>, return as <output path>\" — always use the OUTPUT path in the transformed_file tag, even when the migration renames the file.',\n '- Output the COMPLETE file content — no truncation, no placeholders, no \"rest of file unchanged\" comments.',\n '- No markdown fences and no commentary outside the transformed_file tags.',\n '- Preserve behavior unless the migration target requires changing it.',\n '- Keep types, imports, and naming consistent across all files in this batch and with the migration plan.',\n ].join('\\n');\n}\n\nfunction buildBatchPrompt(\n plan: MigrationPlan,\n batch: ExecutionBatch,\n originals: Map<string, FileEntry>,\n): string {\n const lines = [\n `Migration plan summary:\\n${plan.summary}`,\n `Planned dependency changes: ${JSON.stringify(plan.dependencyChanges)}`,\n '',\n 'Files to transform in this batch:',\n ];\n for (const entry of batch.entries) {\n const outputPath = planOutputPath(entry.plan);\n const action =\n entry.action === 'create'\n ? 'CREATE new file'\n : outputPath === entry.plan.path\n ? 'MODIFY'\n : 'MODIFY and RENAME';\n lines.push(\n `- read from \"${entry.plan.path}\", return as \"${outputPath}\" [${action}, complexity: ${entry.plan.complexity}] ${entry.plan.description}`,\n );\n }\n lines.push('', 'Original file contents:');\n for (const entry of batch.entries) {\n if (entry.action === 'create') {\n lines.push(\n `<file path=\"${entry.plan.path}\">\\n(new file — no original content; create it per the plan description)\\n</file>`,\n );\n continue;\n }\n const original = originals.get(entry.plan.path);\n lines.push(`<file path=\"${entry.plan.path}\">\\n${original?.content ?? ''}\\n</file>`);\n }\n return lines.join('\\n');\n}\n\nasync function completeWithRetry(\n adapter: LLMAdapter,\n request: { systemPrompt: string; userPrompt: string; maxTokens: number },\n maxRetries: number,\n baseDelayMs: number,\n): Promise<LLMResponse> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (attempt > 0) await sleep(baseDelayMs * 2 ** (attempt - 1));\n try {\n return await adapter.complete(request);\n } catch (error) {\n lastError = error;\n }\n }\n throw lastError instanceof Error ? lastError : new Error(String(lastError));\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Resolves relPath inside outputDir; returns null if it would escape it. */\nfunction safeOutputPath(outputDir: string, relPath: string): string | null {\n const root = path.resolve(outputDir);\n const resolved = path.resolve(root, relPath);\n return resolved.startsWith(root + path.sep) ? resolved : null;\n}\n\nfunction countDiffLines(\n oldContent: string,\n newContent: string,\n): { added: number; removed: number } {\n let added = 0;\n let removed = 0;\n for (const part of diffLines(oldContent, newContent)) {\n if (part.added) added += part.count ?? 0;\n else if (part.removed) removed += part.count ?? 0;\n }\n return { added, removed };\n}\n\nasync function saveCheckpoint(\n checkpointPath: string,\n checkpoint: ExecutionCheckpoint,\n): Promise<void> {\n checkpoint.updatedAt = new Date().toISOString();\n await fs.mkdir(path.dirname(checkpointPath), { recursive: true });\n await fs.writeFile(checkpointPath, JSON.stringify(checkpoint, null, 2), 'utf8');\n}\n","export default class Diff {\n diff(oldStr, newStr, \n // Type below is not accurate/complete - see above for full possibilities - but it compiles\n options = {}) {\n let callback;\n if (typeof options === 'function') {\n callback = options;\n options = {};\n }\n else if ('callback' in options) {\n callback = options.callback;\n }\n // Allow subclasses to massage the input prior to running\n const oldString = this.castInput(oldStr, options);\n const newString = this.castInput(newStr, options);\n const oldTokens = this.removeEmpty(this.tokenize(oldString, options));\n const newTokens = this.removeEmpty(this.tokenize(newString, options));\n return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);\n }\n diffWithOptionsObj(oldTokens, newTokens, options, callback) {\n var _a;\n const done = (value) => {\n value = this.postProcess(value, options);\n if (callback) {\n setTimeout(function () { callback(value); }, 0);\n return undefined;\n }\n else {\n return value;\n }\n };\n const newLen = newTokens.length, oldLen = oldTokens.length;\n let editLength = 1;\n let maxEditLength = newLen + oldLen;\n if (options.maxEditLength != null) {\n maxEditLength = Math.min(maxEditLength, options.maxEditLength);\n }\n const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;\n const abortAfterTimestamp = Date.now() + maxExecutionTime;\n const bestPath = [{ oldPos: -1, lastComponent: undefined }];\n // Seed editLength = 0, i.e. the content starts with the same values\n let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);\n if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n // Identity per the equality and tokenizer\n return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));\n }\n // Once we hit the right edge of the edit graph on some diagonal k, we can\n // definitely reach the end of the edit graph in no more than k edits, so\n // there's no point in considering any moves to diagonal k+1 any more (from\n // which we're guaranteed to need at least k+1 more edits).\n // Similarly, once we've reached the bottom of the edit graph, there's no\n // point considering moves to lower diagonals.\n // We record this fact by setting minDiagonalToConsider and\n // maxDiagonalToConsider to some finite value once we've hit the edge of\n // the edit graph.\n // This optimization is not faithful to the original algorithm presented in\n // Myers's paper, which instead pointlessly extends D-paths off the end of\n // the edit graph - see page 7 of Myers's paper which notes this point\n // explicitly and illustrates it with a diagram. This has major performance\n // implications for some common scenarios. For instance, to compute a diff\n // where the new text simply appends d characters on the end of the\n // original text of length n, the true Myers algorithm will take O(n+d^2)\n // time while this optimization needs only O(n+d) time.\n let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;\n // Main worker method. checks all permutations of a given edit length for acceptance.\n const execEditLength = () => {\n for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {\n let basePath;\n const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];\n if (removePath) {\n // No one else is going to attempt to use this value, clear it\n // @ts-expect-error - perf optimisation. This type-violating value will never be read.\n bestPath[diagonalPath - 1] = undefined;\n }\n let canAdd = false;\n if (addPath) {\n // what newPos will be after we do an insertion:\n const addPathNewPos = addPath.oldPos - diagonalPath;\n canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;\n }\n const canRemove = removePath && removePath.oldPos + 1 < oldLen;\n if (!canAdd && !canRemove) {\n // If this path is a terminal then prune\n // @ts-expect-error - perf optimisation. This type-violating value will never be read.\n bestPath[diagonalPath] = undefined;\n continue;\n }\n // Select the diagonal that we want to branch from. We select the prior\n // path whose position in the old string is the farthest from the origin\n // and does not pass the bounds of the diff graph\n if (!canRemove || (canAdd && removePath.oldPos < addPath.oldPos)) {\n basePath = this.addToPath(addPath, true, false, 0, options);\n }\n else {\n basePath = this.addToPath(removePath, false, true, 1, options);\n }\n newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);\n if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n // If we have hit the end of both strings, then we are done\n return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;\n }\n else {\n bestPath[diagonalPath] = basePath;\n if (basePath.oldPos + 1 >= oldLen) {\n maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);\n }\n if (newPos + 1 >= newLen) {\n minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);\n }\n }\n }\n editLength++;\n };\n // Performs the length of edit iteration. Is a bit fugly as this has to support the\n // sync and async mode which is never fun. Loops over execEditLength until a value\n // is produced, or until the edit length exceeds options.maxEditLength (if given),\n // in which case it will return undefined.\n if (callback) {\n (function exec() {\n setTimeout(function () {\n if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {\n return callback(undefined);\n }\n if (!execEditLength()) {\n exec();\n }\n }, 0);\n }());\n }\n else {\n while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {\n const ret = execEditLength();\n if (ret) {\n return ret;\n }\n }\n }\n }\n addToPath(path, added, removed, oldPosInc, options) {\n const last = path.lastComponent;\n if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {\n return {\n oldPos: path.oldPos + oldPosInc,\n lastComponent: { count: last.count + 1, added: added, removed: removed, previousComponent: last.previousComponent }\n };\n }\n else {\n return {\n oldPos: path.oldPos + oldPosInc,\n lastComponent: { count: 1, added: added, removed: removed, previousComponent: last }\n };\n }\n }\n extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {\n const newLen = newTokens.length, oldLen = oldTokens.length;\n let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;\n while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {\n newPos++;\n oldPos++;\n commonCount++;\n if (options.oneChangePerToken) {\n basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };\n }\n }\n if (commonCount && !options.oneChangePerToken) {\n basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };\n }\n basePath.oldPos = oldPos;\n return newPos;\n }\n equals(left, right, options) {\n if (options.comparator) {\n return options.comparator(left, right);\n }\n else {\n return left === right\n || (!!options.ignoreCase && left.toLowerCase() === right.toLowerCase());\n }\n }\n removeEmpty(array) {\n const ret = [];\n for (let i = 0; i < array.length; i++) {\n if (array[i]) {\n ret.push(array[i]);\n }\n }\n return ret;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n castInput(value, options) {\n return value;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n tokenize(value, options) {\n return Array.from(value);\n }\n join(chars) {\n // Assumes ValueT is string, which is the case for most subclasses.\n // When it's false, e.g. in diffArrays, this method needs to be overridden (e.g. with a no-op)\n // Yes, the casts are verbose and ugly, because this pattern - of having the base class SORT OF\n // assume tokens and values are strings, but not completely - is weird and janky.\n return chars.join('');\n }\n postProcess(changeObjects, \n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n options) {\n return changeObjects;\n }\n get useLongestToken() {\n return false;\n }\n buildValues(lastComponent, newTokens, oldTokens) {\n // First we convert our linked list of components in reverse order to an\n // array in the right order:\n const components = [];\n let nextComponent;\n while (lastComponent) {\n components.push(lastComponent);\n nextComponent = lastComponent.previousComponent;\n delete lastComponent.previousComponent;\n lastComponent = nextComponent;\n }\n components.reverse();\n const componentLen = components.length;\n let componentPos = 0, newPos = 0, oldPos = 0;\n for (; componentPos < componentLen; componentPos++) {\n const component = components[componentPos];\n if (!component.removed) {\n if (!component.added && this.useLongestToken) {\n let value = newTokens.slice(newPos, newPos + component.count);\n value = value.map(function (value, i) {\n const oldValue = oldTokens[oldPos + i];\n return oldValue.length > value.length ? oldValue : value;\n });\n component.value = this.join(value);\n }\n else {\n component.value = this.join(newTokens.slice(newPos, newPos + component.count));\n }\n newPos += component.count;\n // Common case\n if (!component.added) {\n oldPos += component.count;\n }\n }\n else {\n component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));\n oldPos += component.count;\n }\n }\n return components;\n }\n}\n","import Diff from './base.js';\nimport { generateOptions } from '../util/params.js';\nclass LineDiff extends Diff {\n constructor() {\n super(...arguments);\n this.tokenize = tokenize;\n }\n equals(left, right, options) {\n // If we're ignoring whitespace, we need to normalise lines by stripping\n // whitespace before checking equality. (This has an annoying interaction\n // with newlineIsToken that requires special handling: if newlines get their\n // own token, then we DON'T want to trim the *newline* tokens down to empty\n // strings, since this would cause us to treat whitespace-only line content\n // as equal to a separator between lines, which would be weird and\n // inconsistent with the documented behavior of the options.)\n if (options.ignoreWhitespace) {\n if (!options.newlineIsToken || !left.includes('\\n')) {\n left = left.trim();\n }\n if (!options.newlineIsToken || !right.includes('\\n')) {\n right = right.trim();\n }\n }\n else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {\n if (left.endsWith('\\n')) {\n left = left.slice(0, -1);\n }\n if (right.endsWith('\\n')) {\n right = right.slice(0, -1);\n }\n }\n return super.equals(left, right, options);\n }\n}\nexport const lineDiff = new LineDiff();\nexport function diffLines(oldStr, newStr, options) {\n return lineDiff.diff(oldStr, newStr, options);\n}\nexport function diffTrimmedLines(oldStr, newStr, options) {\n options = generateOptions(options, { ignoreWhitespace: true });\n return lineDiff.diff(oldStr, newStr, options);\n}\n// Exported standalone so it can be used from jsonDiff too.\nexport function tokenize(value, options) {\n if (options.stripTrailingCr) {\n // remove one \\r before \\n to match GNU diff's --strip-trailing-cr behavior\n value = value.replace(/\\r\\n/g, '\\n');\n }\n const retLines = [], linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n // Ignore the final empty token that occurs if the string ends with a new line\n if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n linesAndNewlines.pop();\n }\n // Merge the content and line separators into single tokens\n for (let i = 0; i < linesAndNewlines.length; i++) {\n const line = linesAndNewlines[i];\n if (i % 2 && !options.newlineIsToken) {\n retLines[retLines.length - 1] += line;\n }\n else {\n retLines.push(line);\n }\n }\n return retLines;\n}\n","/**\n * Verification agent — Pass 3 of the 3-pass migration pipeline.\n *\n * Runs the project's test suite against the migrated output, asks the model\n * to self-review its own migration, computes diff stats, and (when the test\n * pass rate falls below threshold) triggers a self-repair loop that re-runs\n * execution on failed files only.\n *\n * Spike findings applied here:\n * - The package-manager install step runs BEFORE tests, otherwise missing\n * @types packages produce false-positive failures (spike finding 2).\n * - Issues are categorised 'environment' vs 'conversion' so the report says\n * \"1 conversion error, 9 dependency setup items\" instead of \"10 errors\"\n * (spike finding 1).\n * - Self-repair triggers only below the pass-rate threshold (spike finding 3).\n */\nimport { spawn } from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { diffLines } from 'diff';\nimport { executeMigration, type ExecutionResult } from '../execution/index.js';\nimport type { CodebaseManifest } from '../ingestion/index.js';\nimport { AnthropicAdapter, type LLMAdapter } from '../llm/index.js';\nimport {\n planOutputPath,\n type ChangeComplexity,\n type FilePlanEntry,\n type MigrationPlan,\n} from '../planning/index.js';\n\nexport const VERIFICATION_MAX_OUTPUT_TOKENS = 4000;\nexport const DEFAULT_SELF_REPAIR_THRESHOLD = 0.9;\nexport const DEFAULT_MAX_SELF_REPAIR_ATTEMPTS = 2;\nexport const DEFAULT_MAX_REVIEW_FILES = 20;\n/**\n * Hard cap on confidence when the output does not compile. Compilation is\n * necessary, not sufficient: a compile failure caps confidence regardless of\n * the model's self-review, but a compile pass does NOT inflate it.\n */\nexport const COMPILE_FAIL_CONFIDENCE_CAP = 0.3;\nconst TEST_OUTPUT_EXCERPT_CHARS = 4000;\nconst COMMAND_OUTPUT_EXCERPT_CHARS = 600;\n\nexport type IssueCategory = 'environment' | 'conversion';\n\nexport interface FlaggedIssue {\n description: string;\n severity: ChangeComplexity;\n /** environment = setup/dependency problem; conversion = real migration error. */\n category: IssueCategory;\n affectedFiles: string[];\n}\n\nexport interface FileDiffStat {\n path: string;\n linesAdded: number;\n linesRemoved: number;\n}\n\nexport interface DiffStats {\n totalFilesChanged: number;\n linesAdded: number;\n linesRemoved: number;\n /** Top 5 files by total changed lines. */\n largestDiffs: FileDiffStat[];\n}\n\n/** One error from an objective static check (e.g. a tsc diagnostic). */\nexport interface CompileError {\n /** Path as reported by the compiler — an OUTPUT path relative to migratedDir. */\n file: string;\n line?: number;\n col?: number;\n /** Compiler error code, e.g. \"TS2344\". */\n code?: string;\n message: string;\n}\n\n/**\n * Result of the objective static check on the migrated output.\n * `ran && !ok` means the compiler ran and found errors (a CONVERSION\n * problem); `!ran` means the toolchain couldn't run (an ENVIRONMENT\n * problem — recorded in skippedReason, never a conversion failure).\n */\nexport interface CompileCheck {\n ran: boolean;\n ok: boolean;\n errors: CompileError[];\n skippedReason?: string;\n}\n\n/**\n * Static-check recipe for one destination language. installCmd is a\n * default — for node projects the actual package manager is detected from\n * lockfiles, same as the test runner's install step.\n */\nexport interface StaticCheckDescriptor {\n installCmd?: [string, string[]];\n checkCmd: [string, string[]];\n parse(output: string): CompileError[];\n}\n\nexport interface VerificationReport {\n /** 0.0–1.0, or null when no test suite was detected. */\n testPassRate: number | null;\n testOutput: string;\n /** The command used to run tests, or null when none was detected. */\n testCommand: string | null;\n /** Model self-assessment, 0.0–1.0, hard-capped when the output does not compile. */\n confidenceScore: number;\n /**\n * Objective static check on the output. Always set by verifyMigration;\n * optional only for reports persisted by older engine versions (treat a\n * missing value as \"check unavailable\").\n */\n compileCheck?: CompileCheck;\n flaggedIssues: FlaggedIssue[];\n diffStats: DiffStats;\n selfRepairAttempts: number;\n reportGeneratedAt: string;\n}\n\nexport interface CommandResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\nexport type CommandRunner = (\n command: string,\n args: string[],\n cwd: string,\n) => Promise<CommandResult>;\n\nexport interface VerificationOptions {\n /** Override the model adapter (used for tests and model routing). */\n adapter?: LLMAdapter;\n /** Override how shell commands run (used for tests). */\n commandRunner?: CommandRunner;\n /** Required for self-repair: without it, repair is skipped. */\n manifest?: CodebaseManifest;\n /** Default: true. Self-repair is threshold-triggered either way. */\n selfRepair?: boolean;\n /** Re-run execution when testPassRate falls below this. Default: 0.9. */\n selfRepairThreshold?: number;\n /** Default: 2. */\n maxSelfRepairAttempts?: number;\n /** Max original/migrated file pairs sent for self-review. Default: 20. */\n maxReviewFiles?: number;\n /** Skip the dependency install step before running tests. Default: false. */\n skipInstall?: boolean;\n /** Timeout for install + test commands. Default: 10 minutes each. */\n commandTimeoutMs?: number;\n}\n\nexport interface TestSetup {\n /** Run before tests so missing dev deps don't cause false failures. */\n installCommand: [string, string[]] | null;\n testCommand: [string, string[]];\n label: string;\n}\n\nexport async function verifyMigration(\n originalDir: string,\n migratedDir: string,\n plan: MigrationPlan,\n executionResult: ExecutionResult,\n apiKey: string,\n options: VerificationOptions = {},\n): Promise<VerificationReport> {\n const adapter = options.adapter ?? new AnthropicAdapter({ apiKey });\n const runCommand = options.commandRunner ?? defaultCommandRunner(options.commandTimeoutMs);\n const selfRepairEnabled = options.selfRepair ?? true;\n const threshold = options.selfRepairThreshold ?? DEFAULT_SELF_REPAIR_THRESHOLD;\n const maxAttempts = options.maxSelfRepairAttempts ?? DEFAULT_MAX_SELF_REPAIR_ATTEMPTS;\n\n // a) Detect and run the existing test suite from the migrated directory.\n const setup = await detectTestSetup(migratedDir);\n let testPassRate: number | null = null;\n let testOutput = '';\n let testCommand: string | null = null;\n\n if (setup !== null) {\n testCommand = [setup.testCommand[0], ...setup.testCommand[1]].join(' ');\n if (setup.installCommand !== null && options.skipInstall !== true) {\n await runCommand(setup.installCommand[0], setup.installCommand[1], migratedDir);\n }\n ({ testPassRate, testOutput } = await runTests(setup, migratedDir, runCommand));\n }\n\n // d) Self-repair loop: re-run execution on failed files only, then re-test.\n let selfRepairAttempts = 0;\n let failedFiles = executionResult.failedFiles;\n while (\n selfRepairEnabled &&\n options.manifest !== undefined &&\n failedFiles.length > 0 &&\n testPassRate !== null &&\n testPassRate < threshold &&\n selfRepairAttempts < maxAttempts &&\n setup !== null\n ) {\n selfRepairAttempts++;\n const repairResult = await repairFailedFiles(\n options.manifest,\n plan,\n failedFiles,\n executionResult,\n apiKey,\n adapter,\n selfRepairAttempts,\n );\n failedFiles = repairResult.failedFiles;\n ({ testPassRate, testOutput } = await runTests(setup, migratedDir, runCommand));\n }\n\n // e) Objective static check: the ground-truth correctness gate. Tests may\n // be absent and the self-review is subjective; the compiler is neither.\n const descriptor = staticCheckForTarget(plan.migrationTarget.to);\n const installedForTests = setup?.installCommand !== null && setup !== null;\n let compileCheck: CompileCheck =\n descriptor === null\n ? {\n ran: false,\n ok: false,\n errors: [],\n skippedReason: `no static check registered for target \"${plan.migrationTarget.to}\"`,\n }\n : await runStaticCheck(migratedDir, descriptor, runCommand, {\n skipInstall: options.skipInstall === true || installedForTests,\n });\n\n // f) Compile-driven self-repair: files the compiler proves WRONG (not just\n // missing) are re-executed with the exact errors in the prompt, then\n // re-checked, up to the shared attempts cap.\n let compileRepairs = 0;\n while (\n selfRepairEnabled &&\n options.manifest !== undefined &&\n descriptor !== null &&\n compileCheck.ran &&\n !compileCheck.ok &&\n selfRepairAttempts < maxAttempts\n ) {\n const repairTargets = mapCompileErrorsToEntries(compileCheck.errors, plan);\n if (repairTargets.size === 0) break; // errors in files we didn't produce — can't repair\n selfRepairAttempts++;\n compileRepairs++;\n await repairCompileErrors(\n options.manifest,\n plan,\n repairTargets,\n executionResult,\n apiKey,\n adapter,\n selfRepairAttempts,\n );\n compileCheck = await runStaticCheck(migratedDir, descriptor, runCommand, {\n skipInstall: true,\n });\n }\n if (compileRepairs > 0 && setup !== null) {\n // Repairs rewrote files after the last test run — refresh the pass rate.\n ({ testPassRate, testOutput } = await runTests(setup, migratedDir, runCommand));\n }\n\n // b) Model self-review of the final migrated state (sees compile results).\n const review = await selfReview(\n originalDir,\n migratedDir,\n plan,\n `${testOutput}\\n\\n${describeCompileCheck(compileCheck)}`.trim(),\n adapter,\n options.maxReviewFiles ?? DEFAULT_MAX_REVIEW_FILES,\n );\n\n // c) Diff stats over the planned file set.\n const diffStats = await computeDiffStats(originalDir, migratedDir, plan);\n\n // g) Confidence gating: a compile failure hard-caps confidence no matter\n // what the review said; a compile pass does not inflate it; a check that\n // couldn't run is flagged honestly as missing objective verification.\n let confidenceScore = review.confidenceScore;\n const flaggedIssues = [...review.issues];\n if (compileCheck.ran && !compileCheck.ok) {\n confidenceScore = Math.min(confidenceScore, COMPILE_FAIL_CONFIDENCE_CAP);\n const files = [...new Set(compileCheck.errors.map((e) => e.file).filter((f) => f !== ''))];\n flaggedIssues.unshift({\n description:\n `Output does not compile: ${compileCheck.errors.length} compiler error(s)` +\n (selfRepairAttempts > 0 ? ` remain after ${selfRepairAttempts} self-repair attempt(s)` : '') +\n `. ${compileCheck.errors.map(formatCompileError).join('; ')}`,\n severity: 'high',\n category: 'conversion',\n affectedFiles: files,\n });\n } else if (!compileCheck.ran) {\n flaggedIssues.push({\n description: `Objective compile check unavailable (${compileCheck.skippedReason ?? 'unknown reason'}); confidence rests on model self-review only — manual verification recommended.`,\n severity: 'medium',\n category: 'environment',\n affectedFiles: [],\n });\n }\n\n return {\n testPassRate,\n testOutput,\n testCommand,\n confidenceScore,\n compileCheck,\n flaggedIssues,\n diffStats,\n selfRepairAttempts,\n reportGeneratedAt: new Date().toISOString(),\n };\n}\n\n/**\n * Detects the project's test setup from config files in the migrated\n * directory: package.json test script (Node), pytest markers (Python),\n * pubspec.yaml (Flutter), go.mod (Go), Cargo.toml (Rust).\n */\nexport async function detectTestSetup(dir: string): Promise<TestSetup | null> {\n const pkgContent = await readOptional(path.join(dir, 'package.json'));\n if (pkgContent !== null) {\n let pkg: Record<string, unknown> = {};\n try {\n pkg = JSON.parse(pkgContent) as Record<string, unknown>;\n } catch {\n return null;\n }\n const scripts = (pkg.scripts ?? {}) as Record<string, unknown>;\n const testScript = typeof scripts.test === 'string' ? scripts.test : '';\n if (testScript === '' || testScript.includes('no test specified')) return null;\n\n const pm = await detectNodePackageManager(dir);\n return {\n installCommand: [pm, ['install']],\n testCommand: [pm, ['test']],\n label: 'node',\n };\n }\n\n const pyproject = await readOptional(path.join(dir, 'pyproject.toml'));\n const hasPytest =\n (pyproject !== null && pyproject.includes('pytest')) ||\n (await exists(path.join(dir, 'pytest.ini'))) ||\n (await exists(path.join(dir, 'conftest.py')));\n if (hasPytest) {\n return { installCommand: null, testCommand: ['pytest', []], label: 'python' };\n }\n if (await exists(path.join(dir, 'pubspec.yaml'))) {\n return { installCommand: null, testCommand: ['flutter', ['test']], label: 'flutter' };\n }\n if (await exists(path.join(dir, 'go.mod'))) {\n return { installCommand: null, testCommand: ['go', ['test', './...']], label: 'go' };\n }\n if (await exists(path.join(dir, 'Cargo.toml'))) {\n return { installCommand: null, testCommand: ['cargo', ['test']], label: 'rust' };\n }\n return null;\n}\n\n/** Lockfile-based package-manager detection, shared by tests + static check. */\nasync function detectNodePackageManager(dir: string): Promise<string> {\n if (await exists(path.join(dir, 'pnpm-lock.yaml'))) return 'pnpm';\n if (await exists(path.join(dir, 'yarn.lock'))) return 'yarn';\n return 'npm';\n}\n\n// --- Objective static check (Hotfix C) ---\n\n/**\n * Static checks by destination language (plan.migrationTarget.to, lowercased).\n *\n * TypeScript is the launch target and fully implemented. Extension stubs —\n * add a descriptor here when a target ships; do NOT half-implement:\n * python: { checkCmd: ['python', ['-m', 'compileall', '-q', '.']],\n * parse: py_compile \"File \\\"x.py\\\", line N\" diagnostics }\n * go: { checkCmd: ['go', ['build', './...']],\n * parse: \"file.go:line:col: message\" diagnostics }\n * rust: { checkCmd: ['cargo', ['check', '--quiet']],\n * parse: \"error[E0308]: ...\" + \"--> src/x.rs:line:col\" pairs }\n */\nconst STATIC_CHECKS: Record<string, StaticCheckDescriptor> = {\n typescript: {\n installCmd: ['npm', ['install']],\n checkCmd: ['npx', ['tsc', '--noEmit']],\n parse: parseTscOutput,\n },\n};\n\n/** The static check registered for a destination language, or null. */\nexport function staticCheckForTarget(to: string): StaticCheckDescriptor | null {\n return STATIC_CHECKS[to.trim().toLowerCase()] ?? null;\n}\n\n/**\n * Parses tsc diagnostics. Handles both output shapes:\n * src/high.ts:31:15 - error TS2344: message (pretty)\n * src/high.ts(31,15): error TS2344: message (plain)\n * and location-less config errors (\"error TS5083: ...\").\n */\nexport function parseTscOutput(output: string): CompileError[] {\n const located =\n /^(.+?)[(:](\\d+)[,:](\\d+)\\)?\\s*[-:]?\\s*error\\s+(TS\\d+):\\s*(.+)$/;\n const bare = /^error\\s+(TS\\d+):\\s*(.+)$/;\n const errors: CompileError[] = [];\n for (const rawLine of output.split('\\n')) {\n const line = rawLine.trim();\n const withLocation = located.exec(line);\n if (withLocation !== null) {\n errors.push({\n file: withLocation[1]!.trim(),\n line: Number(withLocation[2]),\n col: Number(withLocation[3]),\n code: withLocation[4]!,\n message: withLocation[5]!.trim(),\n });\n continue;\n }\n const withoutLocation = bare.exec(line);\n if (withoutLocation !== null) {\n errors.push({ file: '', code: withoutLocation[1]!, message: withoutLocation[2]!.trim() });\n }\n }\n return errors;\n}\n\nexport function formatCompileError(error: CompileError): string {\n const location =\n error.file === '' ? '' : `${error.file}${error.line === undefined ? '' : `:${error.line}:${error.col ?? 0}`} `;\n return `${location}${error.code === undefined ? '' : `${error.code}: `}${error.message}`;\n}\n\n/**\n * Runs the static check in migratedDir. Never throws: a toolchain that\n * cannot run (install failure, missing compiler) degrades to\n * { ran: false, skippedReason } — an ENVIRONMENT issue, distinct from\n * \"compiler ran and found errors\" which is a CONVERSION issue.\n */\nexport async function runStaticCheck(\n migratedDir: string,\n descriptor: StaticCheckDescriptor,\n runCommand: CommandRunner,\n options: { skipInstall?: boolean } = {},\n): Promise<CompileCheck> {\n const skipped = (skippedReason: string): CompileCheck => ({\n ran: false,\n ok: false,\n errors: [],\n skippedReason,\n });\n try {\n if (\n descriptor.installCmd !== undefined &&\n options.skipInstall !== true &&\n (await exists(path.join(migratedDir, 'package.json')))\n ) {\n const pm = await detectNodePackageManager(migratedDir);\n const install = await runCommand(pm, descriptor.installCmd[1], migratedDir);\n if (install.exitCode !== 0) {\n return skipped(\n `dependency install failed (${pm} install exit ${install.exitCode}): ${excerpt(install.stderr || install.stdout)}`,\n );\n }\n }\n const result = await runCommand(descriptor.checkCmd[0], descriptor.checkCmd[1], migratedDir);\n if (result.exitCode === 0) return { ran: true, ok: true, errors: [] };\n const output = `${result.stdout}\\n${result.stderr}`;\n const errors = descriptor.parse(output);\n if (errors.length === 0) {\n // Non-zero exit with no parseable diagnostics — the toolchain itself\n // failed (command not found, npx offline, …), not the migrated code.\n return skipped(\n `check command could not run (${descriptor.checkCmd[0]} exit ${result.exitCode}): ${excerpt(result.stderr || result.stdout)}`,\n );\n }\n return { ran: true, ok: false, errors };\n } catch (error) {\n return skipped(`toolchain unavailable: ${excerpt(String(error))}`);\n }\n}\n\nfunction excerpt(text: string): string {\n const trimmed = text.trim();\n return trimmed.length <= COMMAND_OUTPUT_EXCERPT_CHARS\n ? trimmed\n : `${trimmed.slice(0, COMMAND_OUTPUT_EXCERPT_CHARS)}…`;\n}\n\nfunction describeCompileCheck(check: CompileCheck): string {\n if (!check.ran) return `Compile check skipped: ${check.skippedReason ?? 'unavailable'}`;\n if (check.ok) return 'Compile check: passed (output compiles cleanly).';\n return `Compile check FAILED with ${check.errors.length} error(s):\\n${check.errors.map(formatCompileError).join('\\n')}`;\n}\n\n/**\n * Maps compiler errors (reported against OUTPUT paths, e.g. high.ts) back to\n * the plan entries that produced them, keyed on the entry's SOURCE path (the\n * pipeline's stable identity — Hotfix A invariant). Errors in files no plan\n * entry produced (copied-through files, location-less config errors) are\n * dropped: they can't be repaired by re-executing a transformation.\n */\nexport function mapCompileErrorsToEntries(\n errors: CompileError[],\n plan: MigrationPlan,\n): Map<string, { entry: FilePlanEntry; errors: CompileError[] }> {\n const byOutputPath = new Map<string, FilePlanEntry>();\n for (const entry of [...plan.filesToModify, ...plan.filesToCreate]) {\n byOutputPath.set(normalizeRelPath(planOutputPath(entry)), entry);\n }\n const targets = new Map<string, { entry: FilePlanEntry; errors: CompileError[] }>();\n for (const error of errors) {\n if (error.file === '') continue;\n const entry = byOutputPath.get(normalizeRelPath(error.file));\n if (entry === undefined) continue;\n const existing = targets.get(entry.path);\n if (existing === undefined) targets.set(entry.path, { entry, errors: [error] });\n else existing.errors.push(error);\n }\n return targets;\n}\n\nfunction normalizeRelPath(relPath: string): string {\n return relPath.replaceAll('\\\\', '/').replace(/^\\.\\//, '');\n}\n\n// --- Cross-file repair context (Hotfix E) ---\n\n/** Max directly-imported files added as read-only context per errored file. */\nexport const REPAIR_CONTEXT_MAX_IMPORTS = 8;\n/** Max characters of one context file included in the repair prompt. */\nexport const REPAIR_CONTEXT_FILE_MAX_CHARS = 12_000;\n\nconst RESOLVE_EXTENSIONS = ['', '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.json'];\n\n/**\n * Extracts module specifiers from import/export/require statements,\n * best-effort by regex — enough for the one-hop repair context, NOT a\n * general import-graph analyzer (deliberately: see Hotfix E scope).\n */\nexport function parseImportSpecifiers(source: string): string[] {\n const patterns = [\n /\\b(?:import|export)\\b[^'\"`;()]*?\\bfrom\\s*['\"]([^'\"]+)['\"]/g,\n /\\bimport\\s*['\"]([^'\"]+)['\"]/g,\n /\\b(?:require|import)\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g,\n ];\n const specifiers: string[] = [];\n for (const pattern of patterns) {\n for (const match of source.matchAll(pattern)) {\n if (!specifiers.includes(match[1]!)) specifiers.push(match[1]!);\n }\n }\n return specifiers;\n}\n\n/**\n * Resolves a RELATIVE import specifier against the importing file's\n * directory to a known source path (extension and /index candidates, plus\n * the ESM \".js\"-suffix-for-\".ts\" convention). Bare/package specifiers and\n * unresolvable paths return null — best-effort by design.\n */\nexport function resolveRelativeImport(\n fromRelPath: string,\n specifier: string,\n knownPaths: ReadonlySet<string>,\n): string | null {\n if (!specifier.startsWith('.')) return null;\n const base = path.posix\n .normalize(path.posix.join(path.posix.dirname(normalizeRelPath(fromRelPath)), specifier))\n .replace(/^\\.\\//, '');\n for (const ext of RESOLVE_EXTENSIONS) {\n if (knownPaths.has(base + ext)) return base + ext;\n }\n for (const ext of RESOLVE_EXTENSIONS.slice(1)) {\n if (knownPaths.has(`${base}/index${ext}`)) return `${base}/index${ext}`;\n }\n const tsForJs = base.replace(/\\.([mc]?)js$/, '.$1ts');\n if (tsForJs !== base && knownPaths.has(tsForJs)) return tsForJs;\n return null;\n}\n\n/**\n * Builds the READ-ONLY cross-file context for a compile repair: the\n * contents of files DIRECTLY imported by the errored files (one hop, never\n * transitive), preferring the MIGRATED version — the declarations tsc\n * actually checked the errored file against. The write set is NOT widened:\n * these files are shown, never re-executed. Returns '' when the errored\n * files have no resolvable imports, keeping the single-file repair path\n * byte-identical to before Hotfix E.\n */\nasync function collectRepairContext(\n manifest: CodebaseManifest,\n plan: MigrationPlan,\n targets: Map<string, { entry: FilePlanEntry; errors: CompileError[] }>,\n migratedDir: string,\n): Promise<string> {\n const bySourcePath = new Map(manifest.files.map((f) => [normalizeRelPath(f.relativePath), f]));\n const knownPaths = new Set(bySourcePath.keys());\n const entriesBySource = new Map<string, FilePlanEntry>();\n for (const entry of [...plan.filesToModify, ...plan.filesToCreate]) {\n entriesBySource.set(normalizeRelPath(entry.path), entry);\n }\n const targetPaths = new Set([...targets.keys()].map(normalizeRelPath));\n\n const blocks: string[] = [];\n const included = new Set<string>();\n for (const sourcePath of targets.keys()) {\n const file = bySourcePath.get(normalizeRelPath(sourcePath));\n if (file === undefined) continue;\n let count = 0;\n for (const specifier of parseImportSpecifiers(file.content)) {\n if (count >= REPAIR_CONTEXT_MAX_IMPORTS) break;\n const resolved = resolveRelativeImport(file.relativePath, specifier, knownPaths);\n // Skip files being repaired in this same pass (their content is in\n // flux) and files already included for another errored importer.\n if (resolved === null || targetPaths.has(resolved) || included.has(resolved)) continue;\n const importedEntry = entriesBySource.get(resolved);\n const migratedRelPath =\n importedEntry === undefined ? resolved : normalizeRelPath(planOutputPath(importedEntry));\n const migrated = await readOptional(path.join(migratedDir, migratedRelPath));\n const content = migrated ?? bySourcePath.get(resolved)!.content;\n const displayPath = migrated === null ? resolved : migratedRelPath;\n included.add(resolved);\n count++;\n const body =\n content.length <= REPAIR_CONTEXT_FILE_MAX_CHARS\n ? content\n : `${content.slice(0, REPAIR_CONTEXT_FILE_MAX_CHARS)}\\n… (truncated)`;\n blocks.push(\n `<context_file path=\"${displayPath}\" imported_by=\"${sourcePath}\">\\n${body}\\n</context_file>`,\n );\n }\n }\n if (blocks.length === 0) return '';\n return [\n '',\n '',\n 'READ-ONLY CONTEXT — files directly imported by the file(s) being repaired, as they exist in the migrated output. Do NOT return these files; they are not part of this batch. Use them to match imported declarations and signatures EXACTLY. When a compiler error involves a symbol imported from one of these files, fix the CALL SITE in the file you are repairing so it satisfies the imported signature as shown (for example, narrow an unknown value with a typeof check before passing it).',\n ...blocks,\n ].join('\\n');\n}\n\n/**\n * Re-executes the files the compiler proved wrong, with the exact errors\n * injected into the prompt so the model targets the real defect. Identity\n * stays on source paths; output paths flow through planOutputPath.\n *\n * Cross-file errors (Hotfix E): the repair prompt additionally carries the\n * migrated contents of files DIRECTLY imported by the errored files, as\n * read-only context — so an error whose cause is a signature declared in\n * another file can be fixed at the call site. The write set stays exactly\n * the errored files; imports are shown, never re-executed.\n */\nasync function repairCompileErrors(\n manifest: CodebaseManifest,\n plan: MigrationPlan,\n targets: Map<string, { entry: FilePlanEntry; errors: CompileError[] }>,\n executionResult: ExecutionResult,\n apiKey: string,\n adapter: LLMAdapter,\n attempt: number,\n): Promise<ExecutionResult> {\n const annotate = (entry: FilePlanEntry): FilePlanEntry => {\n const target = targets.get(entry.path);\n if (target === undefined) return entry;\n return {\n ...entry,\n description:\n `${entry.description} — REPAIR: the previous transformation of this file does not compile. ` +\n `Fix these exact compiler errors: ${target.errors.map(formatCompileError).join('; ')}`,\n };\n };\n const crossFileContext = await collectRepairContext(\n manifest,\n plan,\n targets,\n executionResult.outputDir,\n );\n const repairPlan: MigrationPlan = {\n ...plan,\n summary: `${plan.summary}\\n\\nREPAIR PASS ${attempt}: a previous transformation produced code that fails to compile. Re-transform the listed files, fixing the compiler errors given per file.${crossFileContext}`,\n filesToModify: plan.filesToModify.filter((f) => targets.has(f.path)).map(annotate),\n filesToCreate: plan.filesToCreate.filter((f) => targets.has(f.path)).map(annotate),\n filesToDelete: [],\n };\n return executeMigration(manifest, repairPlan, apiKey, () => {}, {\n adapter,\n outputDir: executionResult.outputDir,\n checkpointPath: `${executionResult.checkpointPath}.compile-repair-${attempt}`,\n });\n}\n\n/**\n * Parses pass/fail counts from test runner output. Handles the common\n * formats of jest, vitest, pytest, and cargo (\"N passed\", \"M failed\").\n * Returns null when no counts are present (e.g. go's package-level output).\n */\nexport function parseTestOutput(output: string): { passed: number; failed: number } | null {\n // Jest prints \"Test Suites: 1 failed, ...\" and vitest \"Test Files 1 failed ...\"\n // BEFORE the per-test summary line — prefer the line starting with \"Tests\"\n // so suite/file counts don't masquerade as test counts.\n const testsLine = output.split('\\n').find((line) => /^\\s*Tests[:\\s]/.test(line));\n const source = testsLine ?? output;\n const passedMatch = /(\\d+)\\s+pass(?:ed|ing)?/i.exec(source);\n const failedMatch = /(\\d+)\\s+fail(?:ed|ing)?/i.exec(source);\n if (passedMatch === null && failedMatch === null) return null;\n return {\n passed: passedMatch === null ? 0 : Number(passedMatch[1]),\n failed: failedMatch === null ? 0 : Number(failedMatch[1]),\n };\n}\n\n/**\n * Heuristic fallback when the model omits an issue category: dependency and\n * module-resolution failures are environment issues, not conversion errors\n * (spike finding 1 — TS2307/TS2591-class errors are setup, not quality).\n */\nexport function categorizeIssue(description: string): IssueCategory {\n const environmentPattern =\n /cannot find module|module not found|TS2307|TS2591|not installed|missing dependenc|ERR_MODULE_NOT_FOUND|command not found|ENOENT|types? package/i;\n return environmentPattern.test(description) ? 'environment' : 'conversion';\n}\n\nasync function runTests(\n setup: TestSetup,\n migratedDir: string,\n runCommand: CommandRunner,\n): Promise<{ testPassRate: number; testOutput: string }> {\n const result = await runCommand(setup.testCommand[0], setup.testCommand[1], migratedDir);\n const testOutput = `${result.stdout}\\n${result.stderr}`.trim();\n const counts = parseTestOutput(testOutput);\n if (counts === null || counts.passed + counts.failed === 0) {\n // No parseable counts — fall back to the exit code.\n return { testPassRate: result.exitCode === 0 ? 1 : 0, testOutput };\n }\n return { testPassRate: counts.passed / (counts.passed + counts.failed), testOutput };\n}\n\nasync function repairFailedFiles(\n manifest: CodebaseManifest,\n plan: MigrationPlan,\n failedFiles: string[],\n executionResult: ExecutionResult,\n apiKey: string,\n adapter: LLMAdapter,\n attempt: number,\n): Promise<ExecutionResult> {\n // failedFiles are keyed on the SOURCE path (entry.plan.path), matching the\n // plan entries' identity; execution resolves the output path per entry.\n const failedSet = new Set(failedFiles);\n const repairPlan: MigrationPlan = {\n ...plan,\n filesToModify: plan.filesToModify.filter((f) => failedSet.has(f.path)),\n filesToCreate: plan.filesToCreate.filter((f) => failedSet.has(f.path)),\n filesToDelete: [],\n };\n return executeMigration(manifest, repairPlan, apiKey, () => {}, {\n adapter,\n outputDir: executionResult.outputDir,\n checkpointPath: `${executionResult.checkpointPath}.repair-${attempt}`,\n });\n}\n\nasync function selfReview(\n originalDir: string,\n migratedDir: string,\n plan: MigrationPlan,\n testOutput: string,\n adapter: LLMAdapter,\n maxReviewFiles: number,\n): Promise<{ confidenceScore: number; issues: FlaggedIssue[] }> {\n const samples = await readReviewSamples(originalDir, migratedDir, plan, maxReviewFiles);\n const { from, to, type } = plan.migrationTarget;\n\n const systemPrompt = [\n `You are a senior software engineer reviewing a completed ${type} migration from \"${from}\" to \"${to}\".`,\n 'Review the migration for missed cases, type errors, and breaking changes. Rate your confidence that the migration is correct from 0.0 to 1.0.',\n 'Categorise every issue: \"environment\" for setup/dependency problems (missing packages, module resolution), \"conversion\" for real migration errors.',\n 'Respond with a single raw JSON object and nothing else:',\n '{ \"confidenceScore\": number, \"issues\": [{ \"description\": string, \"severity\": \"low\" | \"medium\" | \"high\", \"category\": \"environment\" | \"conversion\", \"affectedFiles\": string[] }] }',\n ].join('\\n');\n\n const userPrompt = [\n `Migration plan summary:\\n${plan.summary}`,\n '',\n `Test run output (excerpt):\\n${testOutput.slice(-TEST_OUTPUT_EXCERPT_CHARS) || '(no test suite detected)'}`,\n '',\n `Sampled file pairs (${samples.length} of the migrated files):`,\n ...samples.map(\n (s) =>\n `<original_file path=\"${s.path}\">\\n${s.original}\\n</original_file>\\n` +\n `<migrated_file path=\"${s.outputPath}\">\\n${s.migrated}\\n</migrated_file>`,\n ),\n ].join('\\n');\n\n const response = await adapter.complete({\n systemPrompt,\n userPrompt,\n maxTokens: VERIFICATION_MAX_OUTPUT_TOKENS,\n });\n return parseReviewResponse(response.text);\n}\n\nfunction parseReviewResponse(text: string): { confidenceScore: number; issues: FlaggedIssue[] } {\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start === -1 || end <= start) return unparseableReview();\n let raw: unknown;\n try {\n raw = JSON.parse(text.slice(start, end + 1));\n } catch {\n return unparseableReview();\n }\n if (typeof raw !== 'object' || raw === null) return unparseableReview();\n const obj = raw as Record<string, unknown>;\n\n const confidenceScore =\n typeof obj.confidenceScore === 'number' && Number.isFinite(obj.confidenceScore)\n ? Math.min(1, Math.max(0, obj.confidenceScore))\n : 0;\n\n const issues: FlaggedIssue[] = [];\n if (Array.isArray(obj.issues)) {\n for (const item of obj.issues) {\n if (typeof item !== 'object' || item === null) continue;\n const record = item as Record<string, unknown>;\n if (typeof record.description !== 'string' || record.description === '') continue;\n const severity = record.severity;\n const category = record.category;\n issues.push({\n description: record.description,\n severity:\n severity === 'low' || severity === 'medium' || severity === 'high' ? severity : 'medium',\n category:\n category === 'environment' || category === 'conversion'\n ? category\n : categorizeIssue(record.description),\n affectedFiles: Array.isArray(record.affectedFiles)\n ? record.affectedFiles.filter((f): f is string => typeof f === 'string')\n : [],\n });\n }\n }\n return { confidenceScore, issues };\n}\n\nfunction unparseableReview(): { confidenceScore: number; issues: FlaggedIssue[] } {\n // Degrade gracefully — a broken review response should not kill Pass 3.\n return {\n confidenceScore: 0,\n issues: [\n {\n description: 'Self-review response could not be parsed; manual review recommended.',\n severity: 'medium',\n category: 'environment',\n affectedFiles: [],\n },\n ],\n };\n}\n\ninterface ReviewSample {\n /** Source path (in originalDir). */\n path: string;\n /** Output path (in migratedDir) — differs from path for renames. */\n outputPath: string;\n original: string;\n migrated: string;\n}\n\nasync function readReviewSamples(\n originalDir: string,\n migratedDir: string,\n plan: MigrationPlan,\n maxFiles: number,\n): Promise<ReviewSample[]> {\n const rank: Record<ChangeComplexity, number> = { high: 0, medium: 1, low: 2 };\n const candidates: FilePlanEntry[] = [...plan.filesToModify].sort(\n (a, b) => rank[a.complexity] - rank[b.complexity],\n );\n const samples: ReviewSample[] = [];\n for (const entry of candidates) {\n if (samples.length >= maxFiles) break;\n const outputPath = planOutputPath(entry);\n const migrated = await readOptional(path.join(migratedDir, outputPath));\n if (migrated === null) continue;\n const original = await readOptional(path.join(originalDir, entry.path));\n samples.push({ path: entry.path, outputPath, original: original ?? '(new file)', migrated });\n }\n return samples;\n}\n\nasync function computeDiffStats(\n originalDir: string,\n migratedDir: string,\n plan: MigrationPlan,\n): Promise<DiffStats> {\n // Pair original(source path) ↔ migrated(output path) so renamed files\n // produce a real diff instead of an invisible one.\n const pairs = [\n ...plan.filesToModify.map((f) => ({ source: f.path, output: planOutputPath(f) })),\n ...plan.filesToCreate.map((f) => ({ source: f.path, output: f.path })),\n ];\n const stats: FileDiffStat[] = [];\n for (const pair of pairs) {\n const migrated = await readOptional(path.join(migratedDir, pair.output));\n if (migrated === null) continue;\n const original = (await readOptional(path.join(originalDir, pair.source))) ?? '';\n let linesAdded = 0;\n let linesRemoved = 0;\n for (const part of diffLines(original, migrated)) {\n if (part.added) linesAdded += part.count ?? 0;\n else if (part.removed) linesRemoved += part.count ?? 0;\n }\n if (linesAdded + linesRemoved > 0) stats.push({ path: pair.output, linesAdded, linesRemoved });\n }\n return {\n totalFilesChanged: stats.length,\n linesAdded: stats.reduce((sum, s) => sum + s.linesAdded, 0),\n linesRemoved: stats.reduce((sum, s) => sum + s.linesRemoved, 0),\n largestDiffs: [...stats]\n .sort((a, b) => b.linesAdded + b.linesRemoved - (a.linesAdded + a.linesRemoved))\n .slice(0, 5),\n };\n}\n\nfunction defaultCommandRunner(timeoutMs = 10 * 60 * 1000): CommandRunner {\n return (command, args, cwd) =>\n new Promise((resolve) => {\n const child = spawn(command, args, { cwd, shell: false });\n let stdout = '';\n let stderr = '';\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n stderr += `\\n(command timed out after ${timeoutMs}ms)`;\n }, timeoutMs);\n child.stdout.on('data', (data: Buffer) => (stdout += data.toString()));\n child.stderr.on('data', (data: Buffer) => (stderr += data.toString()));\n child.on('error', (error) => {\n clearTimeout(timer);\n resolve({ exitCode: 127, stdout, stderr: `${stderr}\\n${String(error)}` });\n });\n child.on('close', (code) => {\n clearTimeout(timer);\n resolve({ exitCode: code ?? 1, stdout, stderr });\n });\n });\n}\n\nasync function readOptional(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n}\n\nasync function exists(filePath: string): Promise<boolean> {\n try {\n await fs.stat(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n// --- HTML report ---\n\n/**\n * Renders the verification report as a single self-contained HTML document\n * (inline CSS, no external requests) suitable for download or sharing.\n */\nexport function generateHtmlReport(\n report: VerificationReport,\n plan: MigrationPlan,\n result: ExecutionResult,\n): string {\n const { from, to, type } = plan.migrationTarget;\n const passRateText =\n report.testPassRate === null ? 'No tests found' : `${Math.round(report.testPassRate * 100)}%`;\n const compileCheck = report.compileCheck;\n const compileCardText =\n compileCheck === undefined || !compileCheck.ran\n ? 'Skipped'\n : compileCheck.ok\n ? '✓ Passed'\n : `✗ ${compileCheck.errors.length} error(s)`;\n const compileSection =\n compileCheck === undefined || !compileCheck.ran\n ? `<p class=\"muted\">Skipped — ${esc(compileCheck?.skippedReason ?? 'not available in this report')}. Objective verification was unavailable; review manually.</p>`\n : compileCheck.ok\n ? '<p>✓ The migrated output compiles cleanly.</p>'\n : `<p><span class=\"badge high\">high</span> The migrated output does NOT compile.</p>` +\n `<pre>${esc(compileCheck.errors.map(formatCompileError).join('\\n'))}</pre>`;\n const environmentIssues = report.flaggedIssues.filter((i) => i.category === 'environment');\n const conversionIssues = report.flaggedIssues.filter((i) => i.category === 'conversion');\n\n const issueList = (issues: FlaggedIssue[]): string =>\n issues.length === 0\n ? '<p class=\"muted\">None</p>'\n : `<ul>${issues\n .map(\n (i) =>\n `<li><span class=\"badge ${esc(i.severity)}\">${esc(i.severity)}</span> ${esc(i.description)}` +\n (i.affectedFiles.length > 0\n ? ` <span class=\"muted\">(${i.affectedFiles.map(esc).join(', ')})</span>`\n : '') +\n '</li>',\n )\n .join('')}</ul>`;\n\n const diffRows = report.diffStats.largestDiffs\n .map(\n (d) =>\n `<tr><td><code>${esc(d.path)}</code></td><td class=\"add\">+${d.linesAdded}</td><td class=\"del\">-${d.linesRemoved}</td></tr>`,\n )\n .join('');\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>AutoMigrate Report — ${esc(from)} to ${esc(to)}</title>\n<style>\n body { font-family: -apple-system, 'Segoe UI', Roboto, sans-serif; margin: 0; background: #f7f7f8; color: #1a1a1a; }\n .wrap { max-width: 880px; margin: 0 auto; padding: 32px 24px; }\n h1 { font-size: 24px; margin-bottom: 4px; }\n h2 { font-size: 17px; margin-top: 32px; border-bottom: 1px solid #e2e2e6; padding-bottom: 6px; }\n .muted { color: #6b6b76; }\n .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-top: 20px; }\n .card { background: #fff; border: 1px solid #e2e2e6; border-radius: 8px; padding: 14px; }\n .card .value { font-size: 22px; font-weight: 700; }\n .card .label { font-size: 12px; color: #6b6b76; margin-top: 2px; }\n .badge { display: inline-block; font-size: 11px; font-weight: 600; padding: 1px 8px; border-radius: 999px; margin-right: 6px; text-transform: uppercase; }\n .badge.low { background: #e6f4ea; color: #137333; }\n .badge.medium { background: #fef7e0; color: #b06000; }\n .badge.high { background: #fce8e6; color: #c5221f; }\n pre { background: #16161a; color: #e8e8ed; padding: 14px; border-radius: 8px; overflow-x: auto; font-size: 12px; white-space: pre-wrap; }\n table { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid #e2e2e6; border-radius: 8px; }\n th, td { text-align: left; padding: 8px 12px; border-bottom: 1px solid #ececf0; font-size: 13px; }\n .add { color: #137333; } .del { color: #c5221f; }\n code { font-size: 12px; }\n</style>\n</head>\n<body>\n<div class=\"wrap\">\n <h1>AutoMigrate Verification Report</h1>\n <p class=\"muted\">${esc(type)} migration: <strong>${esc(from)}</strong> → <strong>${esc(to)}</strong> · generated ${esc(report.reportGeneratedAt)}</p>\n\n <div class=\"cards\">\n <div class=\"card\"><div class=\"value\">${result.filesModified + result.filesCreated}</div><div class=\"label\">Files changed</div></div>\n <div class=\"card\"><div class=\"value add\">+${report.diffStats.linesAdded}</div><div class=\"label\">Lines added</div></div>\n <div class=\"card\"><div class=\"value del\">-${report.diffStats.linesRemoved}</div><div class=\"label\">Lines removed</div></div>\n <div class=\"card\"><div class=\"value\">${esc(passRateText)}</div><div class=\"label\">Test pass rate</div></div>\n <div class=\"card\"><div class=\"value\">${esc(compileCardText)}</div><div class=\"label\">Compile check</div></div>\n <div class=\"card\"><div class=\"value\">${Math.round(report.confidenceScore * 100)}%</div><div class=\"label\">Model confidence</div></div>\n <div class=\"card\"><div class=\"value\">${result.tokensUsed.toLocaleString('en-US')}</div><div class=\"label\">Tokens used</div></div>\n </div>\n\n <h2>Migration summary</h2>\n <p>${esc(plan.summary)}</p>\n\n <h2>Compile check</h2>\n ${compileSection}\n\n <h2>Conversion issues (${conversionIssues.length})</h2>\n ${issueList(conversionIssues)}\n\n <h2>Environment setup items (${environmentIssues.length})</h2>\n <p class=\"muted\">Dependency or setup tasks — not migration errors.</p>\n ${issueList(environmentIssues)}\n\n <h2>Largest diffs</h2>\n ${diffRows === '' ? '<p class=\"muted\">No diffs computed.</p>' : `<table><tr><th>File</th><th>Added</th><th>Removed</th></tr>${diffRows}</table>`}\n\n <h2>Test output${report.testCommand === null ? '' : ` — <code>${esc(report.testCommand)}</code>`}</h2>\n ${report.selfRepairAttempts > 0 ? `<p class=\"muted\">Self-repair attempts: ${report.selfRepairAttempts}</p>` : ''}\n <pre>${esc(report.testOutput.slice(-5000) || '(no test suite detected)')}</pre>\n</div>\n</body>\n</html>`;\n}\n\nfunction esc(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;');\n}\n","/**\n * Migration orchestrator — composes the full 3-pass pipeline behind a single\n * entry point so consumers (the API worker, future CLI/extension refactors)\n * don't have to wire ingestion → planning → execution → verification by hand.\n *\n * Token usage is captured through a wrapping adapter that counts every\n * `complete()` call across ALL passes — including the verification self-repair\n * loop, whose tokens are deliberately not reflected in\n * `ExecutionResult.tokensUsed`. This is the number billing (Prompt 10) relies\n * on, so it must be the aggregate, not a per-pass slice.\n */\nimport { readCodebase, type IngestionOptions } from '../ingestion/index.js';\nimport {\n AnthropicAdapter,\n type LLMAdapter,\n type LLMRequest,\n type LLMResponse,\n} from '../llm/index.js';\nimport { planMigration, type MigrationPlan } from '../planning/index.js';\nimport { executeMigration, type ExecutionResult } from '../execution/index.js';\nimport { verifyMigration, type VerificationReport } from '../verification/index.js';\nimport type { MigrationTarget } from '../types.js';\n\n/** API list price per 1,000,000 tokens, by model. */\nconst MODEL_PRICING: Record<string, { input: number; output: number }> = {\n 'claude-sonnet-4-6': { input: 3, output: 15 },\n 'claude-opus-4-8': { input: 15, output: 75 },\n};\nconst DEFAULT_PRICING = MODEL_PRICING['claude-opus-4-8']!;\n\n/** Dollar cost of a request given token counts and the model that served it. */\nexport function modelCostUsd(inputTokens: number, outputTokens: number, model?: string): number {\n const pricing = (model !== undefined ? MODEL_PRICING[model] : undefined) ?? DEFAULT_PRICING;\n const cost = (inputTokens * pricing.input + outputTokens * pricing.output) / 1_000_000;\n return Math.round(cost * 10_000) / 10_000;\n}\n\nexport type OrchestratorStage = 'ingesting' | 'planning' | 'executing' | 'verifying' | 'complete';\n\nexport interface OrchestratorProgressEvent {\n stage: OrchestratorStage;\n /** Overall completion across all passes, 0–100. */\n percent: number;\n message: string;\n filesComplete?: number;\n filesTotal?: number;\n tokensUsed?: number;\n}\n\nexport interface OrchestratorUsage {\n inputTokens: number;\n outputTokens: number;\n /** The model that served the most recent request. */\n model: string;\n costUsd: number;\n}\n\nexport interface OrchestratorResult {\n plan: MigrationPlan;\n executionResult: ExecutionResult;\n report: VerificationReport;\n outputDir: string;\n usage: OrchestratorUsage;\n}\n\nexport interface MigrationOrchestratorOptions {\n apiKey: string;\n /** Override the model adapter for every pass (tests / model routing). */\n adapter?: LLMAdapter;\n ingestion?: IngestionOptions;\n /** Where transformed files are written. Default: <rootPath>/migrated. */\n outputDir?: string;\n checkpointPath?: string;\n}\n\nexport interface RunMigrationInput {\n rootPath: string;\n target: MigrationTarget;\n onProgress?: (event: OrchestratorProgressEvent) => void;\n}\n\n/** Wraps an adapter and accumulates token usage across every call. */\nclass UsageTrackingAdapter implements LLMAdapter {\n inputTokens = 0;\n outputTokens = 0;\n lastModel: string;\n private readonly inner: LLMAdapter;\n\n constructor(inner: LLMAdapter) {\n this.inner = inner;\n this.lastModel = inner.model;\n }\n\n get model(): string {\n return this.inner.model;\n }\n\n async complete(request: LLMRequest): Promise<LLMResponse> {\n const response = await this.inner.complete(request);\n this.inputTokens += response.inputTokens;\n this.outputTokens += response.outputTokens;\n this.lastModel = response.model;\n return response;\n }\n}\n\nexport class MigrationOrchestrator {\n private readonly options: MigrationOrchestratorOptions;\n\n constructor(options: MigrationOrchestratorOptions) {\n this.options = options;\n }\n\n async run(input: RunMigrationInput): Promise<OrchestratorResult> {\n const { rootPath, target, onProgress } = input;\n const baseAdapter =\n this.options.adapter ?? new AnthropicAdapter({ apiKey: this.options.apiKey });\n const tracker = new UsageTrackingAdapter(baseAdapter);\n const usage = (): OrchestratorUsage => ({\n inputTokens: tracker.inputTokens,\n outputTokens: tracker.outputTokens,\n model: tracker.lastModel,\n costUsd: modelCostUsd(tracker.inputTokens, tracker.outputTokens, tracker.lastModel),\n });\n\n onProgress?.({ stage: 'ingesting', percent: 0, message: 'Reading codebase…' });\n const manifest = await readCodebase(rootPath, this.options.ingestion ?? {});\n\n onProgress?.({\n stage: 'planning',\n percent: 10,\n message: 'Planning migration…',\n tokensUsed: usage().inputTokens + usage().outputTokens,\n });\n const plan = await planMigration(manifest, target, this.options.apiKey, {\n adapter: tracker,\n });\n\n const execOptions = {\n adapter: tracker,\n ...(this.options.outputDir !== undefined ? { outputDir: this.options.outputDir } : {}),\n ...(this.options.checkpointPath !== undefined\n ? { checkpointPath: this.options.checkpointPath }\n : {}),\n };\n const executionResult = await executeMigration(\n manifest,\n plan,\n this.options.apiKey,\n (progress) => {\n // Execution spans the 30–80% band of overall progress.\n const fraction = progress.filesTotal > 0 ? progress.filesComplete / progress.filesTotal : 0;\n onProgress?.({\n stage: 'executing',\n percent: 30 + Math.round(fraction * 50),\n message: progress.currentFile\n ? `Transforming ${progress.currentFile}`\n : 'Transforming files…',\n filesComplete: progress.filesComplete,\n filesTotal: progress.filesTotal,\n tokensUsed: progress.tokensUsed,\n });\n },\n execOptions,\n );\n\n onProgress?.({\n stage: 'verifying',\n percent: 80,\n message: 'Running tests and self-review…',\n tokensUsed: usage().inputTokens + usage().outputTokens,\n });\n const report = await verifyMigration(\n rootPath,\n executionResult.outputDir,\n plan,\n executionResult,\n this.options.apiKey,\n { adapter: tracker, manifest },\n );\n\n onProgress?.({\n stage: 'complete',\n percent: 100,\n message: 'Migration complete.',\n tokensUsed: usage().inputTokens + usage().outputTokens,\n });\n\n return {\n plan,\n executionResult,\n report,\n outputDir: executionResult.outputDir,\n usage: usage(),\n };\n }\n}\n","/**\n * Migration target registry: maps the CLI's `<from>-to-<to>` target strings\n * to engine MigrationTarget objects and suggests targets from a detected stack.\n */\nimport type { MigrationTarget, StackInfo } from '@automigrate/engine';\n\nexport const KNOWN_TARGETS: Record<string, MigrationTarget> = {\n 'javascript-to-typescript': { from: 'javascript', to: 'typescript', type: 'language' },\n 'flow-to-typescript': { from: 'flow', to: 'typescript', type: 'language' },\n 'python-2-to-3': { from: 'python 2', to: 'python 3', type: 'language' },\n 'react-17-to-19': { from: 'react 17', to: 'react 19', type: 'framework' },\n 'express-to-hono': { from: 'express', to: 'hono', type: 'framework' },\n 'vue-2-to-3': { from: 'vue 2', to: 'vue 3', type: 'framework' },\n};\n\nconst LANGUAGES = new Set([\n 'javascript',\n 'typescript',\n 'flow',\n 'python',\n 'go',\n 'rust',\n 'dart',\n 'php',\n 'ruby',\n 'java',\n]);\n\n/**\n * Parses a target string: known targets map directly; anything else must be\n * `<from>-to-<to>` and is treated as a language migration when both sides\n * are languages, a framework migration otherwise.\n */\nexport function parseTarget(value: string): MigrationTarget {\n const known = KNOWN_TARGETS[value];\n if (known !== undefined) return known;\n\n const separator = value.indexOf('-to-');\n if (separator <= 0 || separator + 4 >= value.length) {\n throw new Error(\n `Invalid migration target \"${value}\". Use <from>-to-<to>, e.g. javascript-to-typescript.`,\n );\n }\n const from = value.slice(0, separator);\n const to = value.slice(separator + 4);\n return {\n from,\n to,\n type: LANGUAGES.has(from) && LANGUAGES.has(to) ? 'language' : 'framework',\n };\n}\n\n/** Suggests migration targets for a detected stack, most relevant first. */\nexport function suggestTargets(stack: StackInfo): string[] {\n const suggestions: string[] = [];\n if (stack.primaryLanguage === 'javascript') suggestions.push('javascript-to-typescript');\n if (stack.frameworks.includes('react')) suggestions.push('react-17-to-19');\n if (stack.frameworks.includes('express')) suggestions.push('express-to-hono');\n if (stack.frameworks.includes('vue')) suggestions.push('vue-2-to-3');\n return suggestions;\n}\n","/**\n * `automigrate rollback` — restore originals from the pre-migration backup,\n * remove files the migration created (planned creations and rename targets,\n * in case the user applied output.patch), and remove the /migrated directory\n * and the patch artifact. Returns the tree to its pre-migration state.\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport { backupDir, readJobs, saveJob } from '../state.js';\nimport { removeDir, restoreBackup } from '../workspace.js';\n\nexport interface RollbackCommandOptions {\n job?: string;\n}\n\nexport async function rollbackCommand(options: RollbackCommandOptions): Promise<void> {\n const jobs = await readJobs();\n const job =\n options.job !== undefined\n ? jobs.find((j) => j.id === options.job)\n : [...jobs].reverse().find((j) => j.status === 'complete' || j.status === 'failed');\n\n if (job === undefined) {\n console.error(\n chalk.red(\n options.job !== undefined ? `Job ${options.job} not found.` : 'No job to roll back.',\n ),\n );\n process.exitCode = 1;\n return;\n }\n\n const restored = await restoreBackup(backupDir(job.id), job.rootPath);\n // Remove files that exist only post-migration: creations and rename\n // targets (a rename is delete source + create target — the source comes\n // back from the backup above, the target must go). No-ops when the user\n // never applied the patch.\n let removed = 0;\n for (const created of job.createdFiles ?? []) {\n try {\n await fs.rm(path.join(job.rootPath, created));\n removed++;\n } catch {\n // Already absent — the patch was never applied for this file.\n }\n }\n await removeDir(path.join(job.rootPath, 'migrated'));\n await fs.rm(path.join(job.rootPath, 'output.patch'), { force: true });\n\n job.status = 'rolled_back';\n await saveJob(job);\n\n console.log(\n `${chalk.green('Rolled back')} job ${job.id}: restored ${restored} files` +\n `${removed > 0 ? `, removed ${removed} created files` : ''}, removed ${path.join(job.rootPath, 'migrated')}`,\n );\n if (restored === 0 && removed === 0) {\n console.log(\n chalk.dim('No files needed restoring (the migration never modified originals in place).'),\n );\n }\n}\n","/**\n * File operations around a migration run: pre-migration backup, rollback\n * restore, and completing the /migrated directory with unchanged files\n * (the engine writes only transformed files; the CLI delivers the full\n * transformed codebase).\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { planOutputPath, type CodebaseManifest, type MigrationPlan } from '@automigrate/engine';\n\n/** Copies the given files (relative to rootPath) into destDir. Missing files are skipped. */\nexport async function backupFiles(\n rootPath: string,\n relPaths: string[],\n destDir: string,\n): Promise<number> {\n let count = 0;\n for (const rel of relPaths) {\n let content: Buffer;\n try {\n content = Buffer.from(await fs.readFile(path.join(rootPath, rel)));\n } catch {\n continue;\n }\n const target = path.join(destDir, rel);\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.writeFile(target, content);\n count++;\n }\n return count;\n}\n\n/** Restores every file under backupRoot back into rootPath. Returns files restored. */\nexport async function restoreBackup(backupRoot: string, rootPath: string): Promise<number> {\n let count = 0;\n async function walk(dir: string): Promise<void> {\n let entries;\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const abs = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n await walk(abs);\n continue;\n }\n if (!entry.isFile()) continue;\n const rel = path.relative(backupRoot, abs);\n const target = path.join(rootPath, rel);\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.writeFile(target, Buffer.from(await fs.readFile(abs)));\n count++;\n }\n }\n await walk(backupRoot);\n return count;\n}\n\n/**\n * Files that must NOT be copied into the output dir when completing it:\n * planned deletions, and rename sources — a rename's content lives at its\n * outputPath, so copying the source would leave a stale duplicate (low.js\n * next to low.ts) in the migrated output.\n */\nexport function copyExclusions(plan: MigrationPlan): Set<string> {\n const exclude = new Set(plan.filesToDelete);\n for (const entry of plan.filesToModify) {\n if (planOutputPath(entry) !== entry.path) exclude.add(entry.path);\n }\n return exclude;\n}\n\n/**\n * Copies manifest files into outputDir unless they are excluded (planned\n * deletions, rename sources — see copyExclusions) or already present\n * (written by the engine). This turns the engine's transformed-files-only\n * output into the full migrated codebase.\n */\nexport async function copyUnchangedFiles(\n manifest: CodebaseManifest,\n outputDir: string,\n exclude: Set<string>,\n): Promise<number> {\n let count = 0;\n for (const file of manifest.files) {\n if (exclude.has(file.relativePath)) continue;\n const target = path.join(outputDir, file.relativePath);\n if (await exists(target)) continue;\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.writeFile(target, file.content, 'utf8');\n count++;\n }\n return count;\n}\n\nexport async function removeDir(dirPath: string): Promise<void> {\n await fs.rm(dirPath, { recursive: true, force: true });\n}\n\nasync function exists(filePath: string): Promise<boolean> {\n try {\n await fs.stat(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * `automigrate run` — the full 3-pass migration: plan, execute, verify.\n * Produces output.patch + a complete /migrated directory, never touching\n * the original files. --dry-run stops after planning; --resume continues\n * a failed run from its checkpoint.\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport cliProgress from 'cli-progress';\nimport ora from 'ora';\nimport {\n type CodebaseManifest,\n ExecutionError,\n type ExecutionCheckpoint,\n type ExecutionResult,\n executeMigration,\n type MigrationPlan,\n planMigration,\n planOutputPath,\n readCodebase,\n resumeMigration,\n type VerificationReport,\n verifyMigration,\n} from '@automigrate/engine';\nimport { buildIdentity } from '../buildInfo.js';\nimport { buildPatch, collectPatchEntries } from '../patch.js';\nimport {\n acquireLock,\n backupDir,\n checkpointPath,\n type JobRecord,\n newJobId,\n readConfig,\n readJobs,\n releaseLock,\n saveJob,\n} from '../state.js';\nimport { parseTarget } from '../targets.js';\nimport { backupFiles, copyExclusions, copyUnchangedFiles } from '../workspace.js';\n\nexport interface RunCommandOptions {\n target?: string;\n dryRun?: boolean;\n resume?: boolean;\n}\n\ninterface ProjectConfig {\n target?: string;\n ignorePaths?: string[];\n}\n\nexport async function runCommand(options: RunCommandOptions): Promise<void> {\n // Always identify the executing build first: verification behavior differs\n // across builds, and output that doesn't name its build can't be trusted\n // to reflect the current code (Hotfix D).\n console.log(chalk.dim(buildIdentity()));\n const rootPath = process.cwd();\n const config = await readConfig();\n const apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY;\n if (apiKey === undefined || apiKey === '') {\n console.error(\n chalk.red('No API key configured.') +\n ' Run `automigrate config set-key <key>` or set ANTHROPIC_API_KEY.',\n );\n process.exitCode = 1;\n return;\n }\n\n const projectConfig = await readProjectConfig(rootPath);\n const targetSpec = options.target ?? projectConfig?.target;\n if (targetSpec === undefined || targetSpec === '') {\n console.error(\n chalk.red('No migration target.') +\n ' Pass --target <from-to> or run `automigrate init` first.',\n );\n process.exitCode = 1;\n return;\n }\n const target = parseTarget(targetSpec);\n\n const ingestSpinner = ora('Reading codebase…').start();\n const manifest = await readCodebase(rootPath, {\n ignorePaths: [...(config.ignorePaths ?? []), ...(projectConfig?.ignorePaths ?? []), 'migrated'],\n });\n ingestSpinner.succeed(\n `Read ${manifest.files.length} files (${manifest.totalLines.toLocaleString('en-US')} lines, ~${manifest.totalTokens.toLocaleString('en-US')} tokens)`,\n );\n\n if (options.resume === true) {\n await resumeRun(rootPath, manifest, apiKey, targetSpec);\n return;\n }\n\n // Pass 1 — planning.\n const planSpinner = ora('Planning migration (Pass 1)…').start();\n const plan = await planMigration(manifest, target, apiKey, {\n onProgress: (p) => {\n planSpinner.text = `Planning migration (Pass 1)… batch ${p.batchIndex + 1}/${p.batchCount}, ${p.charsStreamed.toLocaleString('en-US')} chars`;\n },\n });\n planSpinner.succeed(\n `Plan ready: ${plan.filesToModify.length} to modify, ${plan.filesToCreate.length} to create, ${plan.filesToDelete.length} to delete (risk: ${plan.riskLevel}, effort: ${plan.estimatedEffort})`,\n );\n\n if (options.dryRun === true) {\n printPlan(plan);\n return;\n }\n\n const jobId = newJobId();\n const job: JobRecord = {\n id: jobId,\n createdAt: new Date().toISOString(),\n rootPath,\n target: targetSpec,\n status: 'executing',\n filesChanged: 0,\n linesAdded: 0,\n linesRemoved: 0,\n tokensUsed: 0,\n testPassRate: null,\n confidenceScore: null,\n };\n\n await acquireLock(rootPath);\n try {\n // Back up every file the plan will touch, for one-command rollback.\n const affected = [...plan.filesToModify.map((f) => f.path), ...plan.filesToDelete];\n const backed = await backupFiles(rootPath, affected, backupDir(jobId));\n console.log(chalk.dim(`Backed up ${backed} files to ${backupDir(jobId)}`));\n await saveJob(job);\n\n // Pass 2 — execution.\n const result = await runExecutionWithProgress(() =>\n executeMigration(manifest, plan, apiKey, progressBarCallback(), {\n outputDir: path.join(rootPath, 'migrated'),\n checkpointPath: checkpointPath(jobId),\n }),\n );\n\n await finishRun(rootPath, manifest, plan, result, apiKey, job);\n } catch (error) {\n job.status = 'failed';\n job.error = error instanceof Error ? error.message : String(error);\n await saveJob(job);\n if (error instanceof ExecutionError) {\n console.error(chalk.red(`\\n${error.message}`));\n console.error(chalk.yellow('Resume with: automigrate run --resume'));\n } else {\n console.error(chalk.red(`\\nMigration failed: ${job.error}`));\n }\n process.exitCode = 1;\n } finally {\n await releaseLock(rootPath);\n }\n}\n\nasync function resumeRun(\n rootPath: string,\n manifest: CodebaseManifest,\n apiKey: string,\n targetSpec: string,\n): Promise<void> {\n const jobs = await readJobs();\n const job = [...jobs].reverse().find((j) => j.rootPath === rootPath && j.status === 'failed');\n if (job === undefined) {\n console.error(chalk.red('No failed migration found for this directory to resume.'));\n process.exitCode = 1;\n return;\n }\n const ckptPath = checkpointPath(job.id);\n let checkpoint: ExecutionCheckpoint;\n try {\n checkpoint = JSON.parse(await fs.readFile(ckptPath, 'utf8')) as ExecutionCheckpoint;\n } catch {\n console.error(chalk.red(`Checkpoint for job ${job.id} not found or unreadable (${ckptPath}).`));\n process.exitCode = 1;\n return;\n }\n\n console.log(chalk.dim(`Resuming job ${job.id} (${job.target || targetSpec})`));\n job.status = 'executing';\n await acquireLock(rootPath);\n try {\n await saveJob(job);\n const result = await runExecutionWithProgress(() =>\n resumeMigration(ckptPath, manifest, apiKey, progressBarCallback()),\n );\n await finishRun(rootPath, manifest, checkpoint.plan, result, apiKey, job);\n } catch (error) {\n job.status = 'failed';\n job.error = error instanceof Error ? error.message : String(error);\n await saveJob(job);\n console.error(chalk.red(`\\nResume failed: ${job.error}`));\n if (error instanceof ExecutionError) {\n console.error(chalk.yellow('You can resume again with: automigrate run --resume'));\n }\n process.exitCode = 1;\n } finally {\n await releaseLock(rootPath);\n }\n}\n\n/** Shared post-execution steps: complete /migrated, verify, patch, summary. */\nasync function finishRun(\n rootPath: string,\n manifest: CodebaseManifest,\n plan: MigrationPlan,\n result: ExecutionResult,\n apiKey: string,\n job: JobRecord,\n): Promise<void> {\n const migratedDir = result.outputDir;\n\n // The engine writes only transformed files — fill in the rest so /migrated\n // holds the full transformed codebase (planned deletions and rename\n // sources stay absent).\n const copied = await copyUnchangedFiles(manifest, migratedDir, copyExclusions(plan));\n console.log(chalk.dim(`Copied ${copied} unchanged files into ${migratedDir}`));\n\n // Pass 3 — verification (manifest enables the self-repair loop).\n const verifySpinner = ora('Verifying migration (Pass 3)…').start();\n const report = await verifyMigration(rootPath, migratedDir, plan, result, apiKey, { manifest });\n verifySpinner.succeed('Verification complete');\n\n // output.patch — unified diff of all changes, applicable with git apply.\n const patchEntries = await collectPatchEntries(manifest, plan, migratedDir);\n const patchPath = path.join(rootPath, 'output.patch');\n await fs.writeFile(patchPath, buildPatch(patchEntries), 'utf8');\n\n job.status = 'complete';\n // Files that exist only after the migration is applied — planned creations\n // and rename targets — so rollback can remove them from the working tree.\n job.createdFiles = [\n ...plan.filesToModify.filter((f) => planOutputPath(f) !== f.path).map(planOutputPath),\n ...plan.filesToCreate.map((f) => f.path),\n ];\n job.filesChanged = result.filesModified + result.filesCreated + result.filesDeleted;\n job.linesAdded = report.diffStats.linesAdded;\n job.linesRemoved = report.diffStats.linesRemoved;\n job.tokensUsed = result.tokensUsed;\n job.testPassRate = report.testPassRate;\n job.confidenceScore = report.confidenceScore;\n await saveJob(job);\n\n printSummary(report, result, patchPath, migratedDir, job.id);\n}\n\nfunction progressBarCallback(): Parameters<typeof executeMigration>[3] {\n const bar = new cliProgress.SingleBar(\n {\n format: `Transforming (Pass 2) ${chalk.cyan('{bar}')} {value}/{total} files · {tokens} tokens · {file}`,\n hideCursor: true,\n },\n cliProgress.Presets.shades_classic,\n );\n let started = false;\n return (progress) => {\n if (!started && progress.filesTotal > 0) {\n bar.start(progress.filesTotal, 0, { tokens: 0, file: '' });\n started = true;\n }\n bar.update(progress.filesComplete, {\n tokens: progress.tokensUsed.toLocaleString('en-US'),\n file: progress.currentFile ?? '',\n });\n if (progress.stage === 'complete' || progress.stage === 'failed') bar.stop();\n };\n}\n\nasync function runExecutionWithProgress(\n run: () => Promise<ExecutionResult>,\n): Promise<ExecutionResult> {\n const result = await run();\n console.log(\n chalk.green(\n `Transformed ${result.filesModified + result.filesCreated} files (${result.tokensUsed.toLocaleString('en-US')} tokens)`,\n ),\n );\n return result;\n}\n\nfunction printPlan(plan: MigrationPlan): void {\n console.log(`\\n${chalk.bold('Migration plan (dry run)')}`);\n console.log(plan.summary);\n console.log(\n `\\nRisk: ${riskColor(plan.riskLevel)} Effort: ${chalk.bold(plan.estimatedEffort)} Est. tokens: ${plan.tokenBudgetEstimate.toLocaleString('en-US')}`,\n );\n if (plan.filesToModify.length > 0) {\n console.log(`\\n${chalk.bold('Files to modify:')}`);\n for (const f of plan.filesToModify) {\n const rename = planOutputPath(f) !== f.path ? chalk.cyan(` → ${planOutputPath(f)}`) : '';\n console.log(\n ` ${complexityBadge(f.complexity)} ${f.path}${rename} ${chalk.dim(f.description)}`,\n );\n }\n }\n if (plan.filesToCreate.length > 0) {\n console.log(`\\n${chalk.bold('Files to create:')}`);\n for (const f of plan.filesToCreate) console.log(` ${chalk.green('+')} ${f.path}`);\n }\n if (plan.filesToDelete.length > 0) {\n console.log(`\\n${chalk.bold('Files to delete:')}`);\n for (const f of plan.filesToDelete) console.log(` ${chalk.red('-')} ${f}`);\n }\n if (plan.dependencyChanges.length > 0) {\n console.log(`\\n${chalk.bold('Dependency changes:')}`);\n for (const d of plan.dependencyChanges) {\n console.log(\n ` ${d.action} ${d.name} ${chalk.dim(`${d.currentVersion ?? ''} → ${d.targetVersion ?? ''}`)}`,\n );\n }\n }\n if (plan.breakingChanges.length > 0) {\n console.log(`\\n${chalk.bold('Breaking changes flagged:')}`);\n for (const b of plan.breakingChanges) {\n console.log(` ${complexityBadge(b.severity)} ${b.description}`);\n }\n }\n console.log(chalk.dim('\\nRun without --dry-run to execute this plan.'));\n}\n\n/**\n * Exported for tests: the summary must ALWAYS contain a \"Compile check:\"\n * line — ✓ passed / ✗ N error(s) / skipped (reason) — including when the\n * check could not run or the report predates the field. A missing line is\n * indistinguishable from the feature being absent (Hotfix D).\n */\nexport function printSummary(\n report: VerificationReport,\n result: ExecutionResult,\n patchPath: string,\n migratedDir: string,\n jobId: string,\n): void {\n const passRate =\n report.testPassRate === null\n ? chalk.dim('no tests found')\n : report.testPassRate >= 0.9\n ? chalk.green(`${Math.round(report.testPassRate * 100)}%`)\n : chalk.red(`${Math.round(report.testPassRate * 100)}%`);\n const conversionIssues = report.flaggedIssues.filter((i) => i.category === 'conversion');\n const environmentIssues = report.flaggedIssues.filter((i) => i.category === 'environment');\n const compile = report.compileCheck;\n const compileLine =\n compile === undefined || !compile.ran\n ? chalk.yellow(`skipped (${compile?.skippedReason ?? 'not available'})`)\n : compile.ok\n ? chalk.green('✓ passed')\n : chalk.red(\n `✗ ${compile.errors.length} error(s) (${[...new Set(compile.errors.map((e) => e.file).filter((f) => f !== ''))].join(', ')})`,\n );\n\n console.log(`\\n${chalk.bold('Migration complete')} ${chalk.dim(`(job ${jobId})`)}`);\n console.log(\n ` Files changed: ${chalk.bold(String(result.filesModified + result.filesCreated + result.filesDeleted))} ` +\n `${chalk.green(`+${report.diffStats.linesAdded}`)} ${chalk.red(`-${report.diffStats.linesRemoved}`)}`,\n );\n console.log(` Compile check: ${compileLine}`);\n console.log(\n ` Test pass rate: ${passRate} Confidence: ${Math.round(report.confidenceScore * 100)}%`,\n );\n if (compile !== undefined && compile.ran && !compile.ok) {\n console.log(\n chalk.red.bold('\\n ⚠ The migrated output does NOT compile.') +\n chalk.red(' Review the errors above before applying output.patch.'),\n );\n }\n if (report.selfRepairAttempts > 0) {\n console.log(` Self-repair attempts: ${report.selfRepairAttempts}`);\n }\n if (result.failedFiles.length > 0) {\n console.log(\n chalk.red(` Failed files (${result.failedFiles.length}): ${result.failedFiles.join(', ')}`),\n );\n }\n if (conversionIssues.length > 0) {\n console.log(`\\n ${chalk.bold('Conversion issues:')}`);\n for (const issue of conversionIssues) {\n console.log(` ${complexityBadge(issue.severity)} ${issue.description}`);\n }\n }\n if (environmentIssues.length > 0) {\n console.log(chalk.dim(` Environment setup items: ${environmentIssues.length} (see report)`));\n }\n console.log(`\\n Review: ${chalk.cyan(patchPath)} (apply with: git apply output.patch)`);\n console.log(` Output: ${chalk.cyan(migratedDir)}`);\n console.log(` Rollback: ${chalk.cyan(`automigrate rollback --job ${jobId}`)}\\n`);\n}\n\nfunction riskColor(risk: 'low' | 'medium' | 'high'): string {\n if (risk === 'low') return chalk.green(risk);\n if (risk === 'medium') return chalk.yellow(risk);\n return chalk.red(risk);\n}\n\nfunction complexityBadge(level: 'low' | 'medium' | 'high'): string {\n if (level === 'low') return chalk.green('●');\n if (level === 'medium') return chalk.yellow('●');\n return chalk.red('●');\n}\n\nasync function readProjectConfig(rootPath: string): Promise<ProjectConfig | null> {\n try {\n return JSON.parse(\n await fs.readFile(path.join(rootPath, 'automigrate.config.json'), 'utf8'),\n ) as ProjectConfig;\n } catch {\n return null;\n }\n}\n","/**\n * Build identity for the running CLI artifact. Every `automigrate run`\n * prints this so output is always attributable to a specific build —\n * a binary that predates a feature is otherwise indistinguishable from\n * one where the feature silently skipped (Hotfix D: a stale global\n * install ran an entire migration with no compile check and no way to\n * tell from the output).\n *\n * The values are injected by tsup at bundle time (see tsup.config.ts);\n * the fallbacks mean a source run (tsx/vitest) identifies itself as such\n * rather than masquerading as a packaged release.\n */\nexport const CLI_VERSION: string = process.env.AUTOMIGRATE_CLI_VERSION ?? 'dev';\nexport const CLI_BUILD_ID: string = process.env.AUTOMIGRATE_CLI_BUILD_ID ?? 'unpackaged';\n\nexport function buildIdentity(): string {\n return `automigrate v${CLI_VERSION} (build ${CLI_BUILD_ID})`;\n}\n","/**\n * Generates a single git-apply-compatible unified diff covering every\n * modified, created, deleted, and renamed file in a migration.\n *\n * A rename serializes as DELETE old + CREATE new (the canonical rename\n * semantics shared with rollback and the extension). We deliberately do not\n * emit `rename from`/`rename to` headers: our existing /dev/null create and\n * delete sections are already proven against `git apply`, while rename\n * headers require similarity metadata and hunks against the old blob —\n * strictly more fragile for an identical on-disk result.\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { structuredPatch } from 'diff';\nimport { planOutputPath, type CodebaseManifest, type MigrationPlan } from '@automigrate/engine';\n\nexport interface PatchEntry {\n /** Output path — where the content ends up. */\n path: string;\n /**\n * Source path when it differs from `path` — the entry is a rename and\n * serializes as delete(oldPath) + create(path).\n */\n oldPath?: string;\n /** null = file is being created. */\n oldContent: string | null;\n /** null = file is being deleted. */\n newContent: string | null;\n}\n\nexport function buildPatch(entries: PatchEntry[]): string {\n let output = '';\n for (const entry of normalizeEntries(entries)) {\n const oldName = entry.oldContent === null ? '/dev/null' : `a/${entry.path}`;\n const newName = entry.newContent === null ? '/dev/null' : `b/${entry.path}`;\n const patch = structuredPatch(\n oldName,\n newName,\n entry.oldContent ?? '',\n entry.newContent ?? '',\n undefined,\n undefined,\n { context: 3 },\n );\n if (patch.hunks.length === 0) continue;\n\n output += `diff --git a/${entry.path} b/${entry.path}\\n`;\n if (entry.oldContent === null) output += 'new file mode 100644\\n';\n if (entry.newContent === null) output += 'deleted file mode 100644\\n';\n output += `--- ${oldName}\\n+++ ${newName}\\n`;\n for (const hunk of patch.hunks) {\n output += `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@\\n`;\n output += `${hunk.lines.join('\\n')}\\n`;\n }\n }\n return output;\n}\n\n/** Expands rename entries into the delete + create pair they serialize as. */\nfunction normalizeEntries(\n entries: PatchEntry[],\n): { path: string; oldContent: string | null; newContent: string | null }[] {\n const normalized: { path: string; oldContent: string | null; newContent: string | null }[] = [];\n for (const entry of entries) {\n if (entry.oldPath === undefined || entry.oldPath === entry.path) {\n normalized.push({\n path: entry.path,\n oldContent: entry.oldContent,\n newContent: entry.newContent,\n });\n continue;\n }\n if (entry.oldContent !== null) {\n normalized.push({ path: entry.oldPath, oldContent: entry.oldContent, newContent: null });\n }\n if (entry.newContent !== null) {\n normalized.push({ path: entry.path, oldContent: null, newContent: entry.newContent });\n }\n }\n return normalized;\n}\n\n/**\n * Collects patch entries for a completed migration by pairing the plan\n * against the migrated output dir. Renames read the new content from\n * planOutputPath(entry) and carry oldPath so buildPatch emits the\n * delete + create pair. Files the engine failed to write are skipped\n * (their originals stay out of the patch).\n */\nexport async function collectPatchEntries(\n manifest: CodebaseManifest,\n plan: MigrationPlan,\n migratedDir: string,\n): Promise<PatchEntry[]> {\n const originals = new Map(manifest.files.map((f) => [f.relativePath, f.content]));\n const entries: PatchEntry[] = [];\n for (const file of plan.filesToModify) {\n const outputPath = planOutputPath(file);\n const newContent = await readOptional(path.join(migratedDir, outputPath));\n if (newContent === null) continue; // failed file — keep original out of the patch\n entries.push({\n path: outputPath,\n ...(outputPath !== file.path ? { oldPath: file.path } : {}),\n oldContent: originals.get(file.path) ?? null,\n newContent,\n });\n }\n for (const file of plan.filesToCreate) {\n const newContent = await readOptional(path.join(migratedDir, file.path));\n if (newContent === null) continue;\n entries.push({ path: file.path, oldContent: null, newContent });\n }\n for (const filePath of plan.filesToDelete) {\n const oldContent = originals.get(filePath);\n if (oldContent === undefined) continue;\n entries.push({ path: filePath, oldContent, newContent: null });\n }\n return entries;\n}\n\nasync function readOptional(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n}\n","export default class Diff {\n diff(oldStr, newStr, \n // Type below is not accurate/complete - see above for full possibilities - but it compiles\n options = {}) {\n let callback;\n if (typeof options === 'function') {\n callback = options;\n options = {};\n }\n else if ('callback' in options) {\n callback = options.callback;\n }\n // Allow subclasses to massage the input prior to running\n const oldString = this.castInput(oldStr, options);\n const newString = this.castInput(newStr, options);\n const oldTokens = this.removeEmpty(this.tokenize(oldString, options));\n const newTokens = this.removeEmpty(this.tokenize(newString, options));\n return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);\n }\n diffWithOptionsObj(oldTokens, newTokens, options, callback) {\n var _a;\n const done = (value) => {\n value = this.postProcess(value, options);\n if (callback) {\n setTimeout(function () { callback(value); }, 0);\n return undefined;\n }\n else {\n return value;\n }\n };\n const newLen = newTokens.length, oldLen = oldTokens.length;\n let editLength = 1;\n let maxEditLength = newLen + oldLen;\n if (options.maxEditLength != null) {\n maxEditLength = Math.min(maxEditLength, options.maxEditLength);\n }\n const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;\n const abortAfterTimestamp = Date.now() + maxExecutionTime;\n const bestPath = [{ oldPos: -1, lastComponent: undefined }];\n // Seed editLength = 0, i.e. the content starts with the same values\n let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);\n if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n // Identity per the equality and tokenizer\n return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));\n }\n // Once we hit the right edge of the edit graph on some diagonal k, we can\n // definitely reach the end of the edit graph in no more than k edits, so\n // there's no point in considering any moves to diagonal k+1 any more (from\n // which we're guaranteed to need at least k+1 more edits).\n // Similarly, once we've reached the bottom of the edit graph, there's no\n // point considering moves to lower diagonals.\n // We record this fact by setting minDiagonalToConsider and\n // maxDiagonalToConsider to some finite value once we've hit the edge of\n // the edit graph.\n // This optimization is not faithful to the original algorithm presented in\n // Myers's paper, which instead pointlessly extends D-paths off the end of\n // the edit graph - see page 7 of Myers's paper which notes this point\n // explicitly and illustrates it with a diagram. This has major performance\n // implications for some common scenarios. For instance, to compute a diff\n // where the new text simply appends d characters on the end of the\n // original text of length n, the true Myers algorithm will take O(n+d^2)\n // time while this optimization needs only O(n+d) time.\n let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;\n // Main worker method. checks all permutations of a given edit length for acceptance.\n const execEditLength = () => {\n for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {\n let basePath;\n const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];\n if (removePath) {\n // No one else is going to attempt to use this value, clear it\n // @ts-expect-error - perf optimisation. This type-violating value will never be read.\n bestPath[diagonalPath - 1] = undefined;\n }\n let canAdd = false;\n if (addPath) {\n // what newPos will be after we do an insertion:\n const addPathNewPos = addPath.oldPos - diagonalPath;\n canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;\n }\n const canRemove = removePath && removePath.oldPos + 1 < oldLen;\n if (!canAdd && !canRemove) {\n // If this path is a terminal then prune\n // @ts-expect-error - perf optimisation. This type-violating value will never be read.\n bestPath[diagonalPath] = undefined;\n continue;\n }\n // Select the diagonal that we want to branch from. We select the prior\n // path whose position in the old string is the farthest from the origin\n // and does not pass the bounds of the diff graph\n if (!canRemove || (canAdd && removePath.oldPos < addPath.oldPos)) {\n basePath = this.addToPath(addPath, true, false, 0, options);\n }\n else {\n basePath = this.addToPath(removePath, false, true, 1, options);\n }\n newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);\n if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n // If we have hit the end of both strings, then we are done\n return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;\n }\n else {\n bestPath[diagonalPath] = basePath;\n if (basePath.oldPos + 1 >= oldLen) {\n maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);\n }\n if (newPos + 1 >= newLen) {\n minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);\n }\n }\n }\n editLength++;\n };\n // Performs the length of edit iteration. Is a bit fugly as this has to support the\n // sync and async mode which is never fun. Loops over execEditLength until a value\n // is produced, or until the edit length exceeds options.maxEditLength (if given),\n // in which case it will return undefined.\n if (callback) {\n (function exec() {\n setTimeout(function () {\n if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {\n return callback(undefined);\n }\n if (!execEditLength()) {\n exec();\n }\n }, 0);\n }());\n }\n else {\n while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {\n const ret = execEditLength();\n if (ret) {\n return ret;\n }\n }\n }\n }\n addToPath(path, added, removed, oldPosInc, options) {\n const last = path.lastComponent;\n if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {\n return {\n oldPos: path.oldPos + oldPosInc,\n lastComponent: { count: last.count + 1, added: added, removed: removed, previousComponent: last.previousComponent }\n };\n }\n else {\n return {\n oldPos: path.oldPos + oldPosInc,\n lastComponent: { count: 1, added: added, removed: removed, previousComponent: last }\n };\n }\n }\n extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {\n const newLen = newTokens.length, oldLen = oldTokens.length;\n let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;\n while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {\n newPos++;\n oldPos++;\n commonCount++;\n if (options.oneChangePerToken) {\n basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };\n }\n }\n if (commonCount && !options.oneChangePerToken) {\n basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };\n }\n basePath.oldPos = oldPos;\n return newPos;\n }\n equals(left, right, options) {\n if (options.comparator) {\n return options.comparator(left, right);\n }\n else {\n return left === right\n || (!!options.ignoreCase && left.toLowerCase() === right.toLowerCase());\n }\n }\n removeEmpty(array) {\n const ret = [];\n for (let i = 0; i < array.length; i++) {\n if (array[i]) {\n ret.push(array[i]);\n }\n }\n return ret;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n castInput(value, options) {\n return value;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n tokenize(value, options) {\n return Array.from(value);\n }\n join(chars) {\n // Assumes ValueT is string, which is the case for most subclasses.\n // When it's false, e.g. in diffArrays, this method needs to be overridden (e.g. with a no-op)\n // Yes, the casts are verbose and ugly, because this pattern - of having the base class SORT OF\n // assume tokens and values are strings, but not completely - is weird and janky.\n return chars.join('');\n }\n postProcess(changeObjects, \n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n options) {\n return changeObjects;\n }\n get useLongestToken() {\n return false;\n }\n buildValues(lastComponent, newTokens, oldTokens) {\n // First we convert our linked list of components in reverse order to an\n // array in the right order:\n const components = [];\n let nextComponent;\n while (lastComponent) {\n components.push(lastComponent);\n nextComponent = lastComponent.previousComponent;\n delete lastComponent.previousComponent;\n lastComponent = nextComponent;\n }\n components.reverse();\n const componentLen = components.length;\n let componentPos = 0, newPos = 0, oldPos = 0;\n for (; componentPos < componentLen; componentPos++) {\n const component = components[componentPos];\n if (!component.removed) {\n if (!component.added && this.useLongestToken) {\n let value = newTokens.slice(newPos, newPos + component.count);\n value = value.map(function (value, i) {\n const oldValue = oldTokens[oldPos + i];\n return oldValue.length > value.length ? oldValue : value;\n });\n component.value = this.join(value);\n }\n else {\n component.value = this.join(newTokens.slice(newPos, newPos + component.count));\n }\n newPos += component.count;\n // Common case\n if (!component.added) {\n oldPos += component.count;\n }\n }\n else {\n component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));\n oldPos += component.count;\n }\n }\n return components;\n }\n}\n","import Diff from './base.js';\nimport { generateOptions } from '../util/params.js';\nclass LineDiff extends Diff {\n constructor() {\n super(...arguments);\n this.tokenize = tokenize;\n }\n equals(left, right, options) {\n // If we're ignoring whitespace, we need to normalise lines by stripping\n // whitespace before checking equality. (This has an annoying interaction\n // with newlineIsToken that requires special handling: if newlines get their\n // own token, then we DON'T want to trim the *newline* tokens down to empty\n // strings, since this would cause us to treat whitespace-only line content\n // as equal to a separator between lines, which would be weird and\n // inconsistent with the documented behavior of the options.)\n if (options.ignoreWhitespace) {\n if (!options.newlineIsToken || !left.includes('\\n')) {\n left = left.trim();\n }\n if (!options.newlineIsToken || !right.includes('\\n')) {\n right = right.trim();\n }\n }\n else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {\n if (left.endsWith('\\n')) {\n left = left.slice(0, -1);\n }\n if (right.endsWith('\\n')) {\n right = right.slice(0, -1);\n }\n }\n return super.equals(left, right, options);\n }\n}\nexport const lineDiff = new LineDiff();\nexport function diffLines(oldStr, newStr, options) {\n return lineDiff.diff(oldStr, newStr, options);\n}\nexport function diffTrimmedLines(oldStr, newStr, options) {\n options = generateOptions(options, { ignoreWhitespace: true });\n return lineDiff.diff(oldStr, newStr, options);\n}\n// Exported standalone so it can be used from jsonDiff too.\nexport function tokenize(value, options) {\n if (options.stripTrailingCr) {\n // remove one \\r before \\n to match GNU diff's --strip-trailing-cr behavior\n value = value.replace(/\\r\\n/g, '\\n');\n }\n const retLines = [], linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n // Ignore the final empty token that occurs if the string ends with a new line\n if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n linesAndNewlines.pop();\n }\n // Merge the content and line separators into single tokens\n for (let i = 0; i < linesAndNewlines.length; i++) {\n const line = linesAndNewlines[i];\n if (i % 2 && !options.newlineIsToken) {\n retLines[retLines.length - 1] += line;\n }\n else {\n retLines.push(line);\n }\n }\n return retLines;\n}\n","import { diffLines } from '../diff/line.js';\nexport const INCLUDE_HEADERS = {\n includeIndex: true,\n includeUnderline: true,\n includeFileHeaders: true\n};\nexport const FILE_HEADERS_ONLY = {\n includeIndex: false,\n includeUnderline: false,\n includeFileHeaders: true\n};\nexport const OMIT_HEADERS = {\n includeIndex: false,\n includeUnderline: false,\n includeFileHeaders: false\n};\nexport function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {\n let optionsObj;\n if (!options) {\n optionsObj = {};\n }\n else if (typeof options === 'function') {\n optionsObj = { callback: options };\n }\n else {\n optionsObj = options;\n }\n if (typeof optionsObj.context === 'undefined') {\n optionsObj.context = 4;\n }\n // We copy this into its own variable to placate TypeScript, which thinks\n // optionsObj.context might be undefined in the callbacks below.\n const context = optionsObj.context;\n // @ts-expect-error (runtime check for something that is correctly a static type error)\n if (optionsObj.newlineIsToken) {\n throw new Error('newlineIsToken may not be used with patch-generation functions, only with diffing functions');\n }\n if (!optionsObj.callback) {\n return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));\n }\n else {\n const { callback } = optionsObj;\n diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {\n const patch = diffLinesResultToPatch(diff);\n // TypeScript is unhappy without the cast because it does not understand that `patch` may\n // be undefined here only if `callback` is StructuredPatchCallbackAbortable:\n callback(patch);\n } }));\n }\n function diffLinesResultToPatch(diff) {\n // STEP 1: Build up the patch with no \"\\" lines and with the arrays\n // of lines containing trailing newline characters. We'll tidy up later...\n if (!diff) {\n return;\n }\n diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier\n function contextLines(lines) {\n return lines.map(function (entry) { return ' ' + entry; });\n }\n const hunks = [];\n let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;\n for (let i = 0; i < diff.length; i++) {\n const current = diff[i], lines = current.lines || splitLines(current.value);\n current.lines = lines;\n if (current.added || current.removed) {\n // If we have previous context, start with that\n if (!oldRangeStart) {\n const prev = diff[i - 1];\n oldRangeStart = oldLine;\n newRangeStart = newLine;\n if (prev) {\n curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];\n oldRangeStart -= curRange.length;\n newRangeStart -= curRange.length;\n }\n }\n // Output our changes\n for (const line of lines) {\n curRange.push((current.added ? '+' : '-') + line);\n }\n // Track the updated file position\n if (current.added) {\n newLine += lines.length;\n }\n else {\n oldLine += lines.length;\n }\n }\n else {\n // Identical context lines. Track line changes\n if (oldRangeStart) {\n // Close out any changes that have been output (or join overlapping)\n if (lines.length <= context * 2 && i < diff.length - 2) {\n // Overlapping\n for (const line of contextLines(lines)) {\n curRange.push(line);\n }\n }\n else {\n // end the range and output\n const contextSize = Math.min(lines.length, context);\n for (const line of contextLines(lines.slice(0, contextSize))) {\n curRange.push(line);\n }\n const hunk = {\n oldStart: oldRangeStart,\n oldLines: (oldLine - oldRangeStart + contextSize),\n newStart: newRangeStart,\n newLines: (newLine - newRangeStart + contextSize),\n lines: curRange\n };\n hunks.push(hunk);\n oldRangeStart = 0;\n newRangeStart = 0;\n curRange = [];\n }\n }\n oldLine += lines.length;\n newLine += lines.length;\n }\n }\n // Step 2: eliminate the trailing `\\n` from each line of each hunk, and, where needed, add\n // \"\\".\n for (const hunk of hunks) {\n for (let i = 0; i < hunk.lines.length; i++) {\n if (hunk.lines[i].endsWith('\\n')) {\n hunk.lines[i] = hunk.lines[i].slice(0, -1);\n }\n else {\n hunk.lines.splice(i + 1, 0, '\\\');\n i++; // Skip the line we just added, then continue iterating\n }\n }\n }\n return {\n oldFileName: oldFileName, newFileName: newFileName,\n oldHeader: oldHeader, newHeader: newHeader,\n hunks: hunks\n };\n }\n}\n/**\n * creates a unified diff patch.\n * @param patch either a single structured patch object (as returned by `structuredPatch`) or an array of them (as returned by `parsePatch`)\n */\nexport function formatPatch(patch, headerOptions) {\n if (!headerOptions) {\n headerOptions = INCLUDE_HEADERS;\n }\n if (Array.isArray(patch)) {\n if (patch.length > 1 && !headerOptions.includeFileHeaders) {\n throw new Error('Cannot omit file headers on a multi-file patch. '\n + '(The result would be unparseable; how would a tool trying to apply '\n + 'the patch know which changes are to which file?)');\n }\n return patch.map(p => formatPatch(p, headerOptions)).join('\\n');\n }\n const ret = [];\n if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName) {\n ret.push('Index: ' + patch.oldFileName);\n }\n if (headerOptions.includeUnderline) {\n ret.push('===================================================================');\n }\n if (headerOptions.includeFileHeaders) {\n ret.push('--- ' + patch.oldFileName + (typeof patch.oldHeader === 'undefined' ? '' : '\\t' + patch.oldHeader));\n ret.push('+++ ' + patch.newFileName + (typeof patch.newHeader === 'undefined' ? '' : '\\t' + patch.newHeader));\n }\n for (let i = 0; i < patch.hunks.length; i++) {\n const hunk = patch.hunks[i];\n // Unified Diff Format quirk: If the chunk size is 0,\n // the first number is one lower than one would expect.\n // https://www.artima.com/weblogs/viewpost.jsp?thread=164293\n if (hunk.oldLines === 0) {\n hunk.oldStart -= 1;\n }\n if (hunk.newLines === 0) {\n hunk.newStart -= 1;\n }\n ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines\n + ' +' + hunk.newStart + ',' + hunk.newLines\n + ' @@');\n for (const line of hunk.lines) {\n ret.push(line);\n }\n }\n return ret.join('\\n') + '\\n';\n}\nexport function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {\n if (typeof options === 'function') {\n options = { callback: options };\n }\n if (!(options === null || options === void 0 ? void 0 : options.callback)) {\n const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);\n if (!patchObj) {\n return;\n }\n return formatPatch(patchObj, options === null || options === void 0 ? void 0 : options.headerOptions);\n }\n else {\n const { callback } = options;\n structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: patchObj => {\n if (!patchObj) {\n callback(undefined);\n }\n else {\n callback(formatPatch(patchObj, options.headerOptions));\n }\n } }));\n }\n}\nexport function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) {\n return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options);\n}\n/**\n * Split `text` into an array of lines, including the trailing newline character (where present)\n */\nfunction splitLines(text) {\n const hasTrailingNl = text.endsWith('\\n');\n const result = text.split('\\n').map(line => line + '\\n');\n if (hasTrailingNl) {\n result.pop();\n }\n else {\n result.push(result.pop().slice(0, -1));\n }\n return result;\n}\n","/**\n * `automigrate status` — show the last 5 migration jobs on this machine.\n */\nimport chalk from 'chalk';\nimport type { MigrationStatus } from '@automigrate/engine';\nimport { readJobs } from '../state.js';\n\nexport async function statusCommand(): Promise<void> {\n const jobs = await readJobs();\n if (jobs.length === 0) {\n console.log(chalk.dim('No migrations recorded yet. Run `automigrate run` to start one.'));\n return;\n }\n\n console.log(chalk.bold(`Last ${Math.min(jobs.length, 5)} migration jobs:\\n`));\n for (const job of jobs.slice(-5).reverse()) {\n const date = job.createdAt.slice(0, 16).replace('T', ' ');\n const stats =\n job.status === 'complete'\n ? `${job.filesChanged} files ${chalk.green(`+${job.linesAdded}`)} ${chalk.red(`-${job.linesRemoved}`)}` +\n (job.testPassRate === null ? '' : ` tests ${Math.round(job.testPassRate * 100)}%`)\n : (job.error ?? '');\n console.log(` ${statusBadge(job.status)} ${chalk.bold(job.id)} ${date} ${job.target}`);\n console.log(` ${chalk.dim(job.rootPath)} ${stats}\\n`);\n }\n}\n\nfunction statusBadge(status: MigrationStatus): string {\n switch (status) {\n case 'complete':\n return chalk.green('✔');\n case 'failed':\n return chalk.red('✖');\n case 'rolled_back':\n return chalk.yellow('↩');\n default:\n return chalk.cyan('…');\n }\n}\n"],"mappings":"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","names":["path","config","config","fs","path","chalk","fs","path","ignore","pkg","chunk","fs","path","path","value","checkpointPath","path","fs","buildSystemPrompt","fs","path","runCommand","path","pkg","fs","chalk","path","fs","config","fs","path","chalk","fs","path","fs","path","exists","chalk","fs","path","fs","path","chalk","ora","fs","path","Diff","path","value","LineDiff","Diff","tokenize","lineDiff","diffLines","tokenize","diffLines","readOptional","path","fs","chalk","config","ora","path","fs","chalk","chalk"]}