cdx-chores 0.0.7
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.
- package/LICENSE +21 -0
- package/README.md +312 -0
- package/dist/cjs/index.cjs +9572 -0
- package/dist/esm/bin.mjs +9544 -0
- package/dist/esm/bin.mjs.map +1 -0
- package/dist/esm/index.d.mts +43 -0
- package/dist/esm/index.mjs +9536 -0
- package/dist/index.d.mts +14 -0
- package/dist/index.mjs +787 -0
- package/package.json +67 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.mjs","names":["toErrorMessage","toErrorMessage","toErrorMessage","escapeSqlString","quoteSqlIdentifier","createDuckDbConnection","normalizeHeader","DEFAULT_NON_TTY_WIDTH","DEFAULT_TTY_WIDTH","MAX_COLUMN_WIDTH","MIN_COLUMN_WIDTH","COLUMN_SEPARATOR","resolveRenderWidth","truncateCell","createSeparator","measureColumnWidth","resolveVisibleColumns","formatColumnSummary","renderTable","createDuckDbConnection","createDuckDbConnection","truncateForPrompt","createDuckDbConnection","parseYamlDocument","buildPrompt","suggestSingleBatch","normalizeExtensions","CLEANUP_HINT_VALUES","RENAME_PLAN_CSV_ARTIFACT_PATTERN","buildCleanupUidBasenames","isRenamePlanCsvArtifactName","CLEANUP_HINT_VALUES","createPromptAbortError","buildPromptLine","isPrintableInput","isPromptCancelError","quoteSqlIdentifier","createDuckDbConnection","resolvePath"],"sources":["../../src/utils/sleep.ts","../../src/adapters/codex/shared.ts","../../node_modules/picocolors/picocolors.js","../../src/cli/colors.ts","../../src/cli/errors.ts","../../src/cli/process.ts","../../src/cli/deps.ts","../../src/cli/duckdb/extensions.ts","../../src/cli/data-preview/normalize.ts","../../src/cli/duckdb/xlsx-sources.ts","../../src/cli/duckdb/query.ts","../../src/cli/rename-template.ts","../../src/utils/datetime.ts","../../src/utils/paths.ts","../../src/utils/slug.ts","../../src/cli/rename-uid.ts","../../src/cli/fs-utils.ts","../../src/cli/actions/shared.ts","../../src/cli/actions/doctor.ts","../../src/utils/csv.ts","../../src/cli/data-preview/source.ts","../../src/cli/data-preview/render.ts","../../src/cli/actions/data-preview.ts","../../src/cli/duckdb/parquet-preview.ts","../../src/cli/actions/data-parquet-preview.ts","../../src/cli/actions/data-duckdb.ts","../../src/cli/data-query/render.ts","../../src/cli/actions/data-query.ts","../../src/cli/interactive/analyzer-status.ts","../../src/cli/data-query/codex.ts","../../src/cli/actions/data-query-codex.ts","../../src/cli/actions/data.ts","../../src/markdown/toml/arrays.ts","../../src/markdown/toml/keys.ts","../../src/markdown/toml/strings.ts","../../src/markdown/toml/values.ts","../../src/markdown/toml/parse-frontmatter.ts","../../src/markdown/parse-markdown.ts","../../src/cli/actions/markdown.ts","../../src/cli/rename-plan-csv.ts","../../src/utils/append-all.ts","../../src/cli/rename-preview.ts","../../src/cli/actions/rename/reporting.ts","../../src/cli/actions/rename/apply.ts","../../src/cli/rename-interactive-router.ts","../../src/adapters/codex/document-rename-titles.ts","../../src/adapters/codex/image-rename-titles.ts","../../src/cli/actions/rename/codex.ts","../../src/cli/actions/rename/filters.ts","../../src/cli/actions/rename/plan-output.ts","../../src/cli/actions/rename/batch.ts","../../src/cli/actions/rename/cleanup-matchers.ts","../../src/cli/actions/rename/cleanup-planner.ts","../../src/cli/actions/rename/cleanup-target.ts","../../src/cli/actions/rename/cleanup.ts","../../src/cli/actions/rename/cleanup-analyzer.ts","../../src/cli/actions/rename/cleanup-analysis-csv.ts","../../src/cli/actions/rename/cleanup-codex.ts","../../src/cli/actions/rename/file.ts","../../src/cli/actions/video.ts","../../src/cli/prompts/path-config.ts","../../src/cli/tui/screen.ts","../../src/cli/tui/raw-session.ts","../../src/cli/tui/keys.ts","../../src/cli/prompts/path-inline-state.ts","../../src/cli/prompts/path-suggestions.ts","../../src/cli/prompts/path-sibling-preview.ts","../../src/cli/prompts/path-inline.ts","../../src/cli/prompts/path.ts","../../src/cli/interactive/data-query.ts","../../src/cli/interactive/shared.ts","../../src/cli/interactive/data.ts","../../src/cli/interactive/markdown.ts","../../src/cli/interactive/menu.ts","../../src/cli/prompts/text-template-candidates.ts","../../src/cli/prompts/text-inline.ts","../../src/cli/interactive/input-validation.ts","../../src/cli/interactive/rename-cleanup.ts","../../src/cli/interactive/rename.ts","../../src/cli/interactive/video.ts","../../src/cli/interactive/index.ts","../../src/cli/program/version-embedded.ts","../../src/cli/program/version.ts","../../src/command.ts","../../src/bin.ts"],"sourcesContent":["export async function sleep(ms: number): Promise<void> {\n if (ms <= 0) {\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { accessSync, constants, existsSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { Codex } from \"@openai/codex-sdk\";\n\nimport { sleep } from \"../../utils/sleep\";\n\nexport interface CodexEnvironmentInspection {\n authSessionAvailable: boolean;\n configuredSupport: boolean;\n detail?: string;\n}\n\nconst CODEX_PATH_OVERRIDE_ENV = \"CDX_CHORES_CODEX_PATH\";\n\nfunction resolveCodexHome(): string {\n const override = process.env.CODEX_HOME?.trim();\n if (override) {\n return override;\n }\n return join(homedir(), \".codex\");\n}\n\nexport function getCodexPathOverrideFromEnv(): string | undefined {\n const value = process.env[CODEX_PATH_OVERRIDE_ENV]?.trim();\n return value ? value : undefined;\n}\n\nfunction inspectCodexPathOverride(codexPathOverride: string): string | undefined {\n try {\n const stats = statSync(codexPathOverride);\n if (!stats.isFile()) {\n return `Codex override path is not a file: ${codexPathOverride}`;\n }\n accessSync(codexPathOverride, constants.X_OK);\n return undefined;\n } catch (error) {\n return `Codex override path is not executable: ${codexPathOverride} (${error instanceof Error ? error.message : String(error)})`;\n }\n}\n\nexport interface CodexFilenameTitleSuggestionResult<TSuggestion> {\n suggestions: TSuggestion[];\n errorMessage?: string;\n}\n\nexport const CODEX_FILENAME_TITLE_OUTPUT_SCHEMA = {\n type: \"object\",\n properties: {\n suggestions: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n filename: { type: \"string\" },\n title: { type: \"string\" },\n },\n required: [\"filename\", \"title\"],\n additionalProperties: false,\n },\n },\n },\n required: [\"suggestions\"],\n additionalProperties: false,\n} as const;\n\nexport function startCodexReadOnlyThread(\n workingDirectory: string,\n options: { codexPathOverride?: string } = {},\n) {\n const codexPathOverride = options.codexPathOverride ?? getCodexPathOverrideFromEnv();\n const codex = codexPathOverride ? new Codex({ codexPathOverride }) : new Codex();\n return codex.startThread({\n workingDirectory,\n sandboxMode: \"read-only\",\n approvalPolicy: \"never\",\n modelReasoningEffort: \"low\",\n networkAccessEnabled: true,\n webSearchMode: \"disabled\",\n });\n}\n\nexport function normalizeTitle(value: string): string {\n return value\n .replace(/[`\"'“”‘’]/g, \"\")\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function chunkItems<T>(items: T[], size: number): T[][] {\n if (size <= 0) {\n return [items];\n }\n const chunks: T[][] = [];\n for (let index = 0; index < items.length; index += size) {\n chunks.push(items.slice(index, index + size));\n }\n return chunks;\n}\n\nexport function parseFilenameTitleSuggestions(finalResponse: string): Map<string, string> {\n const parsed = JSON.parse(finalResponse) as {\n suggestions?: Array<{ filename?: string; title?: string }>;\n };\n\n const suggestionsByFilename = new Map<string, string>();\n for (const item of parsed.suggestions ?? []) {\n const filename = (item.filename ?? \"\").trim();\n const title = normalizeTitle((item.title ?? \"\").trim());\n if (!filename || !title) {\n continue;\n }\n suggestionsByFilename.set(filename, title);\n }\n\n return suggestionsByFilename;\n}\n\nfunction retryDelayMs(attempt: number): number {\n return 300 * (attempt + 1);\n}\n\nexport async function executeBatchesWithRetries<TBatch, TSuggestion>(options: {\n batches: TBatch[];\n retries: number;\n runBatch: (batch: TBatch) => Promise<CodexFilenameTitleSuggestionResult<TSuggestion>>;\n}): Promise<{ suggestions: TSuggestion[]; batchErrors: string[] }> {\n const suggestions: TSuggestion[] = [];\n const batchErrors: string[] = [];\n\n for (const batch of options.batches) {\n let batchResult: CodexFilenameTitleSuggestionResult<TSuggestion> | null = null;\n let lastError = \"\";\n\n for (let attempt = 0; attempt <= options.retries; attempt += 1) {\n try {\n batchResult = await options.runBatch(batch);\n lastError = batchResult.errorMessage ?? \"\";\n if (!batchResult.errorMessage) {\n break;\n }\n } catch (error) {\n lastError = error instanceof Error ? error.message : String(error);\n batchResult = { suggestions: [], errorMessage: lastError };\n }\n\n if (attempt < options.retries) {\n await sleep(retryDelayMs(attempt));\n }\n }\n\n if (batchResult?.suggestions?.length) {\n suggestions.push(...batchResult.suggestions);\n }\n if (lastError) {\n batchErrors.push(lastError);\n }\n }\n\n return { suggestions, batchErrors };\n}\n\nexport function summarizeBatchErrors(batchErrors: string[], hasSuggestions: boolean): string | undefined {\n if (batchErrors.length === 0) {\n return undefined;\n }\n const uniqueErrors = [...new Set(batchErrors)];\n return `${hasSuggestions ? \"Partial Codex suggestions.\" : \"Codex title generation failed.\"} ${uniqueErrors[0]}${uniqueErrors.length > 1 ? ` (+${uniqueErrors.length - 1} more error variant(s))` : \"\"}`;\n}\n\nexport async function inspectCodexEnvironment(): Promise<CodexEnvironmentInspection> {\n try {\n await import(\"@openai/codex-sdk\");\n } catch (error) {\n return {\n authSessionAvailable: false,\n configuredSupport: false,\n detail: error instanceof Error ? error.message : String(error),\n };\n }\n\n const codexPathOverride = getCodexPathOverrideFromEnv();\n const hasAuthSignal =\n Boolean(process.env.CODEX_API_KEY?.trim()) ||\n Boolean(process.env.OPENAI_API_KEY?.trim()) ||\n existsSync(join(resolveCodexHome(), \"auth.json\"));\n\n if (codexPathOverride) {\n const overrideProblem = inspectCodexPathOverride(codexPathOverride);\n if (overrideProblem) {\n return {\n authSessionAvailable: hasAuthSignal,\n configuredSupport: false,\n detail: overrideProblem,\n };\n }\n }\n\n if (!hasAuthSignal) {\n return {\n authSessionAvailable: false,\n configuredSupport: true,\n detail: \"No Codex auth/session signal found. Sign in to Codex or provide CODEX_API_KEY.\",\n };\n }\n\n return {\n authSessionAvailable: true,\n configuredSupport: true,\n };\n}\n","let p = process || {}, argv = p.argv || [], env = p.env || {}\nlet isColorSupported =\n\t!(!!env.NO_COLOR || argv.includes(\"--no-color\")) &&\n\t(!!env.FORCE_COLOR || argv.includes(\"--color\") || p.platform === \"win32\" || ((p.stdout || {}).isTTY && env.TERM !== \"dumb\") || !!env.CI)\n\nlet formatter = (open, close, replace = open) =>\n\tinput => {\n\t\tlet string = \"\" + input, index = string.indexOf(close, open.length)\n\t\treturn ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close\n\t}\n\nlet replaceClose = (string, close, replace, index) => {\n\tlet result = \"\", cursor = 0\n\tdo {\n\t\tresult += string.substring(cursor, index) + replace\n\t\tcursor = index + close.length\n\t\tindex = string.indexOf(close, cursor)\n\t} while (~index)\n\treturn result + string.substring(cursor)\n}\n\nlet createColors = (enabled = isColorSupported) => {\n\tlet f = enabled ? formatter : () => String\n\treturn {\n\t\tisColorSupported: enabled,\n\t\treset: f(\"\\x1b[0m\", \"\\x1b[0m\"),\n\t\tbold: f(\"\\x1b[1m\", \"\\x1b[22m\", \"\\x1b[22m\\x1b[1m\"),\n\t\tdim: f(\"\\x1b[2m\", \"\\x1b[22m\", \"\\x1b[22m\\x1b[2m\"),\n\t\titalic: f(\"\\x1b[3m\", \"\\x1b[23m\"),\n\t\tunderline: f(\"\\x1b[4m\", \"\\x1b[24m\"),\n\t\tinverse: f(\"\\x1b[7m\", \"\\x1b[27m\"),\n\t\thidden: f(\"\\x1b[8m\", \"\\x1b[28m\"),\n\t\tstrikethrough: f(\"\\x1b[9m\", \"\\x1b[29m\"),\n\n\t\tblack: f(\"\\x1b[30m\", \"\\x1b[39m\"),\n\t\tred: f(\"\\x1b[31m\", \"\\x1b[39m\"),\n\t\tgreen: f(\"\\x1b[32m\", \"\\x1b[39m\"),\n\t\tyellow: f(\"\\x1b[33m\", \"\\x1b[39m\"),\n\t\tblue: f(\"\\x1b[34m\", \"\\x1b[39m\"),\n\t\tmagenta: f(\"\\x1b[35m\", \"\\x1b[39m\"),\n\t\tcyan: f(\"\\x1b[36m\", \"\\x1b[39m\"),\n\t\twhite: f(\"\\x1b[37m\", \"\\x1b[39m\"),\n\t\tgray: f(\"\\x1b[90m\", \"\\x1b[39m\"),\n\n\t\tbgBlack: f(\"\\x1b[40m\", \"\\x1b[49m\"),\n\t\tbgRed: f(\"\\x1b[41m\", \"\\x1b[49m\"),\n\t\tbgGreen: f(\"\\x1b[42m\", \"\\x1b[49m\"),\n\t\tbgYellow: f(\"\\x1b[43m\", \"\\x1b[49m\"),\n\t\tbgBlue: f(\"\\x1b[44m\", \"\\x1b[49m\"),\n\t\tbgMagenta: f(\"\\x1b[45m\", \"\\x1b[49m\"),\n\t\tbgCyan: f(\"\\x1b[46m\", \"\\x1b[49m\"),\n\t\tbgWhite: f(\"\\x1b[47m\", \"\\x1b[49m\"),\n\n\t\tblackBright: f(\"\\x1b[90m\", \"\\x1b[39m\"),\n\t\tredBright: f(\"\\x1b[91m\", \"\\x1b[39m\"),\n\t\tgreenBright: f(\"\\x1b[92m\", \"\\x1b[39m\"),\n\t\tyellowBright: f(\"\\x1b[93m\", \"\\x1b[39m\"),\n\t\tblueBright: f(\"\\x1b[94m\", \"\\x1b[39m\"),\n\t\tmagentaBright: f(\"\\x1b[95m\", \"\\x1b[39m\"),\n\t\tcyanBright: f(\"\\x1b[96m\", \"\\x1b[39m\"),\n\t\twhiteBright: f(\"\\x1b[97m\", \"\\x1b[39m\"),\n\n\t\tbgBlackBright: f(\"\\x1b[100m\", \"\\x1b[49m\"),\n\t\tbgRedBright: f(\"\\x1b[101m\", \"\\x1b[49m\"),\n\t\tbgGreenBright: f(\"\\x1b[102m\", \"\\x1b[49m\"),\n\t\tbgYellowBright: f(\"\\x1b[103m\", \"\\x1b[49m\"),\n\t\tbgBlueBright: f(\"\\x1b[104m\", \"\\x1b[49m\"),\n\t\tbgMagentaBright: f(\"\\x1b[105m\", \"\\x1b[49m\"),\n\t\tbgCyanBright: f(\"\\x1b[106m\", \"\\x1b[49m\"),\n\t\tbgWhiteBright: f(\"\\x1b[107m\", \"\\x1b[49m\"),\n\t}\n}\n\nmodule.exports = createColors()\nmodule.exports.createColors = createColors\n","import { createColors } from \"picocolors\";\n\nimport type { CliRuntime } from \"./types\";\n\nexport function isNoColorEnvSet(env: NodeJS.ProcessEnv = process.env): boolean {\n return Object.prototype.hasOwnProperty.call(env, \"NO_COLOR\");\n}\n\nexport function resolveCliColorEnabled(options: {\n env?: NodeJS.ProcessEnv;\n noColorFlag?: boolean;\n} = {}): boolean {\n if (options.noColorFlag) {\n return false;\n }\n return !isNoColorEnvSet(options.env);\n}\n\nexport function getCliColors(runtime: CliRuntime) {\n const stream = runtime.stdout as NodeJS.WritableStream & { isTTY?: boolean };\n return createColors(runtime.colorEnabled && Boolean(stream.isTTY));\n}\n\nexport function getProcessColors(enabled = resolveCliColorEnabled()) {\n return createColors(enabled && Boolean(process.stdout.isTTY));\n}\n","export class CliError extends Error {\n readonly exitCode: number;\n readonly code: string;\n\n constructor(message: string, options: { exitCode?: number; code?: string } = {}) {\n super(message);\n this.name = \"CliError\";\n this.exitCode = options.exitCode ?? 1;\n this.code = options.code ?? \"CLI_ERROR\";\n }\n}\n\nexport function toCliError(error: unknown): CliError {\n if (error instanceof CliError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return new CliError(message);\n}\n\n","import { spawn } from \"node:child_process\";\n\nexport interface ExecCommandResult {\n ok: boolean;\n code: number | null;\n signal: NodeJS.Signals | null;\n stdout: string;\n stderr: string;\n}\n\nexport async function execCommand(\n command: string,\n args: string[],\n options: { cwd?: string } = {},\n): Promise<ExecCommandResult> {\n return await new Promise<ExecCommandResult>((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.setEncoding(\"utf8\");\n child.stderr.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk) => {\n stdout += chunk;\n });\n child.stderr.on(\"data\", (chunk) => {\n stderr += chunk;\n });\n\n child.on(\"error\", (error) => {\n reject(error);\n });\n\n child.on(\"close\", (code, signal) => {\n resolve({\n ok: code === 0,\n code,\n signal,\n stdout,\n stderr,\n });\n });\n });\n}\n\n","import { CliError } from \"./errors\";\nimport { execCommand } from \"./process\";\n\nexport interface CommandStatus {\n name: string;\n available: boolean;\n version: string | null;\n installHint: string;\n}\n\nfunction installHintFor(command: \"pandoc\" | \"ffmpeg\", platform: NodeJS.Platform): string {\n if (platform === \"darwin\") {\n return command === \"pandoc\" ? \"brew install pandoc\" : \"brew install ffmpeg\";\n }\n\n if (platform === \"win32\") {\n return command === \"pandoc\"\n ? \"Install via winget/choco (example: winget install --id JohnMacFarlane.Pandoc)\"\n : \"Install via winget/choco (example: winget install Gyan.FFmpeg)\";\n }\n\n return command === \"pandoc\"\n ? \"Install via your package manager (examples: apt/dnf/pacman) for pandoc\"\n : \"Install via your package manager (examples: apt/dnf/pacman) for ffmpeg\";\n}\n\nfunction parseVersion(command: \"pandoc\" | \"ffmpeg\", output: string): string | null {\n const firstLine = output.split(/\\r?\\n/, 1)[0]?.trim() ?? \"\";\n if (!firstLine) {\n return null;\n }\n\n if (command === \"pandoc\") {\n const matched = firstLine.match(/^pandoc\\s+([^\\s]+)/i);\n return matched?.[1] ?? firstLine;\n }\n\n if (command === \"ffmpeg\") {\n const matched = firstLine.match(/^ffmpeg version\\s+([^\\s]+)/i);\n return matched?.[1] ?? firstLine;\n }\n\n return firstLine;\n}\n\nexport async function inspectCommand(\n command: \"pandoc\" | \"ffmpeg\",\n platform: NodeJS.Platform,\n): Promise<CommandStatus> {\n try {\n const result = await execCommand(command, command === \"pandoc\" ? [\"--version\"] : [\"-version\"]);\n return {\n name: command,\n available: result.ok,\n version: result.ok ? parseVersion(command, result.stdout || result.stderr) : null,\n installHint: installHintFor(command, platform),\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (/ENOENT/i.test(message)) {\n return {\n name: command,\n available: false,\n version: null,\n installHint: installHintFor(command, platform),\n };\n }\n throw new CliError(`Failed to inspect dependency '${command}': ${message}`, {\n code: \"DEPENDENCY_CHECK_FAILED\",\n exitCode: 2,\n });\n }\n}\n\nexport async function requireCommandAvailable(\n command: \"pandoc\" | \"ffmpeg\",\n platform: NodeJS.Platform,\n): Promise<void> {\n const status = await inspectCommand(command, platform);\n if (status.available) {\n return;\n }\n\n throw new CliError(\n `Missing required dependency: ${command}. Install suggestion: ${status.installHint}`,\n {\n code: \"DEPENDENCY_MISSING\",\n exitCode: 2,\n },\n );\n}\n\n","import type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { homedir } from \"node:os\";\nimport { dirname } from \"node:path\";\n\nimport { CliError } from \"../errors\";\n\nexport const DUCKDB_MANAGED_EXTENSION_NAMES = [\"sqlite\", \"excel\"] as const;\n\nexport type DuckDbManagedExtensionName = (typeof DUCKDB_MANAGED_EXTENSION_NAMES)[number];\n\nexport interface DuckDbExtensionProbe {\n detail?: string;\n installed: boolean;\n installable: boolean | null;\n loadable: boolean;\n loaded: boolean;\n}\n\nexport interface DuckDbManagedExtensionProbe extends DuckDbExtensionProbe {\n cacheDirectory?: string;\n cacheFilePath?: string;\n label: string;\n loadName: string;\n name: DuckDbManagedExtensionName;\n runtimeVersion: string;\n statusName: string;\n}\n\ninterface DuckDbExtensionCatalogEntry {\n extension_name?: string;\n install_path?: string;\n installed?: boolean;\n loaded?: boolean;\n}\n\ninterface DuckDbManagedExtensionDefinition {\n label: string;\n loadName: string;\n name: DuckDbManagedExtensionName;\n statusName: string;\n}\n\nconst DUCKDB_MANAGED_EXTENSION_DEFINITIONS: Record<\n DuckDbManagedExtensionName,\n DuckDbManagedExtensionDefinition\n> = {\n sqlite: {\n label: \"SQLite\",\n loadName: \"sqlite\",\n name: \"sqlite\",\n statusName: \"sqlite_scanner\",\n },\n excel: {\n label: \"Excel\",\n loadName: \"excel\",\n name: \"excel\",\n statusName: \"excel\",\n },\n};\n\nfunction getDuckDbManagedExtensionDefinition(\n name: DuckDbManagedExtensionName,\n): DuckDbManagedExtensionDefinition {\n return DUCKDB_MANAGED_EXTENSION_DEFINITIONS[name];\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction writeStatusLine(stream: NodeJS.WritableStream | undefined, line: string): void {\n stream?.write(`${line}\\n`);\n}\n\nfunction resolveDuckDbHomeDirectory(): string | undefined {\n const fromEnv = process.env.HOME?.trim();\n if (fromEnv) {\n return fromEnv;\n }\n\n const fromRuntime = homedir().trim();\n return fromRuntime.length > 0 ? fromRuntime : undefined;\n}\n\nfunction resolveDuckDbCacheLocation(installPath: string | undefined): {\n cacheDirectory?: string;\n cacheFilePath?: string;\n} {\n const normalized = installPath?.trim();\n if (!normalized) {\n return {};\n }\n return {\n cacheDirectory: dirname(normalized),\n cacheFilePath: normalized,\n };\n}\n\nexport function sanitizeDuckDbPathForDisplay(path: string): string {\n const homeDirectory = resolveDuckDbHomeDirectory();\n if (!homeDirectory) {\n return path;\n }\n if (path === homeDirectory) {\n return \"$HOME\";\n }\n if (path.startsWith(`${homeDirectory}/`)) {\n return `$HOME/${path.slice(homeDirectory.length + 1)}`;\n }\n return path;\n}\n\nasync function readDuckDbExtensionCatalog(\n connection: DuckDBConnection,\n): Promise<Record<string, DuckDbExtensionCatalogEntry>> {\n const reader = await connection.runAndReadAll(\n \"select extension_name, install_path, installed, loaded from duckdb_extensions()\",\n );\n const rows = reader.getRowObjectsJson() as DuckDbExtensionCatalogEntry[];\n return Object.fromEntries(\n rows\n .map((row) => {\n const name = typeof row.extension_name === \"string\" ? row.extension_name : undefined;\n if (!name) {\n return undefined;\n }\n return [name, row] as const;\n })\n .filter((entry): entry is readonly [string, DuckDbExtensionCatalogEntry] => Boolean(entry)),\n );\n}\n\nexport async function getDuckDbRuntimeVersion(connection: DuckDBConnection): Promise<string> {\n const reader = await connection.runAndReadAll(\"select version() as duckdb_version\");\n const rows = reader.getRowObjectsJson() as Array<{ duckdb_version?: string }>;\n const version = rows[0]?.duckdb_version?.trim();\n return version && version.length > 0 ? version : \"unknown\";\n}\n\nfunction inferInstallability(installed: boolean, detail: string | undefined): boolean | null {\n if (installed) {\n return true;\n }\n if (!detail) {\n return null;\n }\n if (/install it first/i.test(detail) || /not found/i.test(detail)) {\n return true;\n }\n if (\n /operation not permitted/i.test(detail) ||\n /permission denied/i.test(detail) ||\n /failed to create directory/i.test(detail) ||\n /read-only/i.test(detail) ||\n /failed to download extension/i.test(detail) ||\n /could not establish connection/i.test(detail) ||\n /name or service not known/i.test(detail) ||\n /temporary failure in name resolution/i.test(detail)\n ) {\n return false;\n }\n return null;\n}\n\nfunction withDuckDbCacheLocation(\n definition: DuckDbManagedExtensionDefinition,\n runtimeVersion: string,\n probe: DuckDbExtensionProbe,\n installPath?: string,\n): DuckDbManagedExtensionProbe {\n const cacheLocation = resolveDuckDbCacheLocation(installPath);\n return {\n ...probe,\n ...cacheLocation,\n label: definition.label,\n loadName: definition.loadName,\n name: definition.name,\n runtimeVersion,\n statusName: definition.statusName,\n };\n}\n\nexport async function probeDuckDbManagedExtension(\n connection: DuckDBConnection,\n name: DuckDbManagedExtensionName,\n): Promise<DuckDbManagedExtensionProbe> {\n const definition = getDuckDbManagedExtensionDefinition(name);\n const runtimeVersion = await getDuckDbRuntimeVersion(connection);\n const catalog = await readDuckDbExtensionCatalog(connection);\n const initial = catalog[definition.statusName];\n if (initial?.loaded) {\n return withDuckDbCacheLocation(definition, runtimeVersion, {\n installed: Boolean(initial.installed),\n installable: Boolean(initial.installed),\n loadable: true,\n loaded: true,\n }, initial.install_path);\n }\n\n try {\n await connection.run(`load ${definition.loadName}`);\n const refreshed = (await readDuckDbExtensionCatalog(connection))[definition.statusName];\n return withDuckDbCacheLocation(definition, runtimeVersion, {\n installed: Boolean(refreshed?.installed ?? initial?.installed),\n installable: true,\n loadable: true,\n loaded: true,\n }, refreshed?.install_path ?? initial?.install_path);\n } catch (error) {\n const detail = toErrorMessage(error);\n return withDuckDbCacheLocation(definition, runtimeVersion, {\n detail,\n installed: Boolean(initial?.installed),\n installable: inferInstallability(Boolean(initial?.installed), detail),\n loadable: false,\n loaded: false,\n }, initial?.install_path);\n }\n}\n\nfunction formatDuckDbCacheMessage(\n probe: Pick<DuckDbManagedExtensionProbe, \"cacheDirectory\" | \"cacheFilePath\">,\n): string | undefined {\n if (probe.cacheFilePath) {\n return sanitizeDuckDbPathForDisplay(probe.cacheFilePath);\n }\n if (probe.cacheDirectory) {\n return sanitizeDuckDbPathForDisplay(probe.cacheDirectory);\n }\n return undefined;\n}\n\nexport function createDuckDbExtensionGuidanceMessage(\n name: DuckDbManagedExtensionName,\n probe: DuckDbManagedExtensionProbe,\n): string {\n const definition = getDuckDbManagedExtensionDefinition(name);\n const detail = probe.detail ? ` Detail: ${probe.detail}` : \"\";\n if (probe.installed) {\n return `${definition.label} query requires the DuckDB ${definition.loadName} extension, but it could not be loaded.${detail}`;\n }\n if (probe.installable === false) {\n return `${definition.label} query requires the DuckDB ${definition.loadName} extension, but the current environment cannot install or cache it.${detail}`;\n }\n return `${definition.label} query requires the DuckDB ${definition.loadName} extension, and it is not installed in the current environment. Install it explicitly in DuckDB, then retry.${detail}`;\n}\n\nexport function createDuckDbExtensionInstallCommand(name: DuckDbManagedExtensionName): string {\n return `cdx-chores data duckdb extension install ${name}`;\n}\n\nfunction printDuckDbExtensionInstallSuccess(\n stream: NodeJS.WritableStream | undefined,\n before: DuckDbManagedExtensionProbe,\n after: DuckDbManagedExtensionProbe,\n): void {\n writeStatusLine(\n stream,\n before.installed\n ? `DuckDB extension already present: ${after.name}`\n : `Installed DuckDB extension: ${after.name}`,\n );\n writeStatusLine(stream, `DuckDB runtime: ${after.runtimeVersion}`);\n\n const cacheMessage = formatDuckDbCacheMessage(after);\n if (cacheMessage) {\n const label = after.cacheFilePath ? \"Extension cache\" : \"Extension cache directory\";\n writeStatusLine(stream, `${label}: ${cacheMessage}`);\n }\n\n writeStatusLine(stream, `Load check: ${after.loadable ? \"ok\" : \"failed\"}`);\n}\n\nexport async function installDuckDbManagedExtension(\n connection: DuckDBConnection,\n name: DuckDbManagedExtensionName,\n options: { statusStream?: NodeJS.WritableStream } = {},\n): Promise<DuckDbManagedExtensionProbe> {\n const definition = getDuckDbManagedExtensionDefinition(name);\n const before = await probeDuckDbManagedExtension(connection, name);\n\n if (before.loadable) {\n printDuckDbExtensionInstallSuccess(options.statusStream, before, before);\n return before;\n }\n\n writeStatusLine(\n options.statusStream,\n before.installed\n ? `Refreshing DuckDB extension: ${definition.loadName}`\n : `Installing DuckDB extension: ${definition.loadName}`,\n );\n\n try {\n await connection.run(\n before.installed\n ? `force install ${definition.loadName}`\n : `install ${definition.loadName}`,\n );\n } catch (error) {\n throw new CliError(\n `Failed to install DuckDB ${definition.loadName} extension: ${toErrorMessage(error)}`,\n {\n code: \"DUCKDB_EXTENSION_INSTALL_FAILED\",\n exitCode: 2,\n },\n );\n }\n\n const after = await probeDuckDbManagedExtension(connection, name);\n if (!after.loadable) {\n throw new CliError(createDuckDbExtensionGuidanceMessage(name, after), {\n code: \"DUCKDB_EXTENSION_UNAVAILABLE\",\n exitCode: 2,\n });\n }\n\n printDuckDbExtensionInstallSuccess(options.statusStream, before, after);\n return after;\n}\n\nexport async function ensureDuckDbManagedExtensionLoaded(\n connection: DuckDBConnection,\n name: DuckDbManagedExtensionName,\n options: { installIfMissing?: boolean; statusStream?: NodeJS.WritableStream } = {},\n): Promise<DuckDbManagedExtensionProbe> {\n const probe = await probeDuckDbManagedExtension(connection, name);\n if (probe.loadable) {\n return probe;\n }\n\n if (options.installIfMissing && probe.installable === true) {\n return await installDuckDbManagedExtension(connection, name, {\n statusStream: options.statusStream,\n });\n }\n\n throw new CliError(createDuckDbExtensionGuidanceMessage(name, probe), {\n code: \"DUCKDB_EXTENSION_UNAVAILABLE\",\n exitCode: 2,\n });\n}\n","export type JsonRow = Record<string, unknown>;\n\nexport function normalizeRowsFromJson(input: unknown): JsonRow[] {\n if (Array.isArray(input)) {\n if (input.length === 0) {\n return [];\n }\n if (input.every((item) => item !== null && typeof item === \"object\" && !Array.isArray(item))) {\n return input as JsonRow[];\n }\n return input.map((item) => ({ value: item }));\n }\n\n if (input !== null && typeof input === \"object\") {\n return [input as JsonRow];\n }\n\n return [{ value: input }];\n}\n\nexport function collectFirstSeenColumns(rows: readonly JsonRow[]): string[] {\n const columns: string[] = [];\n const seen = new Set<string>();\n\n for (const row of rows) {\n for (const key of Object.keys(row)) {\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n columns.push(key);\n }\n }\n\n return columns;\n}\n\nexport function stringifyPreviewValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (\n typeof value === \"number\" ||\n typeof value === \"bigint\" ||\n typeof value === \"boolean\"\n ) {\n return String(value);\n }\n if (Array.isArray(value) || typeof value === \"object\") {\n const json = JSON.stringify(value);\n return json ?? \"\";\n }\n return String(value);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { inflateRawSync } from \"node:zlib\";\n\nimport { CliError } from \"../errors\";\n\ninterface ZipEntryMeta {\n compressionMethod: number;\n compressedSize: number;\n fileName: string;\n localHeaderOffset: number;\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction findEndOfCentralDirectory(buffer: Buffer): number {\n const signature = 0x06054b50;\n const minimumSize = 22;\n const searchStart = Math.max(0, buffer.length - 0xffff - minimumSize);\n\n for (let index = buffer.length - minimumSize; index >= searchStart; index -= 1) {\n if (buffer.readUInt32LE(index) === signature) {\n return index;\n }\n }\n\n throw new CliError(\"Invalid .xlsx file: ZIP end-of-central-directory record not found.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n\nfunction readCentralDirectoryEntries(buffer: Buffer): ZipEntryMeta[] {\n const eocdOffset = findEndOfCentralDirectory(buffer);\n const centralDirectoryOffset = buffer.readUInt32LE(eocdOffset + 16);\n const centralDirectorySize = buffer.readUInt32LE(eocdOffset + 12);\n const entries: ZipEntryMeta[] = [];\n\n let offset = centralDirectoryOffset;\n const end = centralDirectoryOffset + centralDirectorySize;\n while (offset < end) {\n if (buffer.readUInt32LE(offset) !== 0x02014b50) {\n throw new CliError(\"Invalid .xlsx file: malformed ZIP central directory.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const compressionMethod = buffer.readUInt16LE(offset + 10);\n const compressedSize = buffer.readUInt32LE(offset + 20);\n const fileNameLength = buffer.readUInt16LE(offset + 28);\n const extraLength = buffer.readUInt16LE(offset + 30);\n const commentLength = buffer.readUInt16LE(offset + 32);\n const localHeaderOffset = buffer.readUInt32LE(offset + 42);\n const fileName = buffer.toString(\"utf8\", offset + 46, offset + 46 + fileNameLength);\n\n entries.push({\n compressionMethod,\n compressedSize,\n fileName,\n localHeaderOffset,\n });\n\n offset += 46 + fileNameLength + extraLength + commentLength;\n }\n\n return entries;\n}\n\nfunction extractZipEntry(buffer: Buffer, entry: ZipEntryMeta): Buffer {\n const localHeaderOffset = entry.localHeaderOffset;\n if (buffer.readUInt32LE(localHeaderOffset) !== 0x04034b50) {\n throw new CliError(\"Invalid .xlsx file: malformed ZIP local header.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const fileNameLength = buffer.readUInt16LE(localHeaderOffset + 26);\n const extraLength = buffer.readUInt16LE(localHeaderOffset + 28);\n const dataStart = localHeaderOffset + 30 + fileNameLength + extraLength;\n const compressedData = buffer.subarray(dataStart, dataStart + entry.compressedSize);\n\n if (entry.compressionMethod === 0) {\n return compressedData;\n }\n if (entry.compressionMethod === 8) {\n return inflateRawSync(compressedData);\n }\n\n throw new CliError(`Unsupported .xlsx ZIP compression method: ${entry.compressionMethod}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n\nfunction decodeXmlEntities(value: string): string {\n return value\n .replaceAll(\""\", '\"')\n .replaceAll(\"'\", \"'\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll(\"&\", \"&\");\n}\n\nexport async function listXlsxSheetNames(inputPath: string): Promise<string[]> {\n let buffer: Buffer;\n try {\n buffer = await readFile(inputPath);\n } catch (error) {\n throw new CliError(`Failed to read .xlsx workbook: ${inputPath} (${toErrorMessage(error)})`, {\n code: \"FILE_READ_ERROR\",\n exitCode: 2,\n });\n }\n\n try {\n const entries = readCentralDirectoryEntries(buffer);\n const workbookEntry = entries.find((entry) => entry.fileName === \"xl/workbook.xml\");\n if (!workbookEntry) {\n throw new CliError(\"Invalid .xlsx file: missing xl/workbook.xml.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const workbookXml = extractZipEntry(buffer, workbookEntry).toString(\"utf8\");\n const sheets = [...workbookXml.matchAll(/<sheet\\b[^>]*\\bname=\"([^\"]+)\"/g)].map((match) =>\n decodeXmlEntities(match[1] ?? \"\"),\n );\n\n if (sheets.length === 0) {\n throw new CliError(\"No worksheet sources found in the .xlsx workbook.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n return sheets;\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n throw new CliError(`Invalid .xlsx file: failed to read workbook metadata (${toErrorMessage(error)}).`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n}\n","import type { DuckDBConnection, DuckDBResultReader } from \"@duckdb/node-api\";\nimport { extname } from \"node:path\";\n\nimport { stringifyPreviewValue } from \"../data-preview/normalize\";\nimport type { DataPreviewRow } from \"../data-preview/source\";\nimport { CliError } from \"../errors\";\nimport {\n type DuckDbExtensionProbe,\n type DuckDbManagedExtensionName,\n ensureDuckDbManagedExtensionLoaded,\n probeDuckDbManagedExtension,\n} from \"./extensions\";\nimport { listXlsxSheetNames } from \"./xlsx-sources\";\n\nexport const DATA_QUERY_INPUT_FORMAT_VALUES = [\"csv\", \"tsv\", \"parquet\", \"sqlite\", \"excel\"] as const;\n\nexport type DataQueryInputFormat = (typeof DATA_QUERY_INPUT_FORMAT_VALUES)[number];\n\nexport interface DataQueryTableResult {\n columns: string[];\n rows: DataPreviewRow[];\n truncated: boolean;\n}\n\nexport interface DataQueryResultSet {\n columns: string[];\n rows: Array<Record<string, unknown>>;\n}\n\nexport interface DataQueryIntrospectionColumn {\n name: string;\n type: string;\n}\n\nexport interface DataQuerySourceIntrospection {\n columns: DataQueryIntrospectionColumn[];\n sampleRows: Array<Record<string, string>>;\n selectedSource?: string;\n truncated: boolean;\n}\n\ninterface PreparedDataQuerySource {\n selectedSource?: string;\n}\n\nconst INPUT_FORMAT_EXTENSION_MAP: Record<string, DataQueryInputFormat> = {\n \".csv\": \"csv\",\n \".tsv\": \"tsv\",\n \".parquet\": \"parquet\",\n \".sqlite\": \"sqlite\",\n \".sqlite3\": \"sqlite\",\n \".xlsx\": \"excel\",\n};\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction escapeSqlString(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction dedupeRequestedColumns(columns: readonly string[] | undefined): string[] {\n if (!columns) {\n return [];\n }\n\n const values: string[] = [];\n const seen = new Set<string>();\n for (const column of columns.map((item) => item.trim()).filter((item) => item.length > 0)) {\n if (seen.has(column)) {\n continue;\n }\n seen.add(column);\n values.push(column);\n }\n return values;\n}\n\nexport function quoteSqlIdentifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\nexport function detectDataQueryInputFormat(\n inputPath: string,\n override?: DataQueryInputFormat,\n): DataQueryInputFormat {\n if (override) {\n return override;\n }\n\n const detected = INPUT_FORMAT_EXTENSION_MAP[extname(inputPath).toLowerCase()];\n if (detected) {\n return detected;\n }\n\n throw new CliError(\n `Unsupported query file type: ${inputPath}. Supported inputs: .csv, .tsv, .parquet, .sqlite, .sqlite3, .xlsx.`,\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n}\n\nexport async function createDuckDbConnection(): Promise<DuckDBConnection> {\n try {\n const duckdb = await import(\"@duckdb/node-api\");\n return await duckdb.DuckDBConnection.create();\n } catch (error) {\n throw new CliError(`DuckDB is unavailable for data query: ${toErrorMessage(error)}`, {\n code: \"DUCKDB_UNAVAILABLE\",\n exitCode: 2,\n });\n }\n}\n\nfunction getDuckDbManagedExtensionNameForFormat(\n format: \"sqlite\" | \"excel\",\n): DuckDbManagedExtensionName {\n return format;\n}\n\nfunction buildRelationSql(inputPath: string, format: DataQueryInputFormat, source?: string): string {\n const escapedInput = escapeSqlString(inputPath);\n switch (format) {\n case \"csv\":\n return `select * from read_csv_auto(${escapedInput}, delim = ',')`;\n case \"tsv\":\n return `select * from read_csv_auto(${escapedInput}, delim = '\\t')`;\n case \"parquet\":\n return `select * from read_parquet(${escapedInput})`;\n case \"sqlite\":\n return `select * from sqlite_scan(${escapedInput}, ${escapeSqlString(source ?? \"\")})`;\n case \"excel\":\n return `select * from read_xlsx(${escapedInput}, sheet = ${escapeSqlString(source ?? \"\")})`;\n }\n}\n\nfunction assertSingleObjectSourceContract(format: DataQueryInputFormat, source?: string): void {\n const normalized = source?.trim();\n if (normalized) {\n throw new CliError(`--source is not valid for ${format.toUpperCase()} query inputs.`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n}\n\nfunction formatAvailableSources(sources: readonly string[]): string {\n return sources.join(\", \");\n}\n\nasync function listSQLiteSources(connection: DuckDBConnection, inputPath: string): Promise<string[]> {\n const reader = await connection.runAndReadAll(\n `select name from sqlite_scan(${escapeSqlString(inputPath)}, 'sqlite_master') where type in ('table', 'view') and name not like 'sqlite_%' order by name`,\n );\n const rows = reader.getRowObjectsJson() as Array<{ name?: string }>;\n return rows\n .map((row) => (typeof row.name === \"string\" ? row.name : \"\"))\n .filter((name) => name.length > 0);\n}\n\nexport async function listDataQuerySources(\n connection: DuckDBConnection,\n inputPath: string,\n format: DataQueryInputFormat,\n): Promise<string[] | undefined> {\n if (format === \"sqlite\") {\n await ensureDuckDbManagedExtensionLoaded(\n connection,\n getDuckDbManagedExtensionNameForFormat(\"sqlite\"),\n );\n return await listSQLiteSources(connection, inputPath);\n }\n\n if (format === \"excel\") {\n await ensureDuckDbManagedExtensionLoaded(\n connection,\n getDuckDbManagedExtensionNameForFormat(\"excel\"),\n );\n return await listXlsxSheetNames(inputPath);\n }\n\n return undefined;\n}\n\nasync function resolveMultiObjectSource(\n connection: DuckDBConnection,\n inputPath: string,\n format: \"sqlite\" | \"excel\",\n source?: string,\n): Promise<string> {\n const sources = await listDataQuerySources(connection, inputPath, format);\n if (!sources) {\n throw new CliError(`No queryable ${format === \"sqlite\" ? \"SQLite\" : \"Excel\"} sources were found.`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n if (sources.length === 0) {\n throw new CliError(`No queryable ${format === \"sqlite\" ? \"SQLite\" : \"Excel\"} sources were found.`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const normalizedSource = source?.trim();\n if (!normalizedSource) {\n throw new CliError(\n `--source is required for ${format === \"sqlite\" ? \"SQLite\" : \"Excel\"} query inputs. Available sources: ${formatAvailableSources(sources)}.`,\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n }\n\n if (!sources.includes(normalizedSource)) {\n throw new CliError(\n `Unknown ${format === \"sqlite\" ? \"SQLite\" : \"Excel\"} source: ${normalizedSource}. Available sources: ${formatAvailableSources(sources)}.`,\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n }\n\n return normalizedSource;\n}\n\nexport async function prepareDataQuerySource(\n connection: DuckDBConnection,\n inputPath: string,\n format: DataQueryInputFormat,\n source?: string,\n options: {\n installMissingExtension?: boolean;\n statusStream?: NodeJS.WritableStream;\n } = {},\n): Promise<PreparedDataQuerySource> {\n let selectedSource = source?.trim();\n\n if (format === \"sqlite\") {\n await ensureDuckDbManagedExtensionLoaded(\n connection,\n getDuckDbManagedExtensionNameForFormat(\"sqlite\"),\n {\n installIfMissing: options.installMissingExtension,\n statusStream: options.statusStream,\n },\n );\n selectedSource = await resolveMultiObjectSource(connection, inputPath, \"sqlite\", source);\n }\n if (format === \"excel\") {\n await ensureDuckDbManagedExtensionLoaded(\n connection,\n getDuckDbManagedExtensionNameForFormat(\"excel\"),\n {\n installIfMissing: options.installMissingExtension,\n statusStream: options.statusStream,\n },\n );\n selectedSource = await resolveMultiObjectSource(connection, inputPath, \"excel\", source);\n }\n\n if (format === \"csv\" || format === \"tsv\" || format === \"parquet\") {\n assertSingleObjectSourceContract(format, source);\n }\n\n try {\n await connection.run(`create or replace temp view file as ${buildRelationSql(inputPath, format, selectedSource)}`);\n return { selectedSource };\n } catch (error) {\n throw new CliError(`Failed to prepare ${format} query input: ${toErrorMessage(error)}`, {\n code: \"DATA_QUERY_SOURCE_FAILED\",\n exitCode: 2,\n });\n }\n}\n\nfunction assertResultSet(reader: DuckDBResultReader): void {\n if (reader.columnCount > 0) {\n return;\n }\n throw new CliError(\"data query requires a SQL statement that returns rows.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n\nfunction normalizeResultRows(\n columns: readonly string[],\n rows: ReadonlyArray<Record<string, unknown>>,\n): DataPreviewRow[] {\n return rows.map((row) => {\n const values: Record<string, string> = {};\n for (const column of columns) {\n values[column] = stringifyPreviewValue(row[column]);\n }\n return { values };\n });\n}\n\nexport async function executeDataQueryForTable(\n connection: DuckDBConnection,\n sql: string,\n rowLimit: number,\n): Promise<DataQueryTableResult> {\n try {\n const reader = await connection.streamAndReadUntil(sql, rowLimit + 1);\n assertResultSet(reader);\n const columns = reader.deduplicatedColumnNames();\n const allRows = reader.getRowObjectsJson() as Array<Record<string, unknown>>;\n const truncated = allRows.length > rowLimit || !reader.done;\n const visibleRows = allRows.slice(0, rowLimit);\n return {\n columns,\n rows: normalizeResultRows(columns, visibleRows),\n truncated,\n };\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n throw new CliError(`Failed to execute query: ${toErrorMessage(error)}`, {\n code: \"DATA_QUERY_FAILED\",\n exitCode: 2,\n });\n }\n}\n\nexport async function executeDataQueryForAllRows(\n connection: DuckDBConnection,\n sql: string,\n): Promise<DataQueryResultSet> {\n try {\n const reader = await connection.runAndReadAll(sql);\n assertResultSet(reader);\n return {\n columns: reader.deduplicatedColumnNames(),\n rows: reader.getRowObjectsJson() as Array<Record<string, unknown>>,\n };\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n throw new CliError(`Failed to execute query: ${toErrorMessage(error)}`, {\n code: \"DATA_QUERY_FAILED\",\n exitCode: 2,\n });\n }\n}\n\nexport async function collectDataQuerySourceIntrospection(\n connection: DuckDBConnection,\n inputPath: string,\n format: DataQueryInputFormat,\n source: string | undefined,\n sampleRowLimit: number,\n): Promise<DataQuerySourceIntrospection> {\n const preparedSource = await prepareDataQuerySource(connection, inputPath, format, source);\n\n try {\n const reader = await connection.streamAndReadUntil(\"select * from file\", sampleRowLimit + 1);\n assertResultSet(reader);\n\n const columnNames = reader.deduplicatedColumnNames();\n const columnTypes = reader.columnTypes();\n const allRows = reader.getRowObjectsJson() as Array<Record<string, unknown>>;\n const visibleRows = allRows.slice(0, sampleRowLimit).map((row) =>\n Object.fromEntries(\n columnNames.map((column) => [column, stringifyPreviewValue(row[column])]),\n ),\n );\n\n return {\n columns: columnNames.map((name, index) => ({\n name,\n type: columnTypes[index]?.toString() ?? \"UNKNOWN\",\n })),\n sampleRows: visibleRows,\n selectedSource: preparedSource.selectedSource,\n truncated: allRows.length > sampleRowLimit || !reader.done,\n };\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n throw new CliError(`Failed to inspect ${format} query input: ${toErrorMessage(error)}`, {\n code: \"DATA_QUERY_SOURCE_FAILED\",\n exitCode: 2,\n });\n }\n}\n\nexport async function inspectDataQueryExtensions(): Promise<{\n available: boolean;\n detail?: string;\n runtimeVersion?: string;\n excel?: DuckDbExtensionProbe;\n sqlite?: DuckDbExtensionProbe;\n}> {\n let connection: DuckDBConnection | undefined;\n try {\n connection = await createDuckDbConnection();\n const excel = await probeDuckDbManagedExtension(connection, \"excel\");\n const sqlite = await probeDuckDbManagedExtension(connection, \"sqlite\");\n return {\n available: true,\n excel,\n runtimeVersion: excel.runtimeVersion,\n sqlite,\n };\n } catch (error) {\n return {\n available: false,\n detail: error instanceof Error ? error.message : String(error),\n };\n } finally {\n connection?.closeSync();\n }\n}\n","export const RENAME_SERIAL_ORDER_VALUES = [\n \"path_asc\",\n \"path_desc\",\n \"mtime_asc\",\n \"mtime_desc\",\n] as const;\n\nexport type RenameSerialOrder = (typeof RENAME_SERIAL_ORDER_VALUES)[number];\n\nexport const RENAME_SERIAL_SCOPE_VALUES = [\"global\", \"directory\"] as const;\n\nexport type RenameSerialScope = (typeof RENAME_SERIAL_SCOPE_VALUES)[number];\n\nexport const DEFAULT_RENAME_SERIAL_ORDER: RenameSerialOrder = \"path_asc\";\nexport const DEFAULT_RENAME_SERIAL_START = 1;\n\nexport const RENAME_TEMPLATE_PRESET_VALUES = [\n \"default\",\n \"timestamp-first\",\n \"stem-first\",\n \"custom\",\n] as const;\n\nexport type RenameTemplatePreset = (typeof RENAME_TEMPLATE_PRESET_VALUES)[number];\n\nconst RENAME_TEMPLATE_PRESET_PATTERNS: Record<Exclude<RenameTemplatePreset, \"custom\">, string> = {\n default: \"{prefix}-{timestamp}-{stem}\",\n \"timestamp-first\": \"{timestamp}-{prefix}-{stem}\",\n \"stem-first\": \"{stem}-{timestamp}-{prefix}\",\n};\n\ninterface SerialTokenOptions {\n width?: number;\n start?: number;\n order?: RenameSerialOrder;\n}\n\nexport interface ParsedSerialToken {\n width?: number;\n start: number;\n order: RenameSerialOrder;\n}\n\nfunction ensureSerialStart(value: number): number {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(\"Serial start must be a non-negative integer.\");\n }\n return value;\n}\n\nfunction ensureSerialWidth(value: number): number {\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(\"Serial width must be a positive integer.\");\n }\n return value;\n}\n\nfunction normalizeSerialTokenInput(token: string): string {\n const trimmed = token.trim();\n if (!trimmed) {\n throw new Error(\"Serial token cannot be empty.\");\n }\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n return trimmed.slice(1, -1).trim();\n }\n return trimmed;\n}\n\nexport function isRenameSerialOrder(value: string): value is RenameSerialOrder {\n return (RENAME_SERIAL_ORDER_VALUES as readonly string[]).includes(value);\n}\n\nexport function isRenameSerialScope(value: string): value is RenameSerialScope {\n return (RENAME_SERIAL_SCOPE_VALUES as readonly string[]).includes(value);\n}\n\nexport function parseSerialToken(token: string): ParsedSerialToken {\n const normalized = normalizeSerialTokenInput(token);\n if (normalized === \"serial\") {\n return {\n start: DEFAULT_RENAME_SERIAL_START,\n order: DEFAULT_RENAME_SERIAL_ORDER,\n };\n }\n if (!normalized.startsWith(\"serial_\")) {\n throw new Error(`Invalid serial token '${token}'. Expected '{serial...}'.`);\n }\n\n const body = normalized.slice(\"serial_\".length);\n const segments = body.split(\"_\").filter((segment) => segment.length > 0);\n if (segments.length === 0) {\n throw new Error(`Invalid serial token '${token}'.`);\n }\n\n let width: number | undefined;\n let start = DEFAULT_RENAME_SERIAL_START;\n let order: RenameSerialOrder = DEFAULT_RENAME_SERIAL_ORDER;\n let hasStart = false;\n let hasOrder = false;\n\n for (let index = 0; index < segments.length; index += 1) {\n const segment = segments[index];\n if (!segment) {\n continue;\n }\n\n if (/^#+$/.test(segment)) {\n if (width !== undefined) {\n throw new Error(\"Serial token cannot contain multiple width markers.\");\n }\n width = segment.length;\n continue;\n }\n\n if (segment === \"start\") {\n if (hasStart) {\n throw new Error(\"Serial token cannot contain multiple start markers.\");\n }\n const value = segments[index + 1];\n if (!value || !/^\\d+$/.test(value)) {\n throw new Error(\"Serial start marker must use 'start_<non-negative-integer>'.\");\n }\n start = ensureSerialStart(Number(value));\n hasStart = true;\n index += 1;\n continue;\n }\n\n if (segment === \"order\") {\n if (hasOrder) {\n throw new Error(\"Serial token cannot contain multiple order markers.\");\n }\n const first = segments[index + 1];\n const second = segments[index + 2];\n if (!first || !second) {\n throw new Error(\n \"Serial order marker must use one of: order_path_asc, order_path_desc, order_mtime_asc, order_mtime_desc.\",\n );\n }\n const value = `${first}_${second}`;\n if (!isRenameSerialOrder(value)) {\n throw new Error(\n \"Serial order marker must use one of: path_asc, path_desc, mtime_asc, mtime_desc.\",\n );\n }\n order = value;\n hasOrder = true;\n index += 2;\n continue;\n }\n\n throw new Error(`Unknown serial token parameter '${segment}'.`);\n }\n\n return { width, start, order };\n}\n\nexport function serializeSerialToken(\n options: SerialTokenOptions = {},\n config: { includeDefaults?: boolean } = {},\n): string {\n const width = options.width !== undefined ? ensureSerialWidth(options.width) : undefined;\n const start = ensureSerialStart(options.start ?? DEFAULT_RENAME_SERIAL_START);\n const order = options.order ?? DEFAULT_RENAME_SERIAL_ORDER;\n const includeDefaults = config.includeDefaults ?? false;\n\n const parts = [\"serial\"];\n\n if (width !== undefined) {\n parts.push(\"#\".repeat(width));\n }\n if (includeDefaults || start !== DEFAULT_RENAME_SERIAL_START) {\n parts.push(\"start\", String(start));\n }\n if (includeDefaults || order !== DEFAULT_RENAME_SERIAL_ORDER) {\n const [orderBase, orderDirection] = order.split(\"_\");\n if (!orderBase || !orderDirection) {\n throw new Error(`Invalid serial order '${order}'.`);\n }\n parts.push(\"order\", orderBase, orderDirection);\n }\n\n return `{${parts.join(\"_\")}}`;\n}\n\nexport function getRenamePatternPresetTemplate(\n preset: Exclude<RenameTemplatePreset, \"custom\">,\n): string {\n return RENAME_TEMPLATE_PRESET_PATTERNS[preset];\n}\n\nexport function resolveRenamePatternTemplate(options: {\n preset: RenameTemplatePreset;\n customTemplate?: string;\n}): string {\n if (options.preset === \"custom\") {\n const customTemplate = (options.customTemplate ?? \"\").trim();\n if (!customTemplate) {\n throw new Error(\"Custom template cannot be empty.\");\n }\n return customTemplate;\n }\n\n return getRenamePatternPresetTemplate(options.preset);\n}\n\nexport function normalizeSerialPlaceholderInTemplate(options: {\n template: string;\n serial: SerialTokenOptions;\n includeDefaults?: boolean;\n}): string {\n const token = serializeSerialToken(options.serial, {\n includeDefaults: options.includeDefaults ?? false,\n });\n return options.template.replace(/\\{serial(?:_[^{}]+)?\\}/g, token);\n}\n\nexport function templateContainsSerialPlaceholder(template: string): boolean {\n return /\\{serial(?:_[^{}]+)?\\}/.test(template);\n}\n\nexport function templateContainsPrefixPlaceholder(template: string): boolean {\n return /\\{prefix\\}/.test(template);\n}\n\nexport type TimestampTimezone = \"local\" | \"utc\";\n\nexport const TIMESTAMP_TIMEZONE_VALUES = [\"local\", \"utc\"] as const;\n\nconst LEGACY_TIMESTAMP_PLACEHOLDER_PATTERN = /\\{\\s*timestamp\\s*\\}/;\nconst LEGACY_TIMESTAMP_PLACEHOLDER_GLOBAL_PATTERN = /\\{\\s*timestamp\\s*\\}/g;\nconst EXPLICIT_TIMESTAMP_PLACEHOLDER_PATTERN =\n /\\{\\s*timestamp_(local|utc)(?:_(iso|12h))?\\s*\\}/;\n\n/**\n * Returns true when a template contains at least one legacy `{timestamp}`\n * placeholder, including mixed templates that also contain explicit variants.\n */\nexport function templateContainsLegacyTimestamp(template: string): boolean {\n return LEGACY_TIMESTAMP_PLACEHOLDER_PATTERN.test(template);\n}\n\n/**\n * Returns true when a template already uses `{timestamp_local}` or `{timestamp_utc}`.\n */\nexport function templateContainsExplicitTimestamp(template: string): boolean {\n return EXPLICIT_TIMESTAMP_PLACEHOLDER_PATTERN.test(template);\n}\n\n/**\n * Rewrite all `{timestamp}` placeholders in a template to the explicit form\n * based on the chosen timezone. No-op when the template does not contain `{timestamp}`.\n */\nexport function rewriteTimestampPlaceholder(template: string, timezone: TimestampTimezone): string {\n const target = timezone === \"local\" ? \"{timestamp_local}\" : \"{timestamp_utc}\";\n return template.replace(LEGACY_TIMESTAMP_PLACEHOLDER_GLOBAL_PATTERN, target);\n}\n\n/**\n * Pure decision: should the interactive flow present a timezone-selection\n * prompt for a given rename pattern?\n *\n * Returns `true` whenever the pattern contains a bare `{timestamp}` token,\n * even if the template also includes explicit timestamp variants.\n */\nexport function shouldPromptTimestampTimezone(pattern: string): boolean {\n return templateContainsLegacyTimestamp(pattern);\n}\n\n/**\n * Apply the result of the interactive timezone prompt to a rename pattern.\n *\n * When `selectedTimezone` is defined the legacy `{timestamp}` tokens are\n * rewritten to the explicit form. Otherwise the pattern is returned as-is.\n */\nexport function resolveTimestampPatternForInteractive(\n pattern: string,\n selectedTimezone: TimestampTimezone | undefined,\n): string {\n if (selectedTimezone === undefined || !templateContainsLegacyTimestamp(pattern)) {\n return pattern;\n }\n return rewriteTimestampPlaceholder(pattern, selectedTimezone);\n}\n","export function formatUtcFileDateTime(date: Date): string {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const day = String(date.getUTCDate()).padStart(2, \"0\");\n const hour = String(date.getUTCHours()).padStart(2, \"0\");\n const minute = String(date.getUTCMinutes()).padStart(2, \"0\");\n const second = String(date.getUTCSeconds()).padStart(2, \"0\");\n return `${year}${month}${day}-${hour}${minute}${second}`;\n}\n\nexport function formatLocalFileDateTime(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const hour = String(date.getHours()).padStart(2, \"0\");\n const minute = String(date.getMinutes()).padStart(2, \"0\");\n const second = String(date.getSeconds()).padStart(2, \"0\");\n return `${year}${month}${day}-${hour}${minute}${second}`;\n}\n\nexport function formatUtcFileDateTimeISO(date: Date): string {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const day = String(date.getUTCDate()).padStart(2, \"0\");\n const hour = String(date.getUTCHours()).padStart(2, \"0\");\n const minute = String(date.getUTCMinutes()).padStart(2, \"0\");\n const second = String(date.getUTCSeconds()).padStart(2, \"0\");\n return `${year}${month}${day}T${hour}${minute}${second}Z`;\n}\n\nfunction formatLocalNumericOffset(date: Date): string {\n const offsetMinutes = -date.getTimezoneOffset();\n const sign = offsetMinutes >= 0 ? \"+\" : \"-\";\n const absoluteMinutes = Math.abs(offsetMinutes);\n const hours = String(Math.floor(absoluteMinutes / 60)).padStart(2, \"0\");\n const minutes = String(absoluteMinutes % 60).padStart(2, \"0\");\n return `${sign}${hours}${minutes}`;\n}\n\nfunction formatTwelveHourClock(hour24: number): { hour12: string; meridiem: \"AM\" | \"PM\" } {\n const meridiem = hour24 >= 12 ? \"PM\" : \"AM\";\n const normalizedHour = hour24 % 12 || 12;\n return {\n hour12: String(normalizedHour).padStart(2, \"0\"),\n meridiem,\n };\n}\n\nexport function formatLocalFileDateTimeISO(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const hour = String(date.getHours()).padStart(2, \"0\");\n const minute = String(date.getMinutes()).padStart(2, \"0\");\n const second = String(date.getSeconds()).padStart(2, \"0\");\n return `${year}${month}${day}T${hour}${minute}${second}${formatLocalNumericOffset(date)}`;\n}\n\nexport function formatUtcFileDateTime12Hour(date: Date): string {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const day = String(date.getUTCDate()).padStart(2, \"0\");\n const { hour12, meridiem } = formatTwelveHourClock(date.getUTCHours());\n const minute = String(date.getUTCMinutes()).padStart(2, \"0\");\n const second = String(date.getUTCSeconds()).padStart(2, \"0\");\n return `${year}${month}${day}-${hour12}${minute}${second}${meridiem}`;\n}\n\nexport function formatLocalFileDateTime12Hour(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const { hour12, meridiem } = formatTwelveHourClock(date.getHours());\n const minute = String(date.getMinutes()).padStart(2, \"0\");\n const second = String(date.getSeconds()).padStart(2, \"0\");\n return `${year}${month}${day}-${hour12}${minute}${second}${meridiem}`;\n}\n","import { extname } from \"node:path\";\n\nexport function defaultOutputPath(inputPath: string, nextExtension: string): string {\n const extension = nextExtension.startsWith(\".\") ? nextExtension : `.${nextExtension}`;\n const currentExt = extname(inputPath);\n if (currentExt.length === 0) {\n return `${inputPath}${extension}`;\n }\n return `${inputPath.slice(0, -currentExt.length)}${extension}`;\n}\n\n","export function slugifyName(value: string, fallback = \"file\"): string {\n const normalized = value\n .normalize(\"NFKD\")\n .replace(/[^\\p{ASCII}]/gu, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return normalized || fallback;\n}\n\nexport function withNumericSuffix(value: string, index: number): string {\n if (index <= 0) {\n return value;\n }\n return `${value}-${String(index).padStart(2, \"0\")}`;\n}\n","import { createHash } from \"node:crypto\";\nimport { realpath } from \"node:fs/promises\";\nimport { basename, extname } from \"node:path\";\n\nconst CROCKFORD_BASE32_ALPHABET = \"0123456789abcdefghjkmnpqrstvwxyz\";\nconst CANONICAL_RENAME_UID_BASENAME_PATTERN = /^uid-([0-9a-hjkmnpqrstvwxyz]{10,16})$/i;\n\nfunction encodeLowerCrockfordBase32(buffer: Uint8Array): string {\n let bits = 0;\n let value = 0;\n let output = \"\";\n\n for (const byte of buffer) {\n value = (value << 8) | byte;\n bits += 8;\n\n while (bits >= 5) {\n output += CROCKFORD_BASE32_ALPHABET[(value >>> (bits - 5)) & 31];\n bits -= 5;\n }\n }\n\n if (bits > 0) {\n output += CROCKFORD_BASE32_ALPHABET[(value << (5 - bits)) & 31];\n }\n\n return output;\n}\n\nasync function buildRenameUidDigestText(sourcePath: string): Promise<string> {\n const normalizedRealPath = (await realpath(sourcePath)).replace(/\\\\/g, \"/\");\n const payload = `rename-cleanup-uid-v1\\0${normalizedRealPath}`;\n const digest = createHash(\"sha256\").update(payload, \"utf8\").digest();\n return encodeLowerCrockfordBase32(digest);\n}\n\nexport async function buildRenameUidBasenames(sourcePath: string): Promise<string[]> {\n const sourceName = basename(sourcePath);\n const sourceStem = basename(sourceName, extname(sourceName));\n const canonicalMatch = CANONICAL_RENAME_UID_BASENAME_PATTERN.exec(sourceStem);\n if (canonicalMatch?.[1]) {\n return [`uid-${canonicalMatch[1].toLowerCase()}`];\n }\n\n const digestText = await buildRenameUidDigestText(sourcePath);\n return [10, 13, 16].map((length) => `uid-${digestText.slice(0, length)}`);\n}\n\nexport async function buildRenameUidBasename(sourcePath: string): Promise<string> {\n const [first] = await buildRenameUidBasenames(sourcePath);\n return first ?? \"uid-0000000000\";\n}\n","import { lstat, mkdir, readFile, readdir, rename, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, extname, join, relative, resolve } from \"node:path\";\n\nimport { CliError } from \"./errors\";\nimport {\n type RenameSerialOrder,\n type RenameSerialScope,\n normalizeSerialPlaceholderInTemplate,\n parseSerialToken,\n} from \"./rename-template\";\nimport type { CliRuntime, PlannedRename, SkippedRenameItem } from \"./types\";\nimport {\n formatLocalFileDateTime,\n formatLocalFileDateTime12Hour,\n formatLocalFileDateTimeISO,\n formatUtcFileDateTime,\n formatUtcFileDateTime12Hour,\n formatUtcFileDateTimeISO,\n} from \"../utils/datetime\";\nimport { defaultOutputPath } from \"../utils/paths\";\nimport { slugifyName, withNumericSuffix } from \"../utils/slug\";\nimport { buildRenameUidBasename } from \"./rename-uid\";\n\nexport { defaultOutputPath } from \"../utils/paths\";\n\nconst RENAME_TEMPLATE_DEFAULT = \"{prefix}-{timestamp}-{stem}\";\nconst RENAME_TEMPLATE_TOKEN_PATTERN = /\\{([^{}]+)\\}/g;\nconst RENAME_TEMPLATE_SIMPLE_TOKENS = new Set([\n \"prefix\",\n \"timestamp\",\n \"timestamp_local\",\n \"timestamp_utc\",\n \"timestamp_local_iso\",\n \"timestamp_utc_iso\",\n \"timestamp_local_12h\",\n \"timestamp_utc_12h\",\n \"date\",\n \"date_local\",\n \"date_utc\",\n \"stem\",\n \"uid\",\n]);\n\ninterface RenamePatternOptions {\n pattern?: string;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope?: RenameSerialScope;\n recursive?: boolean;\n}\n\ninterface PreparedRenamePattern {\n template: string;\n usesUid: boolean;\n serial?: {\n order: RenameSerialOrder;\n start: number;\n width?: number;\n scope: RenameSerialScope;\n };\n}\n\ninterface RenameCandidateEntry {\n sourcePath: string;\n directoryPath: string;\n currentName: string;\n ext: string;\n stemSlug: string;\n mtimeDate: Date;\n mtimeMs: number;\n}\n\nfunction formatLocalDate(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\nfunction formatUtcDate(date: Date): string {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const day = String(date.getUTCDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\nfunction normalizePrefix(prefix: string | undefined): string {\n const trimmed = (prefix ?? \"\").trim();\n if (!trimmed) {\n return \"\";\n }\n return slugifyName(trimmed);\n}\n\nfunction ensureValidTemplateBraces(template: string): void {\n let inToken = false;\n for (const char of template) {\n if (char === \"{\") {\n if (inToken) {\n throw new CliError(\"Invalid --pattern: nested '{' is not supported.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n inToken = true;\n continue;\n }\n if (char === \"}\") {\n if (!inToken) {\n throw new CliError(\"Invalid --pattern: unmatched '}' found.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n inToken = false;\n }\n }\n if (inToken) {\n throw new CliError(\"Invalid --pattern: missing closing '}'.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n}\n\nfunction parseTemplateTokens(template: string): string[] {\n const tokens: string[] = [];\n for (const match of template.matchAll(RENAME_TEMPLATE_TOKEN_PATTERN)) {\n const token = (match[1] ?? \"\").trim();\n if (!token) {\n throw new CliError(\"Invalid --pattern: empty placeholder '{}'.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n tokens.push(token);\n }\n return tokens;\n}\n\nfunction getPreparedRenamePattern(options: RenamePatternOptions): PreparedRenamePattern {\n const template = (options.pattern ?? RENAME_TEMPLATE_DEFAULT).trim();\n if (!template) {\n throw new CliError(\"Invalid --pattern: template cannot be empty.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n ensureValidTemplateBraces(template);\n const tokens = parseTemplateTokens(template);\n\n const serialTokens = tokens.filter((token) => token === \"serial\" || token.startsWith(\"serial_\"));\n if (serialTokens.length > 1) {\n throw new CliError(\n \"Invalid --pattern: only one {serial...} placeholder is supported per template.\",\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n }\n let serial:\n | {\n order: RenameSerialOrder;\n start: number;\n width?: number;\n scope: RenameSerialScope;\n }\n | undefined;\n let normalizedTemplate = template;\n\n if (serialTokens.length > 0) {\n let parsed;\n try {\n parsed = parseSerialToken(serialTokens[0] ?? \"serial\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new CliError(`Invalid --pattern serial token: ${message}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const start = options.serialStart ?? parsed.start;\n if (!Number.isInteger(start) || start < 0) {\n throw new CliError(\"Invalid --serial-start: must be a non-negative integer.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const width = options.serialWidth ?? parsed.width;\n if (width !== undefined && (!Number.isInteger(width) || width <= 0)) {\n throw new CliError(\"Invalid --serial-width: must be a positive integer.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const order = options.serialOrder ?? parsed.order;\n const scope = options.serialScope ?? \"global\";\n\n serial = { order, start, width, scope };\n normalizedTemplate = normalizeSerialPlaceholderInTemplate({\n template,\n serial: {\n order: serial.order,\n start: serial.start,\n width: serial.width,\n },\n includeDefaults: true,\n });\n }\n\n const normalizedTokens = parseTemplateTokens(normalizedTemplate);\n for (const token of normalizedTokens) {\n if (RENAME_TEMPLATE_SIMPLE_TOKENS.has(token)) {\n continue;\n }\n if (token === \"serial\" || token.startsWith(\"serial_\")) {\n try {\n parseSerialToken(token);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new CliError(`Invalid --pattern serial token: ${message}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n continue;\n }\n throw new CliError(\n `Invalid --pattern placeholder: {${token}}. Allowed placeholders: {prefix}, {timestamp}, {timestamp_local}, {timestamp_utc}, {timestamp_local_iso}, {timestamp_utc_iso}, {timestamp_local_12h}, {timestamp_utc_12h}, {date}, {date_local}, {date_utc}, {stem}, {uid}, {serial...}.`,\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n }\n\n return {\n template: normalizedTemplate,\n usesUid: normalizedTokens.includes(\"uid\"),\n serial,\n };\n}\n\nfunction normalizeRenderedBaseName(value: string, fallback = \"file\"): string {\n const sanitized = value\n .replace(/[\\p{Cc}<>:\"/\\\\|?*]/gu, \"-\")\n .replace(/\\s+/g, \" \")\n .replace(/--+/g, \"-\")\n .replace(/__+/g, \"_\")\n .replace(/-_+/g, \"-\")\n .replace(/_-+/g, \"-\")\n .replace(/^[-_.\\s]+|[-_.\\s]+$/g, \"\");\n return sanitized || fallback;\n}\n\nfunction compareEntriesBySerialOrder(\n a: RenameCandidateEntry,\n b: RenameCandidateEntry,\n rootDirectoryPath: string,\n order: RenameSerialOrder,\n): number {\n const pathA = relative(rootDirectoryPath, a.sourcePath);\n const pathB = relative(rootDirectoryPath, b.sourcePath);\n\n if (order === \"path_asc\") {\n return pathA.localeCompare(pathB);\n }\n if (order === \"path_desc\") {\n return pathB.localeCompare(pathA);\n }\n\n const delta = a.mtimeMs - b.mtimeMs;\n if (delta !== 0) {\n return order === \"mtime_asc\" ? delta : -delta;\n }\n\n return pathA.localeCompare(pathB);\n}\n\nfunction buildSerialByPath(options: {\n entries: RenameCandidateEntry[];\n rootDirectoryPath: string;\n serial: NonNullable<PreparedRenamePattern[\"serial\"]>;\n recursive: boolean;\n}): Map<string, string> {\n const groups = new Map<string, RenameCandidateEntry[]>();\n for (const entry of options.entries) {\n const key =\n options.serial.scope === \"directory\" && options.recursive\n ? entry.directoryPath\n : \"__global__\";\n const current = groups.get(key);\n if (current) {\n current.push(entry);\n } else {\n groups.set(key, [entry]);\n }\n }\n\n const serialByPath = new Map<string, string>();\n for (const groupEntries of groups.values()) {\n const sorted = [...groupEntries].sort((a, b) =>\n compareEntriesBySerialOrder(a, b, options.rootDirectoryPath, options.serial.order),\n );\n\n const maxSerialValue = options.serial.start + sorted.length - 1;\n const computedWidth = String(Math.max(maxSerialValue, 0)).length;\n const width = Math.max(options.serial.width ?? 0, computedWidth);\n\n for (let index = 0; index < sorted.length; index += 1) {\n const entry = sorted[index];\n if (!entry) {\n continue;\n }\n const serialValue = options.serial.start + index;\n const serialText = String(serialValue).padStart(width, \"0\");\n serialByPath.set(entry.sourcePath, serialText);\n }\n }\n\n return serialByPath;\n}\n\nfunction renderBaseNameFromTemplate(options: {\n template: string;\n prefix: string;\n stem: string;\n mtimeDate: Date;\n serialText?: string;\n uidText?: string;\n}): string {\n const timestampUtc = formatUtcFileDateTime(options.mtimeDate);\n const timestampLocal = formatLocalFileDateTime(options.mtimeDate);\n const timestampUtcIso = formatUtcFileDateTimeISO(options.mtimeDate);\n const timestampLocalIso = formatLocalFileDateTimeISO(options.mtimeDate);\n const timestampUtc12Hour = formatUtcFileDateTime12Hour(options.mtimeDate);\n const timestampLocal12Hour = formatLocalFileDateTime12Hour(options.mtimeDate);\n const dateLocal = formatLocalDate(options.mtimeDate);\n const dateUtc = formatUtcDate(options.mtimeDate);\n\n const rendered = options.template.replace(\n RENAME_TEMPLATE_TOKEN_PATTERN,\n (_, rawToken: string) => {\n const token = rawToken.trim();\n switch (token) {\n case \"prefix\":\n return options.prefix;\n case \"timestamp\":\n case \"timestamp_utc\":\n return timestampUtc;\n case \"timestamp_local\":\n return timestampLocal;\n case \"timestamp_utc_iso\":\n return timestampUtcIso;\n case \"timestamp_local_iso\":\n return timestampLocalIso;\n case \"timestamp_utc_12h\":\n return timestampUtc12Hour;\n case \"timestamp_local_12h\":\n return timestampLocal12Hour;\n case \"date\":\n case \"date_local\":\n return dateLocal;\n case \"date_utc\":\n return dateUtc;\n case \"stem\":\n return options.stem;\n case \"uid\":\n return options.uidText ?? \"\";\n default:\n if (token === \"serial\" || token.startsWith(\"serial_\")) {\n return options.serialText ?? \"\";\n }\n return \"\";\n }\n },\n );\n\n return normalizeRenderedBaseName(rendered);\n}\n\nexport function resolveFromCwd(runtime: CliRuntime, filePath: string): string {\n return resolve(runtime.cwd, filePath);\n}\n\nexport function formatPathForDisplay(runtime: CliRuntime, filePath: string): string {\n if (runtime.displayPathStyle === \"absolute\") {\n return filePath;\n }\n\n const relativePath = relative(runtime.cwd, filePath);\n return relativePath.length > 0 ? relativePath : \".\";\n}\n\nexport async function readTextFileRequired(path: string): Promise<string> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new CliError(`Failed to read file: ${path} (${message})`, {\n code: \"FILE_READ_ERROR\",\n exitCode: 2,\n });\n }\n}\n\nexport async function ensureParentDir(path: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n}\n\nexport async function writeTextFileSafe(\n path: string,\n content: string,\n options: { overwrite?: boolean } = {},\n): Promise<void> {\n const overwrite = options.overwrite ?? false;\n try {\n if (!overwrite) {\n await stat(path);\n throw new CliError(`Output file already exists: ${path}. Use --overwrite to replace it.`, {\n code: \"OUTPUT_EXISTS\",\n exitCode: 2,\n });\n }\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n // ignore ENOENT and continue\n }\n\n await ensureParentDir(path);\n try {\n await writeFile(path, content, \"utf8\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new CliError(`Failed to write file: ${path} (${message})`, {\n code: \"FILE_WRITE_ERROR\",\n exitCode: 2,\n });\n }\n}\n\nexport async function planBatchRename(\n runtime: CliRuntime,\n directoryInput: string,\n options: {\n prefix?: string;\n pattern?: string;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope?: RenameSerialScope;\n now?: Date;\n titleOverrides?: Map<string, string>;\n fileFilter?: (entryName: string) => boolean;\n recursive?: boolean;\n maxDepth?: number;\n } = {},\n): Promise<{ directoryPath: string; plans: PlannedRename[]; skipped: SkippedRenameItem[] }> {\n const directoryPath = resolveFromCwd(runtime, directoryInput);\n const skipped: SkippedRenameItem[] = [];\n const files: Array<{ directoryPath: string; name: string }> = [];\n const recursive = options.recursive ?? false;\n const maxDepth = recursive ? (options.maxDepth ?? Number.POSITIVE_INFINITY) : 0;\n\n const visitDirectory = async (currentDirectoryPath: string, depth: number): Promise<void> => {\n const entries = await readdir(currentDirectoryPath, { withFileTypes: true });\n const sortedEntries = [...entries].sort((a, b) => a.name.localeCompare(b.name));\n\n for (const entry of sortedEntries) {\n const entryPath = join(currentDirectoryPath, entry.name);\n\n if (entry.isSymbolicLink()) {\n skipped.push({ path: entryPath, reason: \"symlink\" });\n continue;\n }\n\n if (entry.isDirectory()) {\n if (recursive && depth < maxDepth) {\n await visitDirectory(entryPath, depth + 1);\n }\n continue;\n }\n\n if (!entry.isFile()) {\n continue;\n }\n\n if (!(options.fileFilter?.(entry.name) ?? true)) {\n continue;\n }\n\n files.push({ directoryPath: currentDirectoryPath, name: entry.name });\n }\n };\n\n await visitDirectory(directoryPath, 0);\n\n const prefix = normalizePrefix(options.prefix);\n const preparedPattern = getPreparedRenamePattern({\n pattern: options.pattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n recursive,\n });\n const plannedTargets = new Set<string>();\n const plans: PlannedRename[] = [];\n const entries: RenameCandidateEntry[] = [];\n\n for (const file of files) {\n const sourcePath = join(file.directoryPath, file.name);\n\n let fileStats;\n try {\n fileStats = await stat(sourcePath);\n } catch {\n continue;\n }\n\n const ext = extname(file.name).toLowerCase();\n const stem = basename(file.name, extname(file.name));\n const preferredTitle = options.titleOverrides?.get(sourcePath)?.trim();\n const stemSlug = slugifyName(preferredTitle || stem).slice(0, 48);\n const mtimeDate = fileStats.mtime ?? options.now ?? runtime.now();\n entries.push({\n sourcePath,\n directoryPath: file.directoryPath,\n currentName: file.name,\n ext,\n stemSlug,\n mtimeDate,\n mtimeMs: mtimeDate.getTime(),\n });\n }\n\n const serialByPath = preparedPattern.serial\n ? buildSerialByPath({\n entries,\n rootDirectoryPath: directoryPath,\n serial: preparedPattern.serial,\n recursive,\n })\n : undefined;\n const uidByPath = preparedPattern.usesUid\n ? new Map<string, string>(\n await Promise.all(\n entries.map(\n async (entry): Promise<[string, string]> => [\n entry.sourcePath,\n await buildRenameUidBasename(entry.sourcePath),\n ],\n ),\n ),\n )\n : undefined;\n\n for (const entry of entries) {\n const baseName = renderBaseNameFromTemplate({\n template: preparedPattern.template,\n prefix,\n stem: entry.stemSlug,\n mtimeDate: entry.mtimeDate,\n serialText: serialByPath?.get(entry.sourcePath),\n uidText: uidByPath?.get(entry.sourcePath),\n });\n\n let counter = 0;\n let candidatePath = \"\";\n while (true) {\n const nextName = `${withNumericSuffix(baseName, counter)}${entry.ext}`;\n candidatePath = join(entry.directoryPath, nextName);\n if (!plannedTargets.has(candidatePath)) {\n break;\n }\n counter += 1;\n }\n\n plannedTargets.add(candidatePath);\n plans.push({\n fromPath: entry.sourcePath,\n toPath: candidatePath,\n changed: entry.sourcePath !== candidatePath,\n });\n }\n\n return { directoryPath, plans, skipped };\n}\n\nexport async function planSingleRename(\n runtime: CliRuntime,\n fileInput: string,\n options: {\n prefix?: string;\n pattern?: string;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope?: RenameSerialScope;\n now?: Date;\n titleOverride?: string;\n } = {},\n): Promise<{ directoryPath: string; plan: PlannedRename }> {\n const sourcePath = resolveFromCwd(runtime, fileInput);\n\n let sourceLstat;\n try {\n sourceLstat = await lstat(sourcePath);\n } catch {\n throw new CliError(`Input file not found: ${sourcePath}`, {\n code: \"FILE_NOT_FOUND\",\n exitCode: 2,\n });\n }\n\n if (sourceLstat.isSymbolicLink()) {\n throw new CliError(`Symlink inputs are not supported for rename file: ${sourcePath}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n if (!sourceLstat.isFile()) {\n throw new CliError(`Input file not found: ${sourcePath}`, {\n code: \"FILE_NOT_FOUND\",\n exitCode: 2,\n });\n }\n\n const directoryPath = dirname(sourcePath);\n const currentName = basename(sourcePath);\n const ext = extname(currentName).toLowerCase();\n const stem = basename(currentName, extname(currentName));\n const preferredTitle = options.titleOverride?.trim();\n const slug = slugifyName(preferredTitle || stem).slice(0, 48);\n const prefix = normalizePrefix(options.prefix);\n const mtimeDate = sourceLstat.mtime ?? options.now ?? runtime.now();\n const preparedPattern = getPreparedRenamePattern({\n pattern: options.pattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n recursive: false,\n });\n\n const entries = await readdir(directoryPath, { withFileTypes: true });\n const occupiedNames = new Set(\n entries.map((entry) => entry.name).filter((entryName) => entryName !== currentName),\n );\n\n let counter = 0;\n let nextName = currentName;\n const serialText = preparedPattern.serial\n ? String(preparedPattern.serial.start).padStart(\n Math.max(\n preparedPattern.serial.width ?? 0,\n String(Math.max(preparedPattern.serial.start, 0)).length,\n ),\n \"0\",\n )\n : undefined;\n const uidText = preparedPattern.usesUid ? await buildRenameUidBasename(sourcePath) : undefined;\n const baseName = renderBaseNameFromTemplate({\n template: preparedPattern.template,\n prefix,\n stem: slug,\n mtimeDate,\n serialText,\n uidText,\n });\n while (true) {\n nextName = `${withNumericSuffix(baseName, counter)}${ext}`;\n if (!occupiedNames.has(nextName)) {\n break;\n }\n counter += 1;\n }\n\n const toPath = join(directoryPath, nextName);\n return {\n directoryPath,\n plan: {\n fromPath: sourcePath,\n toPath,\n changed: sourcePath !== toPath,\n },\n };\n}\n\nexport async function applyPlannedRenames(plans: PlannedRename[]): Promise<void> {\n const changes = plans.filter((plan) => plan.changed);\n if (changes.length === 0) {\n return;\n }\n\n const tempMoves: Array<{ tempPath: string; finalPath: string }> = [];\n\n let index = 0;\n for (const plan of changes) {\n const tempPath = `${plan.fromPath}.cdx-chores-tmp-${process.pid}-${index}`;\n await rename(plan.fromPath, tempPath);\n tempMoves.push({ tempPath, finalPath: plan.toPath });\n index += 1;\n }\n\n for (const move of tempMoves) {\n await rename(move.tempPath, move.finalPath);\n }\n}\n","import { stat } from \"node:fs/promises\";\n\nimport { CliError } from \"../errors\";\nimport { formatPathForDisplay } from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\n\nexport function printLine(stream: NodeJS.WritableStream, line = \"\"): void {\n stream.write(`${line}\\n`);\n}\n\nexport function displayPath(runtime: CliRuntime, path: string): string {\n return formatPathForDisplay(runtime, path);\n}\n\nexport function assertNonEmpty(value: string | undefined, label: string): string {\n const next = value?.trim() ?? \"\";\n if (!next) {\n throw new CliError(`${label} is required.`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n return next;\n}\n\nexport async function ensureFileExists(path: string, label: string): Promise<void> {\n try {\n const fileStats = await stat(path);\n if (!fileStats.isFile()) {\n throw new Error(\"not a file\");\n }\n } catch {\n throw new CliError(`${label} file not found: ${path}`, {\n code: \"FILE_NOT_FOUND\",\n exitCode: 2,\n });\n }\n}\n\n","import { inspectCodexEnvironment } from \"../../adapters/codex/shared\";\nimport { getCliColors } from \"../colors\";\nimport { inspectCommand } from \"../deps\";\nimport { createDuckDbExtensionInstallCommand } from \"../duckdb/extensions\";\nimport { inspectDataQueryExtensions } from \"../duckdb/query\";\nimport type { CliRuntime } from \"../types\";\nimport { printLine } from \"./shared\";\n\nexport interface DoctorOptions {\n json?: boolean;\n}\n\nexport async function actionDoctor(runtime: CliRuntime, options: DoctorOptions = {}): Promise<void> {\n const pc = getCliColors(runtime);\n const [pandoc, ffmpeg, queryExtensions, codexEnvironment] = await Promise.all([\n inspectCommand(\"pandoc\", runtime.platform),\n inspectCommand(\"ffmpeg\", runtime.platform),\n inspectDataQueryExtensions(),\n inspectCodexEnvironment(),\n ]);\n\n const queryFormats = {\n csv: {\n kind: \"core\" as const,\n detectedSupport: queryExtensions.available,\n },\n tsv: {\n kind: \"core\" as const,\n detectedSupport: queryExtensions.available,\n },\n parquet: {\n kind: \"core\" as const,\n detectedSupport: queryExtensions.available,\n },\n sqlite: {\n kind: \"extension\" as const,\n detectedSupport: queryExtensions.available,\n loadability: queryExtensions.sqlite?.loadable ?? false,\n installability: queryExtensions.sqlite?.installable ?? null,\n detail: queryExtensions.sqlite?.detail,\n },\n excel: {\n kind: \"extension\" as const,\n detectedSupport: queryExtensions.available,\n loadability: queryExtensions.excel?.loadable ?? false,\n installability: queryExtensions.excel?.installable ?? null,\n detail: queryExtensions.excel?.detail,\n },\n };\n\n const queryCodex = {\n configuredSupport: codexEnvironment.configuredSupport,\n authSessionAvailable: codexEnvironment.authSessionAvailable,\n readyToDraft:\n codexEnvironment.configuredSupport &&\n codexEnvironment.authSessionAvailable &&\n queryExtensions.available,\n detail:\n codexEnvironment.detail ??\n (queryExtensions.available ? undefined : queryExtensions.detail),\n };\n\n const capabilities = {\n \"md.to-docx\": pandoc.available,\n \"video.convert\": ffmpeg.available,\n \"video.resize\": ffmpeg.available,\n \"video.gif\": ffmpeg.available,\n \"data.query.csv\": queryFormats.csv.detectedSupport,\n \"data.query.tsv\": queryFormats.tsv.detectedSupport,\n \"data.query.parquet\": queryFormats.parquet.detectedSupport,\n \"data.query.sqlite\": queryFormats.sqlite.loadability,\n \"data.query.excel\": queryFormats.excel.loadability,\n \"data.query.codex\": queryCodex.readyToDraft,\n };\n\n if (options.json) {\n const payload = {\n generatedAt: runtime.now().toISOString(),\n platform: runtime.platform,\n nodeVersion: process.version,\n tools: { pandoc, ffmpeg },\n query: {\n available: queryExtensions.available,\n detail: queryExtensions.detail,\n formats: queryFormats,\n runtimeVersion: queryExtensions.runtimeVersion,\n },\n queryCodex,\n capabilities,\n };\n printLine(runtime.stdout, JSON.stringify(payload, null, 2));\n return;\n }\n\n printLine(runtime.stdout, pc.bold(pc.cyan(\"cdx-chores doctor\")));\n printLine(runtime.stdout, `${pc.dim(\"Platform:\")} ${pc.white(runtime.platform)}`);\n printLine(runtime.stdout, `${pc.dim(\"Node.js:\")} ${pc.white(process.version)}`);\n printLine(runtime.stdout);\n\n for (const item of [pandoc, ffmpeg]) {\n const statusText = item.available\n ? pc.green(`available (${item.version ?? \"unknown version\"})`)\n : pc.red(\"missing\");\n printLine(\n runtime.stdout,\n `- ${pc.bold(item.name)}: ${statusText}`,\n );\n if (!item.available) {\n printLine(runtime.stdout, ` ${pc.yellow(\"Install suggestion:\")} ${item.installHint}`);\n }\n }\n\n printLine(runtime.stdout);\n printLine(runtime.stdout, pc.bold(pc.cyan(\"Capabilities:\")));\n for (const [capability, available] of Object.entries(capabilities)) {\n printLine(\n runtime.stdout,\n `- ${pc.bold(capability)}: ${available ? pc.green(\"available\") : pc.red(\"unavailable\")}`,\n );\n }\n\n printLine(runtime.stdout);\n printLine(runtime.stdout, pc.bold(pc.cyan(\"Data query formats:\")));\n if (!queryExtensions.available) {\n printLine(\n runtime.stdout,\n `- ${pc.bold(\"duckdb\")}: ${pc.red(\"unavailable\")} ${queryExtensions.detail ? `(${queryExtensions.detail})` : \"\"}`.trim(),\n );\n return;\n }\n\n if (queryExtensions.runtimeVersion) {\n printLine(\n runtime.stdout,\n `${pc.dim(\"DuckDB runtime:\")} ${pc.white(queryExtensions.runtimeVersion)}`,\n );\n }\n\n for (const [format, state] of Object.entries(queryFormats)) {\n if (state.kind === \"core\") {\n printLine(\n runtime.stdout,\n `- ${pc.bold(format)}: built-in DuckDB support=${state.detectedSupport ? \"yes\" : \"no\"}`,\n );\n continue;\n }\n\n const installability =\n state.installability === null\n ? \"unknown\"\n : state.installability\n ? \"yes\"\n : \"no\";\n printLine(\n runtime.stdout,\n `- ${pc.bold(format)}: detected support=${state.detectedSupport ? \"yes\" : \"no\"}, loadability=${state.loadability ? \"yes\" : \"no\"}, installability=${installability}`,\n );\n if (state.detail) {\n printLine(runtime.stdout, ` ${pc.dim(state.detail)}`);\n }\n if (!state.loadability && state.installability === true && (format === \"sqlite\" || format === \"excel\")) {\n printLine(\n runtime.stdout,\n ` ${pc.yellow(`Try: ${createDuckDbExtensionInstallCommand(format)}`)}`,\n );\n }\n }\n\n printLine(runtime.stdout);\n printLine(runtime.stdout, pc.bold(pc.cyan(\"Data query Codex:\")));\n printLine(\n runtime.stdout,\n `- ${pc.bold(\"codex\")}: configured support=${queryCodex.configuredSupport ? \"yes\" : \"no\"}, auth/session=${queryCodex.authSessionAvailable ? \"yes\" : \"no\"}, ready-to-draft=${queryCodex.readyToDraft ? \"yes\" : \"no\"}`,\n );\n if (queryCodex.detail) {\n printLine(runtime.stdout, ` ${pc.dim(queryCodex.detail)}`);\n }\n}\n","import Papa from \"papaparse\";\n\ntype CsvRecord = Record<string, unknown>;\n\nfunction normalizeHeader(value: string, index: number): string {\n return (index === 0 ? value.replace(/^\\uFEFF/, \"\") : value).trim();\n}\n\nexport function stringifyCsv(rows: CsvRecord[]): string {\n if (rows.length === 0) {\n return \"\";\n }\n\n const csv = Papa.unparse(rows, {\n header: true,\n newline: \"\\n\",\n });\n return csv.endsWith(\"\\n\") ? csv : `${csv}\\n`;\n}\n\nexport function parseCsv(text: string): string[][] {\n const parsed = Papa.parse<string[]>(text, {\n header: false,\n skipEmptyLines: false,\n delimiter: \",\",\n });\n\n if (parsed.errors.length > 0) {\n const first = parsed.errors[0];\n if (!first) {\n throw new Error(\"CSV parse error\");\n }\n throw new Error(`CSV parse error at row ${first.row ?? \"unknown\"}: ${first.message}`);\n }\n\n return parsed.data.map((row) =>\n Array.isArray(row) ? row.map((cell) => (cell === null || cell === undefined ? \"\" : String(cell))) : [],\n );\n}\n\nexport function csvRowsToObjects(rows: string[][]): Array<Record<string, string>> {\n if (rows.length === 0) {\n return [];\n }\n\n const [headerRow, ...dataRows] = rows;\n if (!headerRow) {\n return [];\n }\n const headers = headerRow.map((header, index) => normalizeHeader(header, index));\n\n return dataRows\n .filter((row) => row.some((value) => value.length > 0))\n .map((row) => {\n const record: Record<string, string> = {};\n headers.forEach((header, index) => {\n if (header.length === 0) {\n return;\n }\n record[header] = row[index] ?? \"\";\n });\n return record;\n });\n}\n","import { extname } from \"node:path\";\n\nimport { parseCsv } from \"../../utils/csv\";\nimport { CliError } from \"../errors\";\nimport {\n collectFirstSeenColumns,\n normalizeRowsFromJson,\n stringifyPreviewValue,\n type JsonRow,\n} from \"./normalize\";\n\nexport type DataPreviewFormat = \"csv\" | \"json\";\n\nexport interface DataPreviewContainsFilter {\n column: string;\n keyword: string;\n}\n\nexport interface DataPreviewRow {\n values: Record<string, string>;\n}\n\nexport interface DataPreviewSource {\n columns: string[];\n format: DataPreviewFormat;\n totalRows: number;\n getWindow(offset: number, rowCount: number): DataPreviewRow[];\n}\n\ninterface InMemoryDataPreviewSourceOptions {\n columns: string[];\n format: DataPreviewFormat;\n rows: DataPreviewRow[];\n}\n\nconst EMPTY_CELL = \"\";\n\nfunction createContainsFilterError(value: string, detail: string): CliError {\n return new CliError(`Invalid --contains value ${JSON.stringify(value)}: ${detail}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n\nfunction resolveMissingContainsColumns(\n source: Pick<DataPreviewSource, \"columns\">,\n filters: readonly DataPreviewContainsFilter[],\n): string[] {\n const available = new Set(source.columns);\n return filters\n .map((filter) => filter.column)\n .filter((column, index, values) => !available.has(column) && values.indexOf(column) === index);\n}\n\nclass InMemoryDataPreviewSource implements DataPreviewSource {\n public readonly columns: string[];\n public readonly format: DataPreviewFormat;\n public readonly totalRows: number;\n private readonly rows: DataPreviewRow[];\n\n constructor(options: InMemoryDataPreviewSourceOptions) {\n this.columns = options.columns;\n this.format = options.format;\n this.rows = options.rows;\n this.totalRows = options.rows.length;\n }\n\n getWindow(offset: number, rowCount: number): DataPreviewRow[] {\n return this.rows.slice(offset, offset + rowCount);\n }\n\n filterContains(filters: readonly DataPreviewContainsFilter[]): InMemoryDataPreviewSource {\n if (filters.length === 0) {\n return this;\n }\n\n assertContainsFilterColumns(this, filters);\n\n const normalizedFilters = filters.map((filter) => ({\n ...filter,\n keyword: filter.keyword.toLowerCase(),\n }));\n const rows = this.rows.filter((row) =>\n normalizedFilters.every((filter) =>\n (row.values[filter.column] ?? \"\").toLowerCase().includes(filter.keyword),\n ),\n );\n\n return new InMemoryDataPreviewSource({\n columns: [...this.columns],\n format: this.format,\n rows,\n });\n }\n}\n\nfunction normalizeCsvHeader(value: string | undefined, index: number): string {\n const trimmed = (index === 0 ? (value ?? \"\").replace(/^\\uFEFF/, \"\") : (value ?? \"\")).trim();\n return trimmed || `column_${index + 1}`;\n}\n\nfunction dedupeColumnName(name: string, seen: Map<string, number>): string {\n const current = seen.get(name) ?? 0;\n seen.set(name, current + 1);\n if (current === 0) {\n return name;\n }\n return `${name}_${current + 1}`;\n}\n\nfunction resolveCsvColumns(rows: readonly string[][]): string[] {\n const headerRow = rows[0] ?? [];\n const maxWidth = rows.reduce((largest, row) => Math.max(largest, row.length), 0);\n const seen = new Map<string, number>();\n const columns: string[] = [];\n\n for (let index = 0; index < maxWidth; index += 1) {\n const normalized = normalizeCsvHeader(headerRow[index], index);\n columns.push(dedupeColumnName(normalized, seen));\n }\n\n return columns;\n}\n\nfunction buildCsvRows(rows: readonly string[][], columns: readonly string[]): DataPreviewRow[] {\n const dataRows = rows.slice(1).filter((row) => row.some((value) => value.length > 0));\n return dataRows.map((row) => {\n const values: Record<string, string> = {};\n columns.forEach((column, index) => {\n values[column] = row[index] ?? EMPTY_CELL;\n });\n return { values };\n });\n}\n\nfunction buildJsonRows(rows: readonly JsonRow[], columns: readonly string[]): DataPreviewRow[] {\n return rows.map((row) => {\n const values: Record<string, string> = {};\n columns.forEach((column) => {\n values[column] = stringifyPreviewValue(row[column]);\n });\n return { values };\n });\n}\n\nfunction createCsvPreviewSource(text: string): DataPreviewSource {\n let rows: string[][];\n try {\n rows = parseCsv(text);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new CliError(`Invalid CSV: ${message}`, { code: \"INVALID_CSV\", exitCode: 2 });\n }\n\n const columns = resolveCsvColumns(rows);\n return new InMemoryDataPreviewSource({\n columns,\n format: \"csv\",\n rows: buildCsvRows(rows, columns),\n });\n}\n\nfunction createJsonPreviewSource(text: string): DataPreviewSource {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new CliError(`Invalid JSON: ${message}`, { code: \"INVALID_JSON\", exitCode: 2 });\n }\n\n const normalizedRows = normalizeRowsFromJson(parsed);\n const columns = collectFirstSeenColumns(normalizedRows);\n return new InMemoryDataPreviewSource({\n columns,\n format: \"json\",\n rows: buildJsonRows(normalizedRows, columns),\n });\n}\n\nexport function parseContainsFilterValue(value: string): DataPreviewContainsFilter {\n let column = \"\";\n let keyword = \"\";\n let escaped = false;\n let seenSeparator = false;\n\n for (const character of value) {\n if (escaped) {\n if (character !== \":\" && character !== \"\\\\\") {\n throw createContainsFilterError(value, `invalid escape sequence \\\\${character}. Use \\\\: for ':' or \\\\\\\\ for '\\\\'.`);\n }\n\n if (seenSeparator) {\n keyword += character;\n } else {\n column += character;\n }\n escaped = false;\n continue;\n }\n\n if (character === \"\\\\\") {\n escaped = true;\n continue;\n }\n\n if (!seenSeparator && character === \":\") {\n seenSeparator = true;\n continue;\n }\n\n if (seenSeparator) {\n keyword += character;\n } else {\n column += character;\n }\n }\n\n if (escaped) {\n throw createContainsFilterError(value, \"trailing escape sequence. Use \\\\: for ':' or \\\\\\\\ for '\\\\'.\");\n }\n\n if (!seenSeparator) {\n throw createContainsFilterError(value, \"missing ':' separator.\");\n }\n\n const normalizedColumn = column.trim();\n const normalizedKeyword = keyword.trim();\n\n if (normalizedColumn.length === 0) {\n throw createContainsFilterError(value, \"column name cannot be blank.\");\n }\n\n if (normalizedKeyword.length === 0) {\n throw createContainsFilterError(value, \"keyword cannot be blank.\");\n }\n\n return {\n column: normalizedColumn,\n keyword: normalizedKeyword,\n };\n}\n\nexport function parseContainsFilterValues(values: readonly string[] | undefined): DataPreviewContainsFilter[] {\n if (!values || values.length === 0) {\n return [];\n }\n return values.map((value) => parseContainsFilterValue(value));\n}\n\nexport function assertContainsFilterColumns(\n source: Pick<DataPreviewSource, \"columns\">,\n filters: readonly DataPreviewContainsFilter[],\n): void {\n const missing = resolveMissingContainsColumns(source, filters);\n if (missing.length > 0) {\n throw new CliError(`Unknown columns: ${missing.join(\", \")}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n}\n\nexport function applyContainsFilters(\n source: DataPreviewSource,\n filters: readonly DataPreviewContainsFilter[],\n): DataPreviewSource {\n if (filters.length === 0) {\n return source;\n }\n\n if (!(source instanceof InMemoryDataPreviewSource)) {\n throw new CliError(\"Contains filtering is only supported for in-memory preview sources.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n assertContainsFilterColumns(source, filters);\n return source.filterContains(filters);\n}\n\nexport function createDataPreviewSource(inputPath: string, text: string): DataPreviewSource {\n const extension = extname(inputPath).toLowerCase();\n\n if (extension === \".csv\") {\n return createCsvPreviewSource(text);\n }\n if (extension === \".json\") {\n return createJsonPreviewSource(text);\n }\n\n throw new CliError(`Unsupported preview file type: ${extension || \"(none)\"}. Expected .csv or .json.`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n","import { formatPathForDisplay } from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\nimport { getCliColors } from \"../colors\";\nimport type { DataPreviewContainsFilter, DataPreviewRow, DataPreviewSource } from \"./source\";\n\nexport interface RenderDataPreviewOptions {\n columns?: string[];\n containsFilters?: readonly DataPreviewContainsFilter[];\n inputPath: string;\n offset: number;\n rowCount: number;\n}\n\nexport interface RenderDataPreviewResult {\n lines: string[];\n}\n\nexport interface RenderDataPreviewSource {\n columns: string[];\n format: string;\n totalRows: number;\n getWindow(offset: number, rowCount: number): DataPreviewRow[];\n}\n\ninterface VisibleColumn {\n name: string;\n width: number;\n}\n\nconst DEFAULT_NON_TTY_WIDTH = 120;\nconst DEFAULT_TTY_WIDTH = 100;\nconst MAX_COLUMN_WIDTH = 32;\nconst MIN_COLUMN_WIDTH = 3;\nconst COLUMN_SEPARATOR = \" | \";\n\nfunction resolveRenderWidth(runtime: CliRuntime): number {\n const stream = runtime.stdout as NodeJS.WritableStream & { columns?: number; isTTY?: boolean };\n if (stream.isTTY && typeof stream.columns === \"number\" && Number.isFinite(stream.columns)) {\n return Math.max(20, Math.floor(stream.columns));\n }\n if (stream.isTTY) {\n return DEFAULT_TTY_WIDTH;\n }\n return DEFAULT_NON_TTY_WIDTH;\n}\n\nfunction truncateCell(value: string, width: number): string {\n if (width <= 0) {\n return \"\";\n }\n if (value.length <= width) {\n return value.padEnd(width, \" \");\n }\n if (width <= 3) {\n return \".\".repeat(width);\n }\n return `${value.slice(0, width - 3)}...`;\n}\n\nfunction createSeparator(widths: readonly number[]): string {\n return widths.map((width) => \"-\".repeat(Math.max(1, width))).join(\"-+-\");\n}\n\nfunction dedupeRequestedColumns(columns: readonly string[] | undefined): string[] {\n if (!columns) {\n return [];\n }\n\n const values: string[] = [];\n const seen = new Set<string>();\n for (const column of columns.map((item) => item.trim()).filter((item) => item.length > 0)) {\n if (seen.has(column)) {\n continue;\n }\n seen.add(column);\n values.push(column);\n }\n return values;\n}\n\nfunction resolveRequestedColumns(\n source: RenderDataPreviewSource,\n requestedColumns: readonly string[] | undefined,\n): string[] {\n const deduped = dedupeRequestedColumns(requestedColumns);\n if (deduped.length === 0) {\n return [...source.columns];\n }\n\n const available = new Set(source.columns);\n const missing = deduped.filter((column) => !available.has(column));\n if (missing.length > 0) {\n throw new Error(`Unknown columns: ${missing.join(\", \")}`);\n }\n\n return deduped;\n}\n\nfunction measureColumnWidth(name: string, rows: readonly DataPreviewRow[]): number {\n let width = name.length;\n for (const row of rows) {\n width = Math.max(width, row.values[name]?.length ?? 0);\n }\n return Math.max(MIN_COLUMN_WIDTH, Math.min(MAX_COLUMN_WIDTH, width));\n}\n\nfunction resolveVisibleColumns(\n columns: readonly string[],\n rows: readonly DataPreviewRow[],\n budget: number,\n): VisibleColumn[] {\n if (columns.length === 0) {\n return [];\n }\n\n const visible: VisibleColumn[] = [];\n let consumed = 0;\n\n for (const column of columns) {\n const separatorWidth = visible.length > 0 ? COLUMN_SEPARATOR.length : 0;\n const remaining = budget - consumed - separatorWidth;\n if (remaining < MIN_COLUMN_WIDTH && visible.length > 0) {\n break;\n }\n\n const targetWidth = measureColumnWidth(column, rows);\n const width = Math.max(1, Math.min(targetWidth, remaining));\n if (width < MIN_COLUMN_WIDTH && visible.length > 0) {\n break;\n }\n\n visible.push({\n name: column,\n width,\n });\n consumed += separatorWidth + width;\n }\n\n return visible.length > 0 ? visible : [{ name: columns[0] ?? \"value\", width: Math.max(1, budget) }];\n}\n\nfunction formatColumnSummary(allColumns: readonly string[], visibleColumns: readonly VisibleColumn[]): string {\n if (visibleColumns.length === 0) {\n return \"(none)\";\n }\n\n const hiddenCount = Math.max(0, allColumns.length - visibleColumns.length);\n const visibleLabel = visibleColumns.map((column) => column.name).join(\", \");\n if (hiddenCount === 0) {\n return visibleLabel;\n }\n return `${visibleLabel} (+${hiddenCount} hidden)`;\n}\n\nfunction formatWindowLabel(offset: number, rowCount: number, totalRows: number): string {\n if (totalRows === 0 || rowCount === 0 || offset >= totalRows) {\n return `0 rows at offset ${offset}`;\n }\n\n const start = offset + 1;\n const end = Math.min(totalRows, offset + rowCount);\n return `${start}-${end} of ${totalRows}`;\n}\n\nfunction resolveContainsFilterColumns(filters: readonly DataPreviewContainsFilter[] | undefined): string[] {\n if (!filters || filters.length === 0) {\n return [];\n }\n\n const columns: string[] = [];\n const seen = new Set<string>();\n for (const filter of filters) {\n if (seen.has(filter.column)) {\n continue;\n }\n seen.add(filter.column);\n columns.push(filter.column);\n }\n return columns;\n}\n\nfunction resolveHiddenContainsColumns(\n filters: readonly DataPreviewContainsFilter[] | undefined,\n visibleColumns: readonly VisibleColumn[],\n): string[] {\n const visibleNames = new Set(visibleColumns.map((column) => column.name));\n return resolveContainsFilterColumns(filters).filter((column) => !visibleNames.has(column));\n}\n\nfunction formatHiddenContainsNote(hiddenColumns: readonly string[]): string {\n if (hiddenColumns.length === 0) {\n return \"\";\n }\n return `hidden matching columns: ${hiddenColumns.join(\", \")}`;\n}\n\nfunction renderTable(\n runtime: CliRuntime,\n visibleColumns: readonly VisibleColumn[],\n rows: readonly DataPreviewRow[],\n options: { containsFilters?: readonly DataPreviewContainsFilter[] } = {},\n): string[] {\n if (visibleColumns.length === 0) {\n return [\"(no columns to display)\"];\n }\n\n const pc = getCliColors(runtime);\n const widths = visibleColumns.map((column) => column.width);\n const highlightedColumns = new Set(resolveContainsFilterColumns(options.containsFilters));\n const header = visibleColumns\n .map((column) => pc.bold(pc.cyan(truncateCell(column.name, column.width).padEnd(column.width, \" \"))))\n .join(COLUMN_SEPARATOR);\n const separator = createSeparator(widths);\n const body = rows.map((row) =>\n visibleColumns\n .map((column) => {\n const cell = truncateCell(row.values[column.name] ?? \"\", column.width);\n if (!highlightedColumns.has(column.name)) {\n return cell;\n }\n return pc.bold(pc.yellow(cell));\n })\n .join(COLUMN_SEPARATOR),\n );\n\n if (body.length === 0) {\n return [header, separator];\n }\n\n return [header, separator, ...body];\n}\n\nexport function renderDataPreview(\n runtime: CliRuntime,\n source: RenderDataPreviewSource,\n options: RenderDataPreviewOptions,\n): RenderDataPreviewResult {\n const pc = getCliColors(runtime);\n const widthBudget = resolveRenderWidth(runtime);\n const selectedColumns = resolveRequestedColumns(source, options.columns);\n const rows = source.getWindow(options.offset, options.rowCount);\n const visibleColumns = resolveVisibleColumns(selectedColumns, rows, widthBudget);\n const hiddenContainsColumns = resolveHiddenContainsColumns(options.containsFilters, visibleColumns);\n\n const lines = [\n `${pc.bold(pc.cyan(\"Input\"))}: ${formatPathForDisplay(runtime, options.inputPath)}`,\n `${pc.bold(pc.cyan(\"Format\"))}: ${source.format}`,\n `${pc.bold(pc.cyan(\"Rows\"))}: ${source.totalRows}`,\n `${pc.bold(pc.cyan(\"Window\"))}: ${formatWindowLabel(options.offset, rows.length, source.totalRows)}`,\n `${pc.bold(pc.cyan(\"Visible columns\"))}: ${formatColumnSummary(selectedColumns, visibleColumns)}`,\n ...(hiddenContainsColumns.length > 0\n ? [`${pc.bold(pc.cyan(\"Contains highlight\"))}: ${formatHiddenContainsNote(hiddenContainsColumns)}`]\n : []),\n \"\",\n ...renderTable(runtime, visibleColumns, rows, { containsFilters: options.containsFilters }),\n ];\n\n return { lines };\n}\n\nexport function renderInMemoryDataPreview(\n runtime: CliRuntime,\n source: DataPreviewSource,\n options: RenderDataPreviewOptions,\n): RenderDataPreviewResult {\n return renderDataPreview(runtime, source, options);\n}\n","import { readTextFileRequired, resolveFromCwd } from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\nimport { printLine, assertNonEmpty, ensureFileExists } from \"./shared\";\nimport {\n applyContainsFilters,\n createDataPreviewSource,\n parseContainsFilterValues,\n type DataPreviewSource,\n} from \"../data-preview/source\";\nimport { renderInMemoryDataPreview } from \"../data-preview/render\";\nimport { CliError } from \"../errors\";\n\nexport interface DataPreviewOptions {\n columns?: string[];\n contains?: string[];\n input: string;\n offset?: number;\n rows?: number;\n}\n\nconst DEFAULT_DATA_PREVIEW_ROWS = 20;\n\nexport async function loadDataPreviewSource(\n runtime: CliRuntime,\n input: string,\n): Promise<{ inputPath: string; source: DataPreviewSource }> {\n const inputPath = resolveFromCwd(runtime, assertNonEmpty(input, \"Input path\"));\n await ensureFileExists(inputPath, \"Input\");\n\n const raw = await readTextFileRequired(inputPath);\n return {\n inputPath,\n source: createDataPreviewSource(inputPath, raw),\n };\n}\n\nexport async function actionDataPreview(runtime: CliRuntime, options: DataPreviewOptions): Promise<void> {\n const { inputPath, source: loadedSource } = await loadDataPreviewSource(runtime, options.input);\n const containsFilters = parseContainsFilterValues(options.contains);\n let source = loadedSource;\n if (containsFilters.length > 0) {\n source = applyContainsFilters(source, containsFilters);\n }\n const rowCount = options.rows ?? DEFAULT_DATA_PREVIEW_ROWS;\n const offset = options.offset ?? 0;\n\n try {\n const result = renderInMemoryDataPreview(runtime, source, {\n columns: options.columns,\n containsFilters,\n inputPath,\n offset,\n rowCount,\n });\n\n result.lines.forEach((line) => {\n printLine(runtime.stdout, line);\n });\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n if (error instanceof Error && error.message.startsWith(\"Unknown columns:\")) {\n throw new CliError(error.message, { code: \"INVALID_INPUT\", exitCode: 2 });\n }\n throw error;\n }\n}\n","import type { DuckDBConnection } from \"@duckdb/node-api\";\n\nimport { CliError } from \"../errors\";\nimport { stringifyPreviewValue } from \"../data-preview/normalize\";\nimport type { DataPreviewRow } from \"../data-preview/source\";\n\nexport interface LoadParquetPreviewWindowOptions {\n columns?: readonly string[];\n inputPath: string;\n offset: number;\n rowCount: number;\n}\n\nexport interface ParquetPreviewWindow {\n allColumns: string[];\n rows: DataPreviewRow[];\n totalRows: number;\n}\n\nfunction quoteSqlIdentifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction validateRequestedColumns(\n availableColumns: readonly string[],\n requestedColumns: readonly string[] | undefined,\n): string[] {\n const normalized = requestedColumns\n ?.map((column) => column.trim())\n .filter((column) => column.length > 0);\n\n if (!normalized || normalized.length === 0) {\n return [...availableColumns];\n }\n\n const selected: string[] = [];\n const seen = new Set<string>();\n for (const column of normalized) {\n if (seen.has(column)) {\n continue;\n }\n selected.push(column);\n seen.add(column);\n }\n\n const available = new Set(availableColumns);\n const missing = selected.filter((column) => !available.has(column));\n if (missing.length > 0) {\n throw new CliError(`Unknown columns: ${missing.join(\", \")}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n return selected;\n}\n\nasync function createDuckDbConnection(): Promise<DuckDBConnection> {\n try {\n const duckdb = await import(\"@duckdb/node-api\");\n return await duckdb.DuckDBConnection.create();\n } catch (error) {\n throw new CliError(`DuckDB is unavailable for Parquet preview: ${toErrorMessage(error)}`, {\n code: \"DUCKDB_UNAVAILABLE\",\n exitCode: 2,\n });\n }\n}\n\nasync function readParquetColumns(connection: DuckDBConnection, inputPath: string): Promise<string[]> {\n const reader = await connection.runAndReadAll(\"select * from read_parquet(?) limit 0\", [inputPath]);\n return reader.columnNames();\n}\n\nasync function readParquetTotalRows(connection: DuckDBConnection, inputPath: string): Promise<number> {\n const reader = await connection.runAndReadAll(\"select count(*) as total_rows from read_parquet(?)\", [inputPath]);\n const rows = reader.getRowObjectsJson();\n return Number(rows[0]?.total_rows ?? 0);\n}\n\nasync function readParquetWindowRows(\n connection: DuckDBConnection,\n inputPath: string,\n columns: readonly string[],\n offset: number,\n rowCount: number,\n): Promise<DataPreviewRow[]> {\n const projection = columns.map((column) => quoteSqlIdentifier(column)).join(\", \");\n const reader = await connection.runAndReadAll(\n `select ${projection} from read_parquet(?) limit ? offset ?`,\n [inputPath, rowCount, offset],\n );\n const rowObjects = reader.getRowObjectsJson();\n\n return rowObjects.map((row) => {\n const values: Record<string, string> = {};\n for (const column of columns) {\n values[column] = stringifyPreviewValue(row[column]);\n }\n return { values };\n });\n}\n\nexport async function loadParquetPreviewWindow(\n options: LoadParquetPreviewWindowOptions,\n): Promise<ParquetPreviewWindow> {\n let connection: DuckDBConnection | undefined;\n try {\n connection = await createDuckDbConnection();\n const allColumns = await readParquetColumns(connection, options.inputPath);\n const selectedColumns = validateRequestedColumns(allColumns, options.columns);\n const totalRows = await readParquetTotalRows(connection, options.inputPath);\n const rows = await readParquetWindowRows(\n connection,\n options.inputPath,\n selectedColumns,\n options.offset,\n options.rowCount,\n );\n\n return {\n allColumns,\n rows,\n totalRows,\n };\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n throw new CliError(`Failed to preview Parquet file: ${toErrorMessage(error)}`, {\n code: \"PARQUET_PREVIEW_FAILED\",\n exitCode: 2,\n });\n } finally {\n connection?.closeSync();\n }\n}\n","import { extname } from \"node:path\";\n\nimport { resolveFromCwd } from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\nimport { renderDataPreview, type RenderDataPreviewSource } from \"../data-preview/render\";\nimport { loadParquetPreviewWindow } from \"../duckdb/parquet-preview\";\nimport { CliError } from \"../errors\";\nimport { assertNonEmpty, ensureFileExists, printLine } from \"./shared\";\n\nexport interface DataParquetPreviewOptions {\n columns?: string[];\n input: string;\n offset?: number;\n rows?: number;\n}\n\nconst DEFAULT_PARQUET_PREVIEW_ROWS = 20;\n\nexport async function actionDataParquetPreview(\n runtime: CliRuntime,\n options: DataParquetPreviewOptions,\n): Promise<void> {\n const inputPath = resolveFromCwd(runtime, assertNonEmpty(options.input, \"Input path\"));\n await ensureFileExists(inputPath, \"Input\");\n\n if (extname(inputPath).toLowerCase() !== \".parquet\") {\n throw new CliError(\"Parquet preview requires a .parquet input file.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const rowCount = options.rows ?? DEFAULT_PARQUET_PREVIEW_ROWS;\n const offset = options.offset ?? 0;\n const preview = await loadParquetPreviewWindow({\n columns: options.columns,\n inputPath,\n offset,\n rowCount,\n });\n\n const source: RenderDataPreviewSource = {\n columns: preview.allColumns,\n format: \"parquet\",\n totalRows: preview.totalRows,\n getWindow(requestedOffset, requestedRowCount) {\n const start = Math.max(0, requestedOffset - offset);\n return preview.rows.slice(start, start + requestedRowCount);\n },\n };\n\n const result = renderDataPreview(runtime, source, {\n columns: options.columns,\n inputPath,\n offset,\n rowCount,\n });\n\n result.lines.forEach((line) => {\n printLine(runtime.stdout, line);\n });\n}\n","import { getCliColors } from \"../colors\";\nimport {\n createDuckDbExtensionInstallCommand,\n DUCKDB_MANAGED_EXTENSION_NAMES,\n installDuckDbManagedExtension,\n probeDuckDbManagedExtension,\n sanitizeDuckDbPathForDisplay,\n type DuckDbManagedExtensionName,\n type DuckDbManagedExtensionProbe,\n} from \"../duckdb/extensions\";\nimport { createDuckDbConnection } from \"../duckdb/query\";\nimport { CliError } from \"../errors\";\nimport type { CliRuntime } from \"../types\";\nimport { printLine } from \"./shared\";\n\nexport interface DataDuckDbDoctorOptions {\n json?: boolean;\n}\n\nexport interface DataDuckDbExtensionInstallOptions {\n allSupported?: boolean;\n extensionName?: DuckDbManagedExtensionName;\n}\n\nfunction formatInstallability(value: boolean | null): string {\n if (value === null) {\n return \"unknown\";\n }\n return value ? \"yes\" : \"no\";\n}\n\nfunction buildDuckDbDoctorPayload(\n runtime: CliRuntime,\n probes: readonly DuckDbManagedExtensionProbe[],\n) {\n return {\n generatedAt: runtime.now().toISOString(),\n duckdb: {\n runtimeVersion: probes[0]?.runtimeVersion ?? \"unknown\",\n extensions: Object.fromEntries(\n probes.map((probe) => [\n probe.name,\n {\n cacheDirectory: probe.cacheDirectory\n ? sanitizeDuckDbPathForDisplay(probe.cacheDirectory)\n : undefined,\n cacheFilePath: probe.cacheFilePath\n ? sanitizeDuckDbPathForDisplay(probe.cacheFilePath)\n : undefined,\n detail: probe.detail,\n installability: probe.installable,\n installed: probe.installed,\n loadability: probe.loadable,\n loaded: probe.loaded,\n },\n ]),\n ),\n },\n };\n}\n\nfunction renderDuckDbProbe(\n runtime: CliRuntime,\n probe: DuckDbManagedExtensionProbe,\n): void {\n const pc = getCliColors(runtime);\n printLine(\n runtime.stdout,\n `- ${pc.bold(probe.name)}: installed=${probe.installed ? \"yes\" : \"no\"}, loadability=${probe.loadable ? \"yes\" : \"no\"}, installability=${formatInstallability(probe.installable)}`,\n );\n\n if (probe.cacheFilePath) {\n printLine(runtime.stdout, ` ${pc.dim(`Cache: ${sanitizeDuckDbPathForDisplay(probe.cacheFilePath)}`)}`);\n } else if (probe.cacheDirectory) {\n printLine(\n runtime.stdout,\n ` ${pc.dim(`Cache directory: ${sanitizeDuckDbPathForDisplay(probe.cacheDirectory)}`)}`,\n );\n }\n\n if (probe.detail) {\n printLine(runtime.stdout, ` ${pc.dim(probe.detail)}`);\n }\n\n if (!probe.loadable && probe.installable === true) {\n printLine(\n runtime.stdout,\n ` ${pc.yellow(`Try: ${createDuckDbExtensionInstallCommand(probe.name)}`)}`,\n );\n }\n}\n\nexport async function actionDataDuckDbDoctor(\n runtime: CliRuntime,\n options: DataDuckDbDoctorOptions = {},\n): Promise<void> {\n let connection: Awaited<ReturnType<typeof createDuckDbConnection>> | undefined;\n try {\n connection = await createDuckDbConnection();\n const activeConnection = connection;\n const probes = await Promise.all(\n DUCKDB_MANAGED_EXTENSION_NAMES.map((name) => probeDuckDbManagedExtension(activeConnection, name)),\n );\n\n if (options.json) {\n printLine(runtime.stdout, JSON.stringify(buildDuckDbDoctorPayload(runtime, probes), null, 2));\n return;\n }\n\n const pc = getCliColors(runtime);\n printLine(runtime.stdout, pc.bold(pc.cyan(\"cdx-chores data duckdb doctor\")));\n printLine(runtime.stdout, `${pc.dim(\"Platform:\")} ${pc.white(runtime.platform)}`);\n printLine(runtime.stdout, `${pc.dim(\"Node.js:\")} ${pc.white(process.version)}`);\n printLine(\n runtime.stdout,\n `${pc.dim(\"DuckDB runtime:\")} ${pc.white(probes[0]?.runtimeVersion ?? \"unknown\")}`,\n );\n printLine(runtime.stdout);\n printLine(runtime.stdout, pc.bold(pc.cyan(\"Managed extensions:\")));\n\n for (const probe of probes) {\n renderDuckDbProbe(runtime, probe);\n }\n } finally {\n connection?.closeSync();\n }\n}\n\nfunction resolveDuckDbInstallTargets(\n options: DataDuckDbExtensionInstallOptions,\n): DuckDbManagedExtensionName[] {\n if (options.allSupported) {\n return [...DUCKDB_MANAGED_EXTENSION_NAMES];\n }\n if (options.extensionName) {\n return [options.extensionName];\n }\n return [];\n}\n\nexport async function actionDataDuckDbExtensionInstall(\n runtime: CliRuntime,\n options: DataDuckDbExtensionInstallOptions,\n): Promise<void> {\n const targets = resolveDuckDbInstallTargets(options);\n if (targets.length === 0) {\n throw new CliError(\n `Extension name is required unless --all-supported is used. Supported names: ${DUCKDB_MANAGED_EXTENSION_NAMES.join(\", \")}.`,\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n }\n let connection: Awaited<ReturnType<typeof createDuckDbConnection>> | undefined;\n try {\n connection = await createDuckDbConnection();\n for (const [index, name] of targets.entries()) {\n if (index > 0) {\n printLine(runtime.stdout);\n }\n await installDuckDbManagedExtension(connection, name, {\n statusStream: runtime.stdout,\n });\n }\n } finally {\n connection?.closeSync();\n }\n}\n","import { formatPathForDisplay } from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\nimport { getCliColors } from \"../colors\";\nimport type { DataPreviewRow } from \"../data-preview/source\";\n\nexport interface RenderDataQueryOptions {\n columns: string[];\n format: string;\n inputPath: string;\n rows: DataPreviewRow[];\n source?: string;\n truncated: boolean;\n}\n\nexport interface RenderDataQueryResult {\n lines: string[];\n}\n\ninterface VisibleColumn {\n name: string;\n width: number;\n}\n\nconst DEFAULT_NON_TTY_WIDTH = 120;\nconst DEFAULT_TTY_WIDTH = 100;\nconst MAX_COLUMN_WIDTH = 32;\nconst MIN_COLUMN_WIDTH = 3;\nconst COLUMN_SEPARATOR = \" | \";\n\nfunction resolveRenderWidth(runtime: CliRuntime): number {\n const stream = runtime.stdout as NodeJS.WritableStream & { columns?: number; isTTY?: boolean };\n if (stream.isTTY && typeof stream.columns === \"number\" && Number.isFinite(stream.columns)) {\n return Math.max(20, Math.floor(stream.columns));\n }\n if (stream.isTTY) {\n return DEFAULT_TTY_WIDTH;\n }\n return DEFAULT_NON_TTY_WIDTH;\n}\n\nfunction truncateCell(value: string, width: number): string {\n if (width <= 0) {\n return \"\";\n }\n if (value.length <= width) {\n return value.padEnd(width, \" \");\n }\n if (width <= 3) {\n return \".\".repeat(width);\n }\n return `${value.slice(0, width - 3)}...`;\n}\n\nfunction createSeparator(widths: readonly number[]): string {\n return widths.map((width) => \"-\".repeat(Math.max(1, width))).join(\"-+-\");\n}\n\nfunction measureColumnWidth(name: string, rows: readonly DataPreviewRow[]): number {\n let width = name.length;\n for (const row of rows) {\n width = Math.max(width, row.values[name]?.length ?? 0);\n }\n return Math.max(MIN_COLUMN_WIDTH, Math.min(MAX_COLUMN_WIDTH, width));\n}\n\nfunction resolveVisibleColumns(\n columns: readonly string[],\n rows: readonly DataPreviewRow[],\n budget: number,\n): VisibleColumn[] {\n if (columns.length === 0) {\n return [];\n }\n\n const visible: VisibleColumn[] = [];\n let consumed = 0;\n\n for (const column of columns) {\n const separatorWidth = visible.length > 0 ? COLUMN_SEPARATOR.length : 0;\n const remaining = budget - consumed - separatorWidth;\n if (remaining < MIN_COLUMN_WIDTH && visible.length > 0) {\n break;\n }\n\n const targetWidth = measureColumnWidth(column, rows);\n const width = Math.max(1, Math.min(targetWidth, remaining));\n if (width < MIN_COLUMN_WIDTH && visible.length > 0) {\n break;\n }\n\n visible.push({ name: column, width });\n consumed += separatorWidth + width;\n }\n\n return visible.length > 0 ? visible : [{ name: columns[0] ?? \"value\", width: Math.max(1, budget) }];\n}\n\nfunction formatColumnSummary(allColumns: readonly string[], visibleColumns: readonly VisibleColumn[]): string {\n if (visibleColumns.length === 0) {\n return \"(none)\";\n }\n\n const hiddenCount = Math.max(0, allColumns.length - visibleColumns.length);\n const visibleLabel = visibleColumns.map((column) => column.name).join(\", \");\n if (hiddenCount === 0) {\n return visibleLabel;\n }\n return `${visibleLabel} (+${hiddenCount} hidden)`;\n}\n\nfunction renderTable(\n runtime: CliRuntime,\n visibleColumns: readonly VisibleColumn[],\n rows: readonly DataPreviewRow[],\n): string[] {\n if (visibleColumns.length === 0) {\n return [\"(no columns to display)\"];\n }\n\n const pc = getCliColors(runtime);\n const widths = visibleColumns.map((column) => column.width);\n const header = visibleColumns\n .map((column) => pc.bold(pc.cyan(truncateCell(column.name, column.width).padEnd(column.width, \" \"))))\n .join(COLUMN_SEPARATOR);\n const separator = createSeparator(widths);\n const body = rows.map((row) =>\n visibleColumns\n .map((column) => truncateCell(row.values[column.name] ?? \"\", column.width))\n .join(COLUMN_SEPARATOR),\n );\n\n if (body.length === 0) {\n return [header, separator];\n }\n\n return [header, separator, ...body];\n}\n\nexport function renderDataQuery(\n runtime: CliRuntime,\n options: RenderDataQueryOptions,\n): RenderDataQueryResult {\n const pc = getCliColors(runtime);\n const widthBudget = resolveRenderWidth(runtime);\n const visibleColumns = resolveVisibleColumns(options.columns, options.rows, widthBudget);\n const resultRowsLabel = options.truncated\n ? `${options.rows.length}+ (bounded)`\n : String(options.rows.length);\n\n const lines = [\n `${pc.bold(pc.cyan(\"Input\"))}: ${formatPathForDisplay(runtime, options.inputPath)}`,\n `${pc.bold(pc.cyan(\"Format\"))}: ${options.format}`,\n ...(options.source\n ? [`${pc.bold(pc.cyan(\"Source\"))}: ${options.source}`]\n : []),\n `${pc.bold(pc.cyan(\"Result rows\"))}: ${resultRowsLabel}`,\n `${pc.bold(pc.cyan(\"Visible columns\"))}: ${formatColumnSummary(options.columns, visibleColumns)}`,\n \"\",\n ...renderTable(runtime, visibleColumns, options.rows),\n ];\n\n return { lines };\n}\n","import { extname } from \"node:path\";\n\nimport { stringifyCsv } from \"../../utils/csv\";\nimport { renderDataQuery } from \"../data-query/render\";\nimport { CliError } from \"../errors\";\nimport { displayPath, assertNonEmpty, ensureFileExists, printLine } from \"./shared\";\nimport { resolveFromCwd, writeTextFileSafe } from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\nimport {\n type DataQueryInputFormat,\n createDuckDbConnection,\n detectDataQueryInputFormat,\n executeDataQueryForAllRows,\n executeDataQueryForTable,\n prepareDataQuerySource,\n} from \"../duckdb/query\";\n\nexport interface DataQueryOptions {\n installMissingExtension?: boolean;\n input: string;\n inputFormat?: DataQueryInputFormat;\n json?: boolean;\n output?: string;\n overwrite?: boolean;\n pretty?: boolean;\n rows?: number;\n source?: string;\n sql: string;\n}\n\nconst DEFAULT_QUERY_ROWS = 20;\n\nfunction normalizeOutputExtension(outputPath: string): \".csv\" | \".json\" {\n const extension = extname(outputPath).toLowerCase();\n if (extension === \".json\" || extension === \".csv\") {\n return extension;\n }\n throw new CliError(\"Unsupported --output extension. Use .json or .csv.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n\nfunction validateDataQueryOptions(options: DataQueryOptions): void {\n if (options.json && options.output) {\n throw new CliError(\"--json cannot be used together with --output.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const outputExtension = options.output ? normalizeOutputExtension(options.output) : undefined;\n if (options.pretty && !options.json && outputExtension !== \".json\") {\n throw new CliError(\"--pretty requires either --json or a .json --output path.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n}\n\nfunction isDuckDbBuiltInQueryFormat(format: DataQueryInputFormat): boolean {\n return format === \"csv\" || format === \"tsv\" || format === \"parquet\";\n}\n\nfunction normalizeSql(sql: string): string {\n const value = assertNonEmpty(sql, \"SQL\");\n return value.endsWith(\";\") ? value : value;\n}\n\nfunction normalizeCsvExportRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n return rows.map((row) =>\n Object.fromEntries(\n Object.entries(row).map(([key, value]) => {\n if (value === null || value === undefined) {\n return [key, \"\"];\n }\n if (typeof value === \"object\") {\n return [key, JSON.stringify(value)];\n }\n return [key, value];\n }),\n ),\n );\n}\n\nexport async function actionDataQuery(runtime: CliRuntime, options: DataQueryOptions): Promise<void> {\n validateDataQueryOptions(options);\n\n const inputPath = resolveFromCwd(runtime, assertNonEmpty(options.input, \"Input path\"));\n await ensureFileExists(inputPath, \"Input\");\n\n const sql = normalizeSql(options.sql);\n const outputPath = options.output?.trim() ? resolveFromCwd(runtime, options.output.trim()) : undefined;\n const format = detectDataQueryInputFormat(inputPath, options.inputFormat);\n if (options.installMissingExtension && isDuckDbBuiltInQueryFormat(format)) {\n throw new CliError(\n \"--install-missing-extension is only valid for extension-backed query formats (sqlite, excel).\",\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n }\n const source = options.source?.trim() || undefined;\n const rowCount = options.rows ?? DEFAULT_QUERY_ROWS;\n\n let connection;\n try {\n connection = await createDuckDbConnection();\n const preparedSource = await prepareDataQuerySource(connection, inputPath, format, source, {\n installMissingExtension: options.installMissingExtension,\n statusStream: runtime.stderr,\n });\n\n if (options.json) {\n const result = await executeDataQueryForAllRows(connection, sql);\n printLine(runtime.stdout, `${JSON.stringify(result.rows, null, options.pretty ? 2 : 0)}\\n`.trimEnd());\n return;\n }\n\n if (outputPath) {\n const result = await executeDataQueryForAllRows(connection, sql);\n const outputExtension = normalizeOutputExtension(outputPath);\n if (outputExtension === \".json\") {\n const json = `${JSON.stringify(result.rows, null, options.pretty ? 2 : 0)}\\n`;\n await writeTextFileSafe(outputPath, json, { overwrite: options.overwrite });\n printLine(runtime.stderr, `Wrote JSON: ${displayPath(runtime, outputPath)}`);\n printLine(runtime.stderr, `Rows: ${result.rows.length}`);\n return;\n }\n\n const csv = stringifyCsv(normalizeCsvExportRows(result.rows));\n await writeTextFileSafe(outputPath, csv, { overwrite: options.overwrite });\n printLine(runtime.stderr, `Wrote CSV: ${displayPath(runtime, outputPath)}`);\n printLine(runtime.stderr, `Rows: ${result.rows.length}`);\n return;\n }\n\n const table = await executeDataQueryForTable(connection, sql, rowCount);\n const rendered = renderDataQuery(runtime, {\n columns: table.columns,\n format,\n inputPath,\n rows: table.rows,\n source: preparedSource.selectedSource,\n truncated: table.truncated,\n });\n\n for (const line of rendered.lines) {\n printLine(runtime.stdout, line);\n }\n } finally {\n connection?.closeSync();\n }\n}\n","import { createColors } from \"picocolors\";\nimport { printLine } from \"../actions/shared\";\n\nconst ANALYZER_WAITING_FRAMES = [\". \", \".. \", \"...\", \".. \", \". \"] as const;\nconst ANALYZER_WAITING_INTERVAL_MS = 360;\n\ninterface TtyWritableStream extends NodeJS.WritableStream {\n isTTY?: boolean;\n}\n\nexport interface InteractiveAnalyzerStatus {\n start(message: string): void;\n update(message: string): void;\n wait(message: string): void;\n stop(): void;\n}\n\nfunction clearStatusLine(stream: NodeJS.WritableStream): void {\n stream.write(\"\\r\\x1b[2K\");\n}\n\nfunction normalizeAnalyzerStatusMessage(message: string): string {\n if (message.includes(\"Sampling filenames\")) {\n return \"sampling\";\n }\n if (message.includes(\"Grouping filename patterns\")) {\n return \"grouping\";\n }\n if (message.includes(\"Waiting for Codex cleanup suggestions\")) {\n return \"waiting\";\n }\n return message;\n}\n\nfunction renderStatusLine(\n stream: NodeJS.WritableStream,\n message: string,\n colorEnabled: boolean,\n): void {\n const pc = createColors(colorEnabled);\n const normalizedMessage = normalizeAnalyzerStatusMessage(message);\n const content = ` ${pc.dim(\"Codex\")} ${pc.white(\"Thinking...\")} ${pc.dim(normalizedMessage)} `;\n stream.write(`\\r\\x1b[2K${pc.bgBlack(content)}`);\n}\n\nfunction renderWaitingStatusLine(\n stream: NodeJS.WritableStream,\n message: string,\n tick: number,\n colorEnabled: boolean,\n): void {\n const pc = createColors(colorEnabled);\n const normalizedMessage = normalizeAnalyzerStatusMessage(message);\n const dots =\n ANALYZER_WAITING_FRAMES[tick % ANALYZER_WAITING_FRAMES.length] ?? \"...\";\n const content = ` ${pc.dim(\"Codex\")} ${pc.white(\"Thinking\")} ${pc.dim(normalizedMessage)} ${pc.gray(dots)} `;\n stream.write(`\\r\\x1b[2K${pc.bgBlack(content)}`);\n}\n\nexport function createInteractiveAnalyzerStatus(\n stream: NodeJS.WritableStream,\n colorEnabled = true,\n): InteractiveAnalyzerStatus {\n const ttyStream = stream as TtyWritableStream;\n\n if (!ttyStream.isTTY) {\n return {\n start(message) {\n printLine(stream, message);\n },\n update(message) {\n printLine(stream, message);\n },\n wait(message) {\n printLine(stream, message);\n },\n stop() {},\n };\n }\n\n let currentMessage = \"\";\n let timer: ReturnType<typeof setInterval> | undefined;\n let tick = 0;\n\n const stopTimer = () => {\n if (!timer) {\n return;\n }\n clearInterval(timer);\n timer = undefined;\n };\n\n return {\n start(message) {\n stopTimer();\n currentMessage = message;\n renderStatusLine(stream, currentMessage, colorEnabled);\n },\n update(message) {\n stopTimer();\n currentMessage = message;\n renderStatusLine(stream, currentMessage, colorEnabled);\n },\n wait(message) {\n stopTimer();\n currentMessage = message;\n tick = 0;\n renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);\n timer = setInterval(() => {\n tick += 1;\n renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);\n }, ANALYZER_WAITING_INTERVAL_MS);\n },\n stop() {\n stopTimer();\n clearStatusLine(stream);\n },\n };\n}\n","import { getCliColors } from \"../colors\";\nimport type { CliRuntime } from \"../types\";\nimport { printLine } from \"../actions/shared\";\nimport { startCodexReadOnlyThread } from \"../../adapters/codex/shared\";\nimport type { DataQueryInputFormat, DataQuerySourceIntrospection } from \"../duckdb/query\";\n\nconst DATA_QUERY_CODEX_OUTPUT_SCHEMA = {\n type: \"object\",\n properties: {\n sql: {\n type: \"string\",\n },\n reasoning_summary: {\n type: \"string\",\n },\n },\n required: [\"sql\", \"reasoning_summary\"],\n additionalProperties: false,\n} as const;\n\nconst DATA_QUERY_CODEX_TIMEOUT_MS = 30_000;\nconst DATA_QUERY_CODEX_MAX_SAMPLE_VALUE_CHARS = 120;\nconst DATA_QUERY_CODEX_EDITOR_SCHEMA_COLUMNS = 8;\nconst DATA_QUERY_CODEX_EDITOR_SAMPLE_ROWS = 3;\n\nexport interface DataQueryCodexDraft {\n reasoningSummary: string;\n sql: string;\n}\n\nexport interface DataQueryCodexDraftResult {\n draft?: DataQueryCodexDraft;\n errorMessage?: string;\n}\n\nexport type DataQueryCodexRunner = (options: {\n prompt: string;\n workingDirectory: string;\n timeoutMs?: number;\n}) => Promise<string>;\n\nfunction truncateForPrompt(value: string, maxChars: number): string {\n if (value.length <= maxChars) {\n return value;\n }\n if (maxChars <= 3) {\n return value.slice(0, maxChars);\n }\n return `${value.slice(0, maxChars - 3)}...`;\n}\n\nfunction normalizePromptSampleRows(rows: readonly Record<string, string>[]): string[] {\n if (rows.length === 0) {\n return [\"(no sample rows available)\"];\n }\n\n return rows.map((row, index) => {\n const safeRow = Object.fromEntries(\n Object.entries(row).map(([key, value]) => [key, truncateForPrompt(value, DATA_QUERY_CODEX_MAX_SAMPLE_VALUE_CHARS)]),\n );\n return `${index + 1}. ${JSON.stringify(safeRow)}`;\n });\n}\n\nfunction summarizeEditorSchema(introspection: DataQuerySourceIntrospection): string {\n if (introspection.columns.length === 0) {\n return \"(no columns available)\";\n }\n\n const visibleColumns = introspection.columns\n .slice(0, DATA_QUERY_CODEX_EDITOR_SCHEMA_COLUMNS)\n .map((column) => `${column.name} (${column.type})`);\n const remainingColumns = introspection.columns.length - visibleColumns.length;\n return remainingColumns > 0\n ? `${visibleColumns.join(\", \")}, +${remainingColumns} more`\n : visibleColumns.join(\", \");\n}\n\nexport function normalizeDataQueryCodexIntent(intent: string): string {\n return intent\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .join(\" \")\n .trim();\n}\n\nexport function stripDataQueryCodexIntentCommentLines(intent: string): string {\n return intent\n .split(/\\r?\\n/)\n .filter((line) => !line.trimStart().startsWith(\"#\"))\n .join(\"\\n\");\n}\n\nexport function normalizeDataQueryCodexEditorIntent(intent: string): string {\n return normalizeDataQueryCodexIntent(stripDataQueryCodexIntentCommentLines(intent));\n}\n\nexport function buildDataQueryCodexIntentEditorTemplate(options: {\n format: DataQueryInputFormat;\n intent?: string;\n introspection: DataQuerySourceIntrospection;\n}): string {\n const sampleLines = normalizePromptSampleRows(\n options.introspection.sampleRows.slice(0, DATA_QUERY_CODEX_EDITOR_SAMPLE_ROWS),\n );\n const remainingSampleRows = options.introspection.sampleRows.length - sampleLines.length;\n const sampleOverflowLine =\n remainingSampleRows > 0\n ? `# ... +${remainingSampleRows} more sampled rows`\n : options.introspection.truncated\n ? \"# ... additional sampled rows omitted\"\n : undefined;\n\n return [\n \"# Query context for Codex drafting.\",\n \"# Logical table: file\",\n `# Format: ${options.format}`,\n ...(options.introspection.selectedSource\n ? [`# Source: ${options.introspection.selectedSource}`]\n : []),\n `# Schema: ${summarizeEditorSchema(options.introspection)}`,\n \"# Sample rows:\",\n ...sampleLines.map((line) => `# ${line}`),\n ...(sampleOverflowLine ? [sampleOverflowLine] : []),\n \"#\",\n \"# Write plain intent below. Comment lines starting with # are ignored.\",\n \"\",\n options.intent?.trim() ?? \"\",\n ].join(\"\\n\");\n}\n\nexport function buildDataQueryCodexPrompt(options: {\n format: DataQueryInputFormat;\n intent: string;\n introspection: DataQuerySourceIntrospection;\n}): string {\n const schemaLines =\n options.introspection.columns.length > 0\n ? options.introspection.columns.map((column, index) => `${index + 1}. ${column.name}: ${column.type}`)\n : [\"(no columns available)\"];\n const sampleLines = normalizePromptSampleRows(options.introspection.sampleRows);\n\n return [\n \"Draft one DuckDB SQL query for the logical table `file`.\",\n \"Return JSON only following the provided schema.\",\n \"\",\n \"Rules:\",\n \"- Use only the table name `file`.\",\n \"- Draft SQL only; do not execute it.\",\n \"- Keep the SQL readable and explicit.\",\n \"- Prefer named columns instead of `select *` when the intent does not require every column.\",\n \"- If the intent is slightly ambiguous, make the narrowest reasonable assumption and explain it briefly in reasoning_summary.\",\n \"\",\n `User intent: ${options.intent}`,\n `Detected format: ${options.format}`,\n `Selected source: ${options.introspection.selectedSource ?? \"(implicit single source)\"}`,\n \"\",\n `Schema (${options.introspection.columns.length} columns):`,\n ...schemaLines,\n \"\",\n `Sample rows (showing ${options.introspection.sampleRows.length}${options.introspection.truncated ? \"+\" : \"\"}):`,\n ...sampleLines,\n ].join(\"\\n\");\n}\n\nfunction parseDataQueryCodexDraft(finalResponse: string): DataQueryCodexDraft {\n const parsed = JSON.parse(finalResponse) as {\n reasoning_summary?: unknown;\n sql?: unknown;\n };\n\n const sql = typeof parsed.sql === \"string\" ? parsed.sql.trim() : \"\";\n if (!sql) {\n throw new Error(\"Codex drafting response did not include SQL.\");\n }\n\n const reasoningSummary =\n typeof parsed.reasoning_summary === \"string\" ? parsed.reasoning_summary.trim() : \"\";\n if (!reasoningSummary) {\n throw new Error(\"Codex drafting response did not include reasoning_summary.\");\n }\n\n return {\n reasoningSummary,\n sql,\n };\n}\n\nasync function runDataQueryCodexPrompt(options: {\n prompt: string;\n workingDirectory: string;\n timeoutMs?: number;\n}): Promise<string> {\n const thread = startCodexReadOnlyThread(options.workingDirectory);\n const turn = await thread.run([{ type: \"text\", text: options.prompt }], {\n outputSchema: DATA_QUERY_CODEX_OUTPUT_SCHEMA,\n signal: AbortSignal.timeout(options.timeoutMs ?? DATA_QUERY_CODEX_TIMEOUT_MS),\n });\n return turn.finalResponse;\n}\n\nexport async function draftDataQueryWithCodex(options: {\n format: DataQueryInputFormat;\n intent: string;\n introspection: DataQuerySourceIntrospection;\n runner?: DataQueryCodexRunner;\n timeoutMs?: number;\n workingDirectory: string;\n}): Promise<DataQueryCodexDraftResult> {\n try {\n const runner = options.runner ?? runDataQueryCodexPrompt;\n const normalizedIntent = normalizeDataQueryCodexIntent(options.intent);\n const finalResponse = await runner({\n prompt: buildDataQueryCodexPrompt({\n format: options.format,\n intent: normalizedIntent,\n introspection: options.introspection,\n }),\n workingDirectory: options.workingDirectory,\n timeoutMs: options.timeoutMs,\n });\n return {\n draft: parseDataQueryCodexDraft(finalResponse),\n };\n } catch (error) {\n return {\n errorMessage: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport function renderDataQueryCodexDraft(options: {\n draft: DataQueryCodexDraft;\n format: DataQueryInputFormat;\n intent: string;\n introspection: DataQuerySourceIntrospection;\n runtime: CliRuntime;\n}): void {\n const pc = getCliColors(options.runtime);\n const lines = [\n `${pc.bold(pc.cyan(\"Intent\"))}: ${pc.white(options.intent)}`,\n `${pc.bold(pc.cyan(\"Format\"))}: ${pc.white(options.format)}`,\n ...(options.introspection.selectedSource\n ? [`${pc.bold(pc.cyan(\"Source\"))}: ${pc.white(options.introspection.selectedSource)}`]\n : []),\n `${pc.bold(pc.cyan(\"Schema\"))}:`,\n ...(options.introspection.columns.length > 0\n ? options.introspection.columns.map(\n (column) =>\n `- ${pc.bold(column.name)}: ${pc.dim(column.type)}`,\n )\n : [`- ${pc.dim(\"(no columns available)\")}`]),\n `${pc.bold(pc.cyan(\"Sample Rows\"))}:`,\n ...(options.introspection.sampleRows.length > 0\n ? options.introspection.sampleRows.map(\n (row, index) => `- ${pc.dim(`${index + 1}.`)} ${pc.white(JSON.stringify(row))}`,\n )\n : [`- ${pc.dim(\"(no sample rows available)\")}`]),\n `${pc.bold(pc.cyan(\"Codex Summary\"))}: ${pc.white(options.draft.reasoningSummary)}`,\n \"\",\n `${pc.bold(pc.green(\"SQL\"))}:`,\n pc.yellow(options.draft.sql),\n ];\n\n for (const line of lines) {\n printLine(options.runtime.stdout, line);\n }\n}\n","import { resolveFromCwd } from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\nimport { createInteractiveAnalyzerStatus } from \"../interactive/analyzer-status\";\nimport {\n collectDataQuerySourceIntrospection,\n createDuckDbConnection,\n detectDataQueryInputFormat,\n type DataQueryInputFormat,\n} from \"../duckdb/query\";\nimport {\n draftDataQueryWithCodex,\n normalizeDataQueryCodexIntent,\n renderDataQueryCodexDraft,\n type DataQueryCodexRunner,\n} from \"../data-query/codex\";\nimport { CliError } from \"../errors\";\nimport { assertNonEmpty, ensureFileExists, printLine } from \"./shared\";\n\nconst DATA_QUERY_CODEX_SAMPLE_ROWS = 5;\n\nexport interface DataQueryCodexOptions {\n input: string;\n inputFormat?: DataQueryInputFormat;\n intent: string;\n printSql?: boolean;\n runner?: DataQueryCodexRunner;\n source?: string;\n timeoutMs?: number;\n}\n\nfunction classifyCodexDraftingFailure(message: string): { code: string; prefix: string } {\n if (\n /codex exec exited/i.test(message) ||\n /missing optional dependency/i.test(message) ||\n /spawn/i.test(message) ||\n /enoent/i.test(message) ||\n /auth/i.test(message) ||\n /sign in/i.test(message) ||\n /api key/i.test(message)\n ) {\n return {\n code: \"CODEX_UNAVAILABLE\",\n prefix: \"Codex drafting unavailable\",\n };\n }\n\n return {\n code: \"DATA_QUERY_CODEX_FAILED\",\n prefix: \"Codex drafting failed\",\n };\n}\n\nexport async function actionDataQueryCodex(\n runtime: CliRuntime,\n options: DataQueryCodexOptions,\n): Promise<void> {\n const input = assertNonEmpty(options.input, \"Input path\");\n const inputPath = resolveFromCwd(runtime, input);\n await ensureFileExists(inputPath, \"Input\");\n\n const intent = normalizeDataQueryCodexIntent(assertNonEmpty(options.intent, \"Intent\"));\n const format = detectDataQueryInputFormat(inputPath, options.inputFormat);\n const source = options.source?.trim() || undefined;\n const statusStream = runtime.stdout as NodeJS.WritableStream & { isTTY?: boolean };\n const status = statusStream.isTTY\n ? createInteractiveAnalyzerStatus(runtime.stdout, runtime.colorEnabled)\n : {\n start() {},\n update() {},\n wait() {},\n stop() {},\n };\n\n let connection;\n try {\n connection = await createDuckDbConnection();\n status.start(\"Introspecting data source...\");\n const introspection = await collectDataQuerySourceIntrospection(\n connection,\n inputPath,\n format,\n source,\n DATA_QUERY_CODEX_SAMPLE_ROWS,\n );\n status.wait(\"Drafting SQL with Codex\");\n const draftResult = await draftDataQueryWithCodex({\n format,\n intent,\n introspection,\n runner: options.runner,\n timeoutMs: options.timeoutMs,\n workingDirectory: runtime.cwd,\n });\n\n if (!draftResult.draft) {\n const message = draftResult.errorMessage ?? \"Unknown Codex drafting failure.\";\n const failure = classifyCodexDraftingFailure(message);\n throw new CliError(`${failure.prefix}: ${message}`, {\n code: failure.code,\n exitCode: 2,\n });\n }\n\n status.stop();\n\n if (options.printSql) {\n printLine(runtime.stdout, draftResult.draft.sql);\n return;\n }\n\n renderDataQueryCodexDraft({\n draft: draftResult.draft,\n format,\n intent,\n introspection,\n runtime,\n });\n } finally {\n status.stop();\n connection?.closeSync();\n }\n}\n","import { csvRowsToObjects, parseCsv, stringifyCsv } from \"../../utils/csv\";\nimport { normalizeRowsFromJson } from \"../data-preview/normalize\";\nimport { CliError } from \"../errors\";\nimport {\n defaultOutputPath,\n readTextFileRequired,\n resolveFromCwd,\n writeTextFileSafe,\n} from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\nimport { assertNonEmpty, displayPath, ensureFileExists, printLine } from \"./shared\";\n\nexport interface JsonToCsvOptions {\n input: string;\n output?: string;\n overwrite?: boolean;\n}\n\nexport async function actionJsonToCsv(runtime: CliRuntime, options: JsonToCsvOptions): Promise<void> {\n const inputPath = resolveFromCwd(runtime, assertNonEmpty(options.input, \"Input path\"));\n const outputPath = resolveFromCwd(runtime, options.output?.trim() || defaultOutputPath(inputPath, \".csv\"));\n await ensureFileExists(inputPath, \"Input\");\n\n const raw = await readTextFileRequired(inputPath);\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new CliError(`Invalid JSON: ${message}`, { code: \"INVALID_JSON\", exitCode: 2 });\n }\n\n const rows = normalizeRowsFromJson(parsed);\n const csv = stringifyCsv(rows);\n await writeTextFileSafe(outputPath, csv, { overwrite: options.overwrite });\n\n printLine(runtime.stdout, `Wrote CSV: ${displayPath(runtime, outputPath)}`);\n printLine(runtime.stdout, `Rows: ${rows.length}`);\n}\n\nexport interface CsvToJsonOptions {\n input: string;\n output?: string;\n overwrite?: boolean;\n pretty?: boolean;\n}\n\nexport async function actionCsvToJson(runtime: CliRuntime, options: CsvToJsonOptions): Promise<void> {\n const inputPath = resolveFromCwd(runtime, assertNonEmpty(options.input, \"Input path\"));\n const outputPath = resolveFromCwd(runtime, options.output?.trim() || defaultOutputPath(inputPath, \".json\"));\n await ensureFileExists(inputPath, \"Input\");\n\n const raw = await readTextFileRequired(inputPath);\n const rows = parseCsv(raw);\n const records = csvRowsToObjects(rows);\n const json = `${JSON.stringify(records, null, options.pretty ? 2 : 0)}\\n`;\n await writeTextFileSafe(outputPath, json, { overwrite: options.overwrite });\n\n printLine(runtime.stdout, `Wrote JSON: ${displayPath(runtime, outputPath)}`);\n printLine(runtime.stdout, `Rows: ${records.length}`);\n}\n","export function ensureArrayContainer(\n result: Record<string, unknown>,\n key: string,\n): Record<string, unknown>[] {\n const existing = result[key];\n if (Array.isArray(existing)) {\n return existing as Record<string, unknown>[];\n }\n const list: Record<string, unknown>[] = [];\n result[key] = list;\n return list;\n}\n\nexport function flattenArrayTables(result: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(result)) {\n if (!Array.isArray(value)) {\n continue;\n }\n const flattened = value\n .map((entry) =>\n Object.entries(entry)\n .map(([entryKey, entryValue]) => `${entryKey}=${entryValue}`)\n .join(\", \"),\n )\n .join(\" | \");\n result[key] = flattened;\n }\n}\n","function stripKeyQuotes(key: string): string {\n const trimmed = key.trim();\n if (\n (trimmed.startsWith(\"\\\"\") && trimmed.endsWith(\"\\\"\")) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n\nexport function normalizeKeyPath(key: string): string | null {\n const trimmed = key.trim();\n if (!trimmed) {\n return null;\n }\n\n if (\n (trimmed.startsWith(\"\\\"\") && trimmed.endsWith(\"\\\"\")) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n const unquoted = stripKeyQuotes(trimmed);\n return unquoted ? unquoted : null;\n }\n\n const segments = trimmed.split(\".\").map((segment) => segment.trim());\n if (segments.some((segment) => !segment)) {\n return null;\n }\n return segments.join(\".\");\n}\n","export function stripInlineComment(line: string): string {\n let inString: \"single\" | \"double\" | null = null;\n let escaped = false;\n\n for (let i = 0; i < line.length; i += 1) {\n const char = line[i] ?? \"\";\n\n if (inString) {\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\" && inString === \"double\") {\n escaped = true;\n continue;\n }\n\n if (inString === \"double\" && char === \"\\\"\") {\n inString = null;\n continue;\n }\n\n if (inString === \"single\" && char === \"'\") {\n inString = null;\n continue;\n }\n\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = \"double\";\n continue;\n }\n\n if (char === \"'\") {\n inString = \"single\";\n continue;\n }\n\n if (char === \"#\") {\n return line.slice(0, i).trimEnd();\n }\n }\n\n return line;\n}\n\nfunction unescapeBasic(input: string): string {\n return input\n .replace(/\\\\\\\\/g, \"\\\\\")\n .replace(/\\\\\"/g, \"\\\"\")\n .replace(/\\\\n/g, \"\\n\")\n .replace(/\\\\t/g, \"\\t\")\n .replace(/\\\\r/g, \"\\r\");\n}\n\nexport function parseStringLiteral(value: string): string | null {\n if (value.startsWith('\"\"\"') && value.endsWith('\"\"\"')) {\n const inner = value.slice(3, -3);\n return unescapeBasic(inner);\n }\n\n if (value.startsWith(\"'''\") && value.endsWith(\"'''\")) {\n return value.slice(3, -3);\n }\n\n if (value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\")) {\n return unescapeBasic(value.slice(1, -1));\n }\n\n if (value.startsWith(\"'\") && value.endsWith(\"'\")) {\n return value.slice(1, -1);\n }\n\n return null;\n}\n","import { normalizeKeyPath } from \"./keys\";\nimport { parseStringLiteral } from \"./strings\";\nimport type { TomlValue } from \"./types\";\n\nfunction parsePrimitive(raw: string): string | number | boolean | null {\n const value = raw.trim();\n if (!value) {\n return null;\n }\n\n const stringLiteral = parseStringLiteral(value);\n if (stringLiteral !== null) {\n return stringLiteral;\n }\n\n if (value === \"true\") {\n return true;\n }\n\n if (value === \"false\") {\n return false;\n }\n\n if (/^[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$/.test(value)) {\n return Number(value);\n }\n\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(value)) {\n return value;\n }\n\n return value;\n}\n\nfunction parseArray(raw: string): Array<string | number | boolean> | null {\n const value = raw.trim();\n if (!value.startsWith(\"[\") || !value.endsWith(\"]\")) {\n return null;\n }\n\n const inner = value.slice(1, -1).trim();\n if (!inner) {\n return [];\n }\n\n const items: Array<string | number | boolean> = [];\n let current = \"\";\n let inString: \"single\" | \"double\" | null = null;\n let escaped = false;\n\n for (let i = 0; i < inner.length; i += 1) {\n const char = inner[i] ?? \"\";\n\n if (inString) {\n current += char;\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\" && inString === \"double\") {\n escaped = true;\n continue;\n }\n\n if (inString === \"double\" && char === \"\\\"\") {\n inString = null;\n } else if (inString === \"single\" && char === \"'\") {\n inString = null;\n }\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = \"double\";\n current += char;\n continue;\n }\n\n if (char === \"'\") {\n inString = \"single\";\n current += char;\n continue;\n }\n\n if (char === \",\") {\n const item = parsePrimitive(current);\n if (item === null) {\n return null;\n }\n items.push(item);\n current = \"\";\n continue;\n }\n\n current += char;\n }\n\n const finalItem = parsePrimitive(current);\n if (finalItem === null) {\n return null;\n }\n items.push(finalItem);\n\n return items;\n}\n\nfunction parseInlineTable(raw: string): Record<string, TomlValue> | null {\n const trimmed = raw.trim();\n if (!trimmed.startsWith(\"{\") || !trimmed.endsWith(\"}\")) {\n return null;\n }\n\n const inner = trimmed.slice(1, -1).trim();\n if (!inner) {\n return {};\n }\n\n const pairs: string[] = [];\n let current = \"\";\n let inString: \"single\" | \"double\" | null = null;\n let escaped = false;\n let bracketDepth = 0;\n let braceDepth = 0;\n\n for (let i = 0; i < inner.length; i += 1) {\n const char = inner[i] ?? \"\";\n\n if (inString) {\n current += char;\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\" && inString === \"double\") {\n escaped = true;\n continue;\n }\n\n if (inString === \"double\" && char === \"\\\"\") {\n inString = null;\n } else if (inString === \"single\" && char === \"'\") {\n inString = null;\n }\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = \"double\";\n current += char;\n continue;\n }\n\n if (char === \"'\") {\n inString = \"single\";\n current += char;\n continue;\n }\n\n if (char === \"[\") {\n bracketDepth += 1;\n current += char;\n continue;\n }\n\n if (char === \"]\") {\n if (bracketDepth > 0) {\n bracketDepth -= 1;\n }\n current += char;\n continue;\n }\n\n if (char === \"{\") {\n braceDepth += 1;\n current += char;\n continue;\n }\n\n if (char === \"}\") {\n if (braceDepth > 0) {\n braceDepth -= 1;\n }\n current += char;\n continue;\n }\n\n if (char === \",\" && bracketDepth === 0 && braceDepth === 0) {\n pairs.push(current);\n current = \"\";\n continue;\n }\n\n current += char;\n }\n\n if (current.trim()) {\n pairs.push(current);\n }\n\n const output: Record<string, TomlValue> = {};\n for (const pair of pairs) {\n const separatorIndex = pair.indexOf(\"=\");\n if (separatorIndex === -1) {\n return null;\n }\n const key = normalizeKeyPath(pair.slice(0, separatorIndex));\n if (!key) {\n return null;\n }\n const valueRaw = pair.slice(separatorIndex + 1).trim();\n if (!valueRaw) {\n return null;\n }\n if (valueRaw.startsWith(\"{\")) {\n return null;\n }\n const normalized = normalizeValue(valueRaw);\n if (normalized === null) {\n return null;\n }\n if (typeof normalized === \"object\" && !Array.isArray(normalized)) {\n return null;\n }\n output[key] = normalized;\n }\n\n return output;\n}\n\nexport function normalizeValue(value: string): TomlValue | null {\n if (!value) {\n return null;\n }\n\n const trimmed = value.trim();\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n return parseInlineTable(trimmed);\n }\n\n const array = parseArray(trimmed);\n if (array) {\n return array;\n }\n\n if (trimmed.startsWith(\"[\") && trimmed.endsWith(\"]\")) {\n return null;\n }\n\n return parsePrimitive(trimmed);\n}\n\nexport function toPlainText(value: unknown): string {\n if (value == null) {\n return \"\";\n }\n if (Array.isArray(value)) {\n return value.map((item) => String(item)).join(\", \");\n }\n return String(value);\n}\n","import { ensureArrayContainer, flattenArrayTables } from \"./arrays\";\nimport { normalizeKeyPath } from \"./keys\";\nimport { stripInlineComment } from \"./strings\";\nimport { normalizeValue, toPlainText } from \"./values\";\n\nexport function parseTomlFrontmatter(frontmatter: string): Record<string, unknown> | null {\n const result: Record<string, unknown> = {};\n const lines = frontmatter.split(\"\\n\");\n let tablePrefix = \"\";\n let tableTarget: Record<string, unknown> | null = null;\n let tablePrefixInList = false;\n\n for (let index = 0; index < lines.length; index += 1) {\n const rawLine = lines[index] ?? \"\";\n const trimmedLine = rawLine.trim();\n if (!trimmedLine || trimmedLine.startsWith(\"#\")) {\n continue;\n }\n\n if (trimmedLine.startsWith(\"[[\")) {\n const match = trimmedLine.match(/^\\[\\[([^\\]]+)]]$/);\n if (!match) {\n return null;\n }\n const normalizedTable = normalizeKeyPath(match[1] ?? \"\");\n if (!normalizedTable) {\n return null;\n }\n const list = ensureArrayContainer(result, normalizedTable);\n const newEntry: Record<string, unknown> = {};\n list.push(newEntry);\n tableTarget = newEntry;\n tablePrefix = normalizedTable;\n tablePrefixInList = true;\n continue;\n }\n\n const tableMatch = trimmedLine.match(/^\\[([^\\]]+)]$/);\n if (tableMatch) {\n const normalizedTable = normalizeKeyPath(tableMatch[1] ?? \"\");\n if (!normalizedTable) {\n return null;\n }\n tablePrefix = normalizedTable;\n tablePrefixInList = false;\n tableTarget = null;\n continue;\n }\n\n const lineForParsing = /(\"\"\"|''')/.test(rawLine) ? rawLine : stripInlineComment(rawLine);\n const separatorIndex = lineForParsing.indexOf(\"=\");\n if (separatorIndex === -1) {\n return null;\n }\n\n const keyRaw = lineForParsing.slice(0, separatorIndex);\n const key = normalizeKeyPath(keyRaw);\n let valueRaw = lineForParsing.slice(separatorIndex + 1).trim();\n if (!key) {\n return null;\n }\n\n const tripleDelimiter = valueRaw.startsWith('\"\"\"') ? '\"\"\"' : valueRaw.startsWith(\"'''\") ? \"'''\" : null;\n if (tripleDelimiter) {\n const closingIndex = valueRaw.indexOf(tripleDelimiter, tripleDelimiter.length);\n if (closingIndex !== -1) {\n const after = valueRaw.slice(closingIndex + tripleDelimiter.length);\n const strippedAfter = stripInlineComment(after);\n valueRaw = `${valueRaw.slice(0, closingIndex + tripleDelimiter.length)}${strippedAfter}`;\n } else {\n const delimiter = tripleDelimiter;\n let combined = valueRaw;\n let closed = false;\n while (index + 1 < lines.length) {\n index += 1;\n const nextLine = lines[index] ?? \"\";\n combined += `\\n${nextLine}`;\n if (new RegExp(`${delimiter}\\\\s*$`).test(nextLine)) {\n closed = true;\n break;\n }\n }\n if (!closed) {\n return null;\n }\n valueRaw = combined;\n }\n }\n\n const normalized = normalizeValue(valueRaw);\n if (normalized === null) {\n return null;\n }\n\n const fullKey = tablePrefix ? `${tablePrefix}.${key}` : key;\n if (typeof normalized === \"object\" && !Array.isArray(normalized)) {\n for (const [inlineKey, inlineValue] of Object.entries(normalized)) {\n const entryKey = tablePrefixInList ? `${key}.${inlineKey}` : `${fullKey}.${inlineKey}`;\n if (tablePrefixInList && tableTarget) {\n tableTarget[entryKey] = toPlainText(inlineValue);\n } else {\n result[entryKey] = toPlainText(inlineValue);\n }\n }\n continue;\n }\n\n if (tablePrefixInList && tableTarget) {\n tableTarget[key] = toPlainText(normalized);\n continue;\n }\n\n result[fullKey] = toPlainText(normalized);\n }\n\n flattenArrayTables(result);\n\n return result;\n}\n","import { parseDocument } from \"yaml\";\nimport { parseTomlFrontmatter } from \"./toml-simple\";\nimport type { FrontmatterType, ParsedMarkdown } from \"./types\";\n\nconst FENCE_TO_TYPE: Record<string, FrontmatterType> = {\n \"---\": \"yaml\",\n \"+++\": \"toml\",\n \";;;\": \"json\",\n};\n\nfunction normalizeNewlines(input: string): string {\n return input.replace(/\\r\\n/g, \"\\n\");\n}\n\nfunction stripBom(line: string): string {\n return line.startsWith(\"\\uFEFF\") ? line.slice(1) : line;\n}\n\nfunction getFenceType(line: string): FrontmatterType | null {\n const match = line.match(/^[\\t ]*(---|\\+\\+\\+|;;;)[\\t ]*$/);\n if (!match) {\n return null;\n }\n return FENCE_TO_TYPE[match[1] ?? \"\"] ?? null;\n}\n\nfunction parseFrontmatter(frontmatter: string, type: FrontmatterType | null): Record<string, unknown> | null {\n if (!type) {\n return null;\n }\n\n if (type === \"json\") {\n try {\n return JSON.parse(frontmatter) as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n\n if (type === \"yaml\") {\n const doc = parseDocument(frontmatter, { prettyErrors: false });\n if (doc.errors.length > 0) {\n return null;\n }\n const data = doc.toJSON();\n if (!data || typeof data !== \"object\" || Array.isArray(data)) {\n return null;\n }\n return data as Record<string, unknown>;\n }\n\n if (type === \"toml\") {\n return parseTomlFrontmatter(frontmatter);\n }\n\n return null;\n}\n\nfunction extractJsonBlock(text: string, startIndex: number): { jsonText: string; endIndex: number } | null {\n let depth = 0;\n let inString = false;\n let escaped = false;\n\n for (let i = startIndex; i < text.length; i += 1) {\n const char = text[i] ?? \"\";\n\n if (inString) {\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = false;\n }\n\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = true;\n continue;\n }\n\n if (char === \"{\") {\n depth += 1;\n continue;\n }\n\n if (char === \"}\") {\n depth -= 1;\n if (depth === 0) {\n const jsonText = text.slice(startIndex, i + 1);\n return { jsonText, endIndex: i };\n }\n }\n }\n\n return null;\n}\n\nexport function parseMarkdown(input: string): ParsedMarkdown {\n const normalized = normalizeNewlines(input);\n const lines = normalized.split(\"\\n\");\n if (lines.length === 0) {\n return { frontmatter: null, content: normalized, data: null, frontmatterType: null };\n }\n\n lines[0] = stripBom(lines[0] ?? \"\");\n const normalizedWithoutBom = lines.join(\"\\n\");\n\n const openingType = getFenceType(lines[0] ?? \"\");\n if (!openingType) {\n const leadingWhitespace = normalizedWithoutBom.match(/^[\\t \\n]*/)?.[0] ?? \"\";\n const jsonStart = leadingWhitespace.length;\n if (normalizedWithoutBom[jsonStart] !== \"{\") {\n return { frontmatter: null, content: normalizedWithoutBom, data: null, frontmatterType: null };\n }\n\n const jsonBlock = extractJsonBlock(normalizedWithoutBom, jsonStart);\n if (!jsonBlock) {\n return { frontmatter: null, content: normalizedWithoutBom, data: null, frontmatterType: null };\n }\n\n const frontmatter = jsonBlock.jsonText;\n let content = normalizedWithoutBom.slice(jsonBlock.endIndex + 1);\n if (content.startsWith(\"\\n\")) {\n content = content.slice(1);\n }\n const data = parseFrontmatter(frontmatter, \"json\");\n if (!data) {\n return { frontmatter: null, content: normalizedWithoutBom, data: null, frontmatterType: null };\n }\n\n return {\n frontmatter,\n content,\n data,\n frontmatterType: \"json\",\n };\n }\n\n let closingIndex = -1;\n for (let i = 1; i < lines.length; i += 1) {\n if (getFenceType(lines[i] ?? \"\") === openingType) {\n closingIndex = i;\n break;\n }\n }\n\n if (closingIndex === -1) {\n return { frontmatter: null, content: normalizedWithoutBom, data: null, frontmatterType: null };\n }\n\n const frontmatter = lines.slice(1, closingIndex).join(\"\\n\");\n const content = lines.slice(closingIndex + 1).join(\"\\n\");\n const data = parseFrontmatter(frontmatter, openingType);\n\n return {\n frontmatter,\n content,\n data,\n frontmatterType: openingType,\n };\n}\n","import { stat } from \"node:fs/promises\";\n\nimport { parseMarkdown } from \"../../markdown\";\nimport { requireCommandAvailable } from \"../deps\";\nimport { CliError } from \"../errors\";\nimport {\n defaultOutputPath,\n readTextFileRequired,\n resolveFromCwd,\n writeTextFileSafe,\n} from \"../fs-utils\";\nimport { execCommand } from \"../process\";\nimport type { CliRuntime } from \"../types\";\nimport { assertNonEmpty, displayPath, ensureFileExists, printLine } from \"./shared\";\n\nexport interface MdToDocxOptions {\n input: string;\n output?: string;\n overwrite?: boolean;\n}\n\nexport async function actionMdToDocx(runtime: CliRuntime, options: MdToDocxOptions): Promise<void> {\n const inputPath = resolveFromCwd(runtime, assertNonEmpty(options.input, \"Input path\"));\n const outputPath = resolveFromCwd(runtime, options.output?.trim() || defaultOutputPath(inputPath, \".docx\"));\n await ensureFileExists(inputPath, \"Input\");\n await requireCommandAvailable(\"pandoc\", runtime.platform);\n\n if (!options.overwrite) {\n try {\n await stat(outputPath);\n throw new CliError(`Output file already exists: ${outputPath}. Use --overwrite to replace it.`, {\n code: \"OUTPUT_EXISTS\",\n exitCode: 2,\n });\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n }\n }\n\n const args = [inputPath, \"-o\", outputPath];\n const result = await execCommand(\"pandoc\", args, { cwd: runtime.cwd });\n if (!result.ok) {\n throw new CliError(`pandoc failed (${result.code ?? \"unknown\"}): ${result.stderr || result.stdout}`.trim(), {\n code: \"PROCESS_FAILED\",\n exitCode: 1,\n });\n }\n\n printLine(runtime.stdout, `Wrote DOCX: ${displayPath(runtime, outputPath)}`);\n}\n\nexport interface MdFrontmatterToJsonOptions {\n input: string;\n output?: string;\n overwrite?: boolean;\n pretty?: boolean;\n dataOnly?: boolean;\n toStdout?: boolean;\n}\n\nfunction stringifyJsonOutput(value: unknown, pretty = false): string {\n const spacing = pretty ? 2 : 0;\n return `${JSON.stringify(value, null, spacing)}\\n`;\n}\n\nexport async function actionMdFrontmatterToJson(\n runtime: CliRuntime,\n options: MdFrontmatterToJsonOptions,\n): Promise<void> {\n const inputPath = resolveFromCwd(runtime, assertNonEmpty(options.input, \"Input path\"));\n await ensureFileExists(inputPath, \"Input\");\n\n const raw = await readTextFileRequired(inputPath);\n const parsed = parseMarkdown(raw);\n\n if (parsed.frontmatterType === null || parsed.frontmatter === null) {\n throw new CliError(`No frontmatter found in Markdown file: ${inputPath}`, {\n code: \"FRONTMATTER_NOT_FOUND\",\n exitCode: 2,\n });\n }\n\n if (parsed.data === null || typeof parsed.data !== \"object\" || Array.isArray(parsed.data)) {\n throw new CliError(`Failed to parse frontmatter as an object in: ${inputPath}`, {\n code: \"INVALID_FRONTMATTER\",\n exitCode: 2,\n });\n }\n\n const payload = options.dataOnly\n ? parsed.data\n : {\n frontmatterType: parsed.frontmatterType,\n data: parsed.data,\n };\n const json = stringifyJsonOutput(payload, options.pretty);\n\n const outputInput = options.output?.trim();\n const writeToStdout = options.toStdout ?? !outputInput;\n if (writeToStdout) {\n runtime.stdout.write(json);\n return;\n }\n\n const outputPath = resolveFromCwd(\n runtime,\n outputInput || defaultOutputPath(inputPath, \".frontmatter.json\"),\n );\n await writeTextFileSafe(outputPath, json, { overwrite: options.overwrite });\n printLine(runtime.stdout, `Wrote JSON: ${displayPath(runtime, outputPath)}`);\n}\n","import { randomUUID } from \"node:crypto\";\nimport { basename, isAbsolute, relative, resolve } from \"node:path\";\n\nimport { csvRowsToObjects, parseCsv, stringifyCsv } from \"../utils/csv\";\nimport { formatUtcFileDateTimeISO } from \"../utils/datetime\";\nimport { CliError } from \"./errors\";\nimport { applyPlannedRenames, readTextFileRequired, writeTextFileSafe } from \"./fs-utils\";\nimport type { CliRuntime, PlannedRename, SkippedRenameItem } from \"./types\";\n\nexport const RENAME_PLAN_CSV_HEADERS = [\n \"old_name\",\n \"new_name\",\n \"cleaned_stem\",\n \"ai_new_name\",\n \"ai_provider\",\n \"ai_model\",\n \"changed_at\",\n \"old_path\",\n \"new_path\",\n \"plan_id\",\n \"planned_at\",\n \"applied_at\",\n \"status\",\n \"reason\",\n \"timestamp_tz\",\n] as const;\n\nexport type RenamePlanCsvStatus = \"planned\" | \"skipped\" | \"applied\" | \"failed\";\nconst RENAME_PLAN_CSV_REPLAY_REQUIRED_HEADERS = [\n \"old_path\",\n \"new_path\",\n \"status\",\n \"plan_id\",\n \"planned_at\",\n] as const;\n\nexport interface RenamePlanCsvRow {\n old_name: string;\n new_name: string;\n cleaned_stem: string;\n ai_new_name: string;\n ai_provider: string;\n ai_model: string;\n changed_at: string;\n old_path: string;\n new_path: string;\n plan_id: string;\n planned_at: string;\n applied_at: string;\n status: RenamePlanCsvStatus;\n reason: string;\n timestamp_tz: string;\n}\n\nfunction toRelativePathFromCwd(cwd: string, absolutePath: string): string {\n const next = relative(cwd, absolutePath);\n if (!next || next.startsWith(\"..\")) {\n throw new CliError(`Rename plan path escaped current working directory: ${absolutePath}`, {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n });\n }\n return next;\n}\n\nfunction assertPathWithinCwd(cwd: string, pathValue: string, label: string): string {\n const trimmed = pathValue.trim();\n if (!trimmed) {\n throw new CliError(`Rename plan CSV missing required field: ${label}`, {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n });\n }\n\n if (isAbsolute(trimmed)) {\n throw new CliError(`Rename plan ${label} must be cwd-relative: ${trimmed}`, {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n });\n }\n\n const resolved = resolve(cwd, trimmed);\n const back = relative(cwd, resolved);\n if (!back || back.startsWith(\"..\")) {\n throw new CliError(`Rename plan ${label} escaped current working directory: ${trimmed}`, {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n });\n }\n return resolved;\n}\n\nfunction normalizeHeader(value: string, index: number): string {\n return (index === 0 ? value.replace(/^\\uFEFF/, \"\") : value).trim();\n}\n\nfunction isRenamePlanCsvStatus(value: string): value is RenamePlanCsvStatus {\n return [\"planned\", \"skipped\", \"applied\", \"failed\"].includes(value);\n}\n\nfunction validateRenamePlanCsvHeaders(headerRow: string[]): void {\n const headers = headerRow.map((header, index) => normalizeHeader(header, index));\n const missing = RENAME_PLAN_CSV_REPLAY_REQUIRED_HEADERS.filter(\n (header) => !headers.includes(header),\n );\n if (missing.length > 0) {\n throw new CliError(\n `Rename plan CSV missing required column${missing.length > 1 ? \"s\" : \"\"}: ${missing.join(\", \")}`,\n {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n },\n );\n }\n}\n\nfunction assertRequiredReplayField(value: string, field: string, rowNumber: number): void {\n if (!value) {\n throw new CliError(`Rename plan CSV row ${rowNumber} missing required field: ${field}`, {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n });\n }\n}\n\nfunction validateAndParseRenamePlanCsvRow(\n record: Record<string, string>,\n rowNumber: number,\n): RenamePlanCsvRow {\n const statusValue = (record.status ?? \"\").trim();\n if (!statusValue) {\n throw new CliError(`Rename plan CSV row ${rowNumber} missing required field: status`, {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n });\n }\n if (!isRenamePlanCsvStatus(statusValue)) {\n throw new CliError(`Invalid rename plan status '${statusValue}' in CSV row ${rowNumber}`, {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n });\n }\n\n return {\n old_name: (record.old_name ?? \"\").trim(),\n new_name: (record.new_name ?? \"\").trim(),\n cleaned_stem: (record.cleaned_stem ?? \"\").trim(),\n ai_new_name: (record.ai_new_name ?? \"\").trim(),\n ai_provider: (record.ai_provider ?? \"\").trim(),\n ai_model: (record.ai_model ?? \"\").trim(),\n changed_at: (record.changed_at ?? \"\").trim(),\n old_path: (record.old_path ?? \"\").trim(),\n new_path: (record.new_path ?? \"\").trim(),\n plan_id: (record.plan_id ?? \"\").trim(),\n planned_at: (record.planned_at ?? \"\").trim(),\n applied_at: (record.applied_at ?? \"\").trim(),\n status: statusValue,\n reason: (record.reason ?? \"\").trim(),\n timestamp_tz: (record.timestamp_tz ?? \"\").trim(),\n } satisfies RenamePlanCsvRow;\n}\n\nfunction assertSingleReplayMetadataValue(\n rows: RenamePlanCsvRow[],\n field: \"plan_id\" | \"planned_at\",\n): void {\n const values = new Set(rows.map((row) => row[field]));\n if (values.size > 1) {\n throw new CliError(`Rename plan CSV has inconsistent ${field} values across rows`, {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n });\n }\n}\n\nfunction assertNoDuplicateExecutablePath(\n seen: Map<string, number>,\n resolvedPath: string,\n rowNumber: number,\n label: \"old_path\" | \"new_path\",\n): void {\n const previousRowNumber = seen.get(resolvedPath);\n if (previousRowNumber !== undefined) {\n throw new CliError(\n `Rename plan CSV has duplicate executable ${label} entries at rows ${previousRowNumber} and ${rowNumber}`,\n {\n code: \"INVALID_RENAME_PLAN\",\n exitCode: 2,\n },\n );\n }\n seen.set(resolvedPath, rowNumber);\n}\n\nfunction validateExecutableApplyRows(\n runtime: CliRuntime,\n rows: RenamePlanCsvRow[],\n): PlannedRename[] {\n // Validate per-row replay metadata before cross-row checks.\n rows.forEach((row, index) => {\n const rowNumber = index + 2;\n assertRequiredReplayField(row.plan_id, \"plan_id\", rowNumber);\n assertRequiredReplayField(row.planned_at, \"planned_at\", rowNumber);\n });\n\n assertSingleReplayMetadataValue(rows, \"plan_id\");\n assertSingleReplayMetadataValue(rows, \"planned_at\");\n\n const seenOldPaths = new Map<string, number>();\n const seenNewPaths = new Map<string, number>();\n const plans: PlannedRename[] = [];\n\n rows.forEach((row, index) => {\n if (row.status !== \"planned\") {\n return;\n }\n\n const rowNumber = index + 2;\n const fromPath = assertPathWithinCwd(runtime.cwd, row.old_path, \"old_path\");\n const toPath = assertPathWithinCwd(runtime.cwd, row.new_path, \"new_path\");\n\n assertNoDuplicateExecutablePath(seenOldPaths, fromPath, rowNumber, \"old_path\");\n assertNoDuplicateExecutablePath(seenNewPaths, toPath, rowNumber, \"new_path\");\n\n plans.push({\n fromPath,\n toPath,\n changed: fromPath !== toPath,\n });\n });\n\n return plans;\n}\n\nfunction stringifyRenamePlanCsv(rows: RenamePlanCsvRow[]): string {\n if (rows.length === 0) {\n return `${RENAME_PLAN_CSV_HEADERS.join(\",\")}\\n`;\n }\n return stringifyCsv(rows as unknown as Array<Record<string, unknown>>);\n}\n\nexport function createRenamePlanCsvRows(options: {\n runtime: CliRuntime;\n plans: PlannedRename[];\n cleanedStemBySourcePath?: Map<string, string>;\n aiNameBySourcePath?: Map<string, string>;\n reasonBySourcePath?: Map<string, string>;\n skippedItems?: SkippedRenameItem[];\n aiProvider?: string;\n aiModel?: string;\n timestampTz?: string;\n}): { rows: RenamePlanCsvRow[]; planId: string; plannedAt: string } {\n const plannedAt = options.runtime.now().toISOString();\n const planId = `${formatUtcFileDateTimeISO(options.runtime.now())}-${randomUUID().slice(0, 8)}`;\n const timestampTz = options.timestampTz ?? \"\";\n\n const rows = options.plans.map((plan) => {\n const aiNewName = options.aiNameBySourcePath?.get(plan.fromPath) ?? \"\";\n const changed = plan.changed;\n return {\n old_name: basename(plan.fromPath),\n new_name: basename(plan.toPath),\n cleaned_stem: options.cleanedStemBySourcePath?.get(plan.fromPath) ?? \"\",\n ai_new_name: aiNewName,\n ai_provider: aiNewName ? (options.aiProvider ?? \"codex\") : \"\",\n ai_model: aiNewName ? (options.aiModel ?? \"auto\") : \"\",\n changed_at: \"\",\n old_path: toRelativePathFromCwd(options.runtime.cwd, plan.fromPath),\n new_path: toRelativePathFromCwd(options.runtime.cwd, plan.toPath),\n plan_id: planId,\n planned_at: plannedAt,\n applied_at: \"\",\n status: changed ? \"planned\" : \"skipped\",\n reason: options.reasonBySourcePath?.get(plan.fromPath) ?? (changed ? \"\" : \"unchanged\"),\n timestamp_tz: timestampTz,\n } satisfies RenamePlanCsvRow;\n });\n\n const skippedRows = (options.skippedItems ?? []).map((item) => {\n const oldName = basename(item.path);\n return {\n old_name: oldName,\n new_name: oldName,\n cleaned_stem: \"\",\n ai_new_name: \"\",\n ai_provider: \"\",\n ai_model: \"\",\n changed_at: \"\",\n old_path: toRelativePathFromCwd(options.runtime.cwd, item.path),\n new_path: toRelativePathFromCwd(options.runtime.cwd, item.path),\n plan_id: planId,\n planned_at: plannedAt,\n applied_at: \"\",\n status: \"skipped\" as const,\n reason: item.reason,\n timestamp_tz: timestampTz,\n } satisfies RenamePlanCsvRow;\n });\n\n return { rows: [...rows, ...skippedRows], planId, plannedAt };\n}\n\nexport async function writeRenamePlanCsv(\n runtime: CliRuntime,\n rows: RenamePlanCsvRow[],\n): Promise<string> {\n const filename = `rename-plan-${formatUtcFileDateTimeISO(runtime.now())}-${randomUUID().slice(0, 8)}.csv`;\n const csvPath = resolve(runtime.cwd, filename);\n await writeTextFileSafe(csvPath, stringifyRenamePlanCsv(rows), { overwrite: false });\n return csvPath;\n}\n\nexport async function readRenamePlanCsv(\n runtime: CliRuntime,\n csvPathInput: string,\n): Promise<{ csvPath: string; rows: RenamePlanCsvRow[] }> {\n const csvPath = resolve(runtime.cwd, csvPathInput);\n const text = await readTextFileRequired(csvPath);\n const parsedRows = parseCsv(text);\n validateRenamePlanCsvHeaders(parsedRows[0] ?? []);\n\n const records = csvRowsToObjects(parsedRows);\n const rows = records.map((record, index) => validateAndParseRenamePlanCsvRow(record, index + 2));\n\n return { csvPath, rows };\n}\n\nexport async function applyRenamePlanCsv(\n runtime: CliRuntime,\n csvPathInput: string,\n): Promise<{\n csvPath: string;\n totalRows: number;\n appliedCount: number;\n skippedCount: number;\n}> {\n const { csvPath, rows } = await readRenamePlanCsv(runtime, csvPathInput);\n const plans = validateExecutableApplyRows(runtime, rows);\n const executableRows = rows.filter((row) => row.status === \"planned\");\n\n await applyPlannedRenames(plans);\n\n const appliedAt = runtime.now().toISOString();\n const updatedRows = rows.map((row) => {\n if (row.status !== \"planned\") {\n return row;\n }\n return {\n ...row,\n status: \"applied\" as const,\n applied_at: appliedAt,\n changed_at: appliedAt,\n reason: row.reason,\n };\n });\n await writeTextFileSafe(csvPath, stringifyRenamePlanCsv(updatedRows), { overwrite: true });\n\n return {\n csvPath,\n totalRows: rows.length,\n appliedCount: executableRows.length,\n skippedCount: rows.filter((row) => row.status !== \"planned\").length,\n };\n}\n","export function appendAll<T>(target: T[], source: readonly T[]): void {\n for (const item of source) {\n target.push(item);\n }\n}\n","import { basename, resolve } from \"node:path\";\n\nimport { appendAll } from \"../utils\";\nimport { formatPathForDisplay } from \"./fs-utils\";\nimport type { RenamePlanCsvRow } from \"./rename-plan-csv\";\nimport type { CliRuntime, PlannedRename, SkippedRenameItem } from \"./types\";\n\nexport interface RenamePreviewTruncation {\n totalCount: number;\n headCount: number;\n tailCount: number;\n omittedCount: number;\n}\n\nexport interface RenamePreviewRenameRow {\n kind: \"rename\";\n plan: PlannedRename;\n line: string;\n}\n\nexport interface RenamePreviewSkippedSummaryRow {\n kind: \"skipped-summary\";\n reason: string;\n count: number;\n line: string;\n}\n\nexport interface RenamePreviewSkippedDetailRow {\n kind: \"skipped-detail\";\n item: SkippedRenameItem;\n line: string;\n}\n\nexport interface RenameBatchPreviewData {\n renameRows: RenamePreviewRenameRow[];\n skippedSummaryRows: RenamePreviewSkippedSummaryRow[];\n skippedDetailRows: RenamePreviewSkippedDetailRow[];\n fullLines: string[];\n}\n\nexport interface RenamePreviewSourceData {\n plans: PlannedRename[];\n skipped: SkippedRenameItem[];\n}\n\nexport interface HeadTailSlice<T> {\n head: T[];\n tail: T[];\n omittedCount: number;\n totalCount: number;\n truncated: boolean;\n}\n\nexport interface RenamePreviewBudget {\n rowCount: number;\n headCount: number;\n tailCount: number;\n}\n\nexport interface CompactRenameBatchPreviewData {\n renameLines: string[];\n skippedSummaryLines: string[];\n truncation?: RenamePreviewTruncation;\n}\n\nexport interface DetailedSkippedPreviewData {\n skippedLines: string[];\n truncation?: RenamePreviewTruncation;\n}\n\nconst DEFAULT_RENAME_PREVIEW_MAX_ROWS = 40;\nconst DEFAULT_RENAME_PREVIEW_MIN_ROWS = 6;\nconst DEFAULT_RENAME_PREVIEW_RESERVED_TERMINAL_ROWS = 18;\nconst UNBOUNDED_PREVIEW_ROWS = Number.MAX_SAFE_INTEGER;\n\nexport function formatPlannedRenamePreviewLine(plan: PlannedRename): string {\n const fromName = basename(plan.fromPath);\n const toName = basename(plan.toPath);\n return plan.changed ? `- ${fromName} -> ${toName}` : `- ${fromName} (unchanged)`;\n}\n\nexport function formatSkippedRenamePreviewLine(runtime: CliRuntime, item: SkippedRenameItem): string {\n return `- ${formatPathForDisplay(runtime, item.path)} (skipped: ${item.reason})`;\n}\n\nexport function summarizeSkippedRenameItems(\n items: readonly SkippedRenameItem[],\n): RenamePreviewSkippedSummaryRow[] {\n const countsByReason = new Map<string, number>();\n for (const item of items) {\n countsByReason.set(item.reason, (countsByReason.get(item.reason) ?? 0) + 1);\n }\n\n return [...countsByReason.entries()]\n .sort((left, right) => {\n if (right[1] !== left[1]) {\n return right[1] - left[1];\n }\n return left[0].localeCompare(right[0]);\n })\n .map(([reason, count]) => ({\n kind: \"skipped-summary\" as const,\n reason,\n count,\n line: `- ${count} ${reason}`,\n }));\n}\n\nexport function buildHeadTailSlice<T>(\n items: readonly T[],\n options: {\n headCount: number;\n tailCount: number;\n },\n): HeadTailSlice<T> {\n const totalCount = items.length;\n const headCount = Math.max(0, options.headCount);\n const tailCount = Math.max(0, options.tailCount);\n const visibleCount = headCount + tailCount;\n\n if (totalCount <= visibleCount) {\n return {\n head: [...items],\n tail: [],\n omittedCount: 0,\n totalCount,\n truncated: false,\n };\n }\n\n const head = items.slice(0, headCount);\n const tail = tailCount > 0 ? items.slice(-tailCount) : [];\n return {\n head,\n tail,\n omittedCount: Math.max(0, totalCount - head.length - tail.length),\n totalCount,\n truncated: true,\n };\n}\n\nexport function resolveRenamePreviewBudget(runtime: CliRuntime): RenamePreviewBudget {\n const stream = runtime.stdout as NodeJS.WritableStream & { isTTY?: boolean; rows?: number };\n if (!stream.isTTY) {\n return {\n rowCount: UNBOUNDED_PREVIEW_ROWS,\n headCount: UNBOUNDED_PREVIEW_ROWS,\n tailCount: 0,\n };\n }\n\n let rowCount = DEFAULT_RENAME_PREVIEW_MAX_ROWS;\n\n if (typeof stream.rows === \"number\" && Number.isFinite(stream.rows)) {\n rowCount = Math.min(\n DEFAULT_RENAME_PREVIEW_MAX_ROWS,\n Math.max(DEFAULT_RENAME_PREVIEW_MIN_ROWS, Math.floor(stream.rows) - DEFAULT_RENAME_PREVIEW_RESERVED_TERMINAL_ROWS),\n );\n }\n\n return {\n rowCount,\n headCount: Math.max(1, Math.ceil(rowCount / 2)),\n tailCount: Math.max(0, Math.floor(rowCount / 2)),\n };\n}\n\nexport function composeRenameBatchPreviewData(\n runtime: CliRuntime,\n options: {\n plans: readonly PlannedRename[];\n skipped: readonly SkippedRenameItem[];\n },\n): RenameBatchPreviewData {\n const renameRows = options.plans.map((plan) => ({\n kind: \"rename\" as const,\n plan,\n line: formatPlannedRenamePreviewLine(plan),\n }));\n const skippedSummaryRows = summarizeSkippedRenameItems(options.skipped);\n const skippedDetailRows = options.skipped.map((item) => ({\n kind: \"skipped-detail\" as const,\n item,\n line: formatSkippedRenamePreviewLine(runtime, item),\n }));\n\n const fullLines: string[] = [];\n appendAll(\n fullLines,\n renameRows.map((row) => row.line),\n );\n appendAll(\n fullLines,\n skippedDetailRows.map((row) => row.line),\n );\n\n return {\n renameRows,\n skippedSummaryRows,\n skippedDetailRows,\n fullLines,\n };\n}\n\nexport function createRenamePreviewSourceData(options: {\n plans: readonly PlannedRename[];\n skipped: readonly SkippedRenameItem[];\n}): RenamePreviewSourceData {\n return {\n plans: [...options.plans],\n skipped: [...options.skipped],\n };\n}\n\nexport function createRenamePreviewSourceDataFromPlanCsvRows(\n runtime: CliRuntime,\n rows: readonly RenamePlanCsvRow[],\n): RenamePreviewSourceData {\n const plans: PlannedRename[] = [];\n const skipped: SkippedRenameItem[] = [];\n\n for (const row of rows) {\n const fromPath = resolve(runtime.cwd, row.old_path);\n const toPath = resolve(runtime.cwd, row.new_path);\n\n if (row.status === \"skipped\") {\n skipped.push({\n path: fromPath,\n reason: row.reason || \"skipped\",\n });\n continue;\n }\n\n plans.push({\n fromPath,\n toPath,\n changed: fromPath !== toPath,\n });\n }\n\n return { plans, skipped };\n}\n\nexport function composeRenameBatchPreviewDataFromPlanCsvRows(\n runtime: CliRuntime,\n rows: readonly RenamePlanCsvRow[],\n): RenameBatchPreviewData {\n const source = createRenamePreviewSourceDataFromPlanCsvRows(runtime, rows);\n return composeRenameBatchPreviewData(runtime, source);\n}\n\nexport function composeCompactRenameBatchPreviewData(\n runtime: CliRuntime,\n options: {\n plans: readonly PlannedRename[];\n skipped: readonly SkippedRenameItem[];\n },\n): CompactRenameBatchPreviewData {\n const previewData = composeRenameBatchPreviewData(runtime, options);\n const budget = resolveRenamePreviewBudget(runtime);\n const changedRenameRows = previewData.renameRows.filter((row) => row.plan.changed);\n const renameRowsForCompactPreview =\n previewData.renameRows.length > budget.rowCount && changedRenameRows.length > 0\n ? changedRenameRows\n : previewData.renameRows;\n const renameSlice = buildHeadTailSlice(renameRowsForCompactPreview, {\n headCount: budget.headCount,\n tailCount: budget.tailCount,\n });\n\n const renameLines: string[] = [];\n appendAll(renameLines, renameSlice.head.map((row) => row.line));\n if (renameSlice.truncated) {\n renameLines.push(\"...\");\n appendAll(renameLines, renameSlice.tail.map((row) => row.line));\n }\n\n return {\n renameLines,\n skippedSummaryLines: previewData.skippedSummaryRows.map((row) => row.line),\n truncation: renameSlice.truncated\n ? {\n totalCount: renameSlice.totalCount,\n headCount: renameSlice.head.length,\n tailCount: renameSlice.tail.length,\n omittedCount: renameSlice.omittedCount,\n }\n : undefined,\n };\n}\n\nexport function composeCompactRenameBatchPreviewDataFromPlanCsvRows(\n runtime: CliRuntime,\n rows: readonly RenamePlanCsvRow[],\n): CompactRenameBatchPreviewData {\n const source = createRenamePreviewSourceDataFromPlanCsvRows(runtime, rows);\n return composeCompactRenameBatchPreviewData(runtime, source);\n}\n\nexport function resolveDetailedSkippedPreviewBudget(runtime: CliRuntime): RenamePreviewBudget {\n const base = resolveRenamePreviewBudget(runtime);\n const rowCount = Math.min(8, Math.max(4, Math.floor(base.rowCount / 2)));\n return {\n rowCount,\n headCount: Math.max(1, Math.ceil(rowCount / 2)),\n tailCount: Math.max(0, Math.floor(rowCount / 2)),\n };\n}\n\nexport function composeDetailedSkippedPreviewData(\n runtime: CliRuntime,\n options: {\n skipped: readonly SkippedRenameItem[];\n },\n): DetailedSkippedPreviewData {\n const detailRows = options.skipped.map((item) => ({\n kind: \"skipped-detail\" as const,\n item,\n line: formatSkippedRenamePreviewLine(runtime, item),\n }));\n const budget = resolveDetailedSkippedPreviewBudget(runtime);\n const slice = buildHeadTailSlice(detailRows, {\n headCount: budget.headCount,\n tailCount: budget.tailCount,\n });\n\n const skippedLines: string[] = [];\n appendAll(skippedLines, slice.head.map((row) => row.line));\n if (slice.truncated) {\n skippedLines.push(\"...\");\n appendAll(skippedLines, slice.tail.map((row) => row.line));\n }\n\n return {\n skippedLines,\n truncation: slice.truncated\n ? {\n totalCount: slice.totalCount,\n headCount: slice.head.length,\n tailCount: slice.tail.length,\n omittedCount: slice.omittedCount,\n }\n : undefined,\n };\n}\n","import {\n composeCompactRenameBatchPreviewData,\n composeDetailedSkippedPreviewData,\n composeRenameBatchPreviewData,\n formatPlannedRenamePreviewLine,\n} from \"../../rename-preview\";\nimport type { CliRuntime, PlannedRename } from \"../../types\";\nimport { displayPath, printLine } from \"../shared\";\n\ntype RenameSkippedItem = {\n path: string;\n reason: string;\n};\n\nexport function printRenameBatchPreview(\n runtime: CliRuntime,\n options: {\n plans: PlannedRename[];\n skipped: RenameSkippedItem[];\n previewSkips: \"summary\" | \"detailed\";\n dryRun: boolean;\n },\n): { truncated: boolean } {\n if (options.dryRun) {\n const previewData = composeCompactRenameBatchPreviewData(runtime, {\n plans: options.plans,\n skipped: options.skipped,\n });\n\n if (previewData.truncation) {\n printLine(\n runtime.stdout,\n `Renames: showing first ${previewData.truncation.headCount} and last ${previewData.truncation.tailCount} of ${previewData.truncation.totalCount} rows; ${previewData.truncation.omittedCount} omitted from the middle.`,\n );\n } else if (previewData.renameLines.length > 0) {\n printLine(runtime.stdout, \"Renames:\");\n }\n\n for (const line of previewData.renameLines) {\n printLine(runtime.stdout, line);\n }\n\n if (previewData.skippedSummaryLines.length > 0) {\n if (previewData.renameLines.length > 0 || previewData.truncation) {\n printLine(runtime.stdout);\n }\n printLine(runtime.stdout, \"Skipped summary:\");\n for (const line of previewData.skippedSummaryLines) {\n printLine(runtime.stdout, line);\n }\n\n if (options.previewSkips === \"detailed\") {\n const skippedPreview = composeDetailedSkippedPreviewData(runtime, {\n skipped: options.skipped,\n });\n printLine(runtime.stdout);\n if (skippedPreview.truncation) {\n printLine(\n runtime.stdout,\n `Skipped: showing first ${skippedPreview.truncation.headCount} and last ${skippedPreview.truncation.tailCount} of ${skippedPreview.truncation.totalCount} rows; ${skippedPreview.truncation.omittedCount} omitted from the middle.`,\n );\n } else {\n printLine(runtime.stdout, \"Skipped details:\");\n }\n for (const line of skippedPreview.skippedLines) {\n printLine(runtime.stdout, line);\n }\n }\n }\n\n return { truncated: Boolean(previewData.truncation) };\n }\n\n const previewData = composeRenameBatchPreviewData(runtime, {\n plans: options.plans,\n skipped: options.skipped,\n });\n for (const line of previewData.fullLines) {\n printLine(runtime.stdout, line);\n }\n\n return { truncated: false };\n}\n\nexport function printRenameBatchDryRunFooter(\n runtime: CliRuntime,\n options: {\n planCsvPath: string;\n truncated: boolean;\n },\n): void {\n printLine(runtime.stdout);\n if (options.truncated) {\n printLine(runtime.stdout, \"Full review: use the generated plan CSV for the complete rename list.\");\n }\n printLine(runtime.stdout, `Plan CSV: ${displayPath(runtime, options.planCsvPath)}`);\n printLine(runtime.stdout, \"Dry run only. No files were renamed.\");\n}\n\nexport function printRenameBatchApplyFooter(runtime: CliRuntime, changedCount: number): void {\n printLine(runtime.stdout);\n printLine(runtime.stdout, `Renamed ${changedCount} file(s).`);\n}\n\nexport function printRenameFilePreview(runtime: CliRuntime, plan: PlannedRename): void {\n printLine(runtime.stdout);\n printLine(runtime.stdout, formatPlannedRenamePreviewLine(plan));\n}\n\nexport function printRenameFileDryRunFooter(runtime: CliRuntime, planCsvPath: string): void {\n printLine(runtime.stdout);\n printLine(runtime.stdout, `Plan CSV: ${displayPath(runtime, planCsvPath)}`);\n printLine(runtime.stdout, \"Dry run only. No files were renamed.\");\n}\n\nexport function printRenameFileApplyFooter(runtime: CliRuntime, changed: boolean): void {\n printLine(runtime.stdout);\n if (changed) {\n printLine(runtime.stdout, \"Renamed 1 file(s).\");\n } else {\n printLine(runtime.stdout, \"No rename needed.\");\n }\n}\n\nexport async function printRenameApplyResult(\n runtime: CliRuntime,\n options: {\n csvPath: string;\n totalRows: number;\n appliedCount: number;\n skippedCount: number;\n autoClean: boolean;\n removeCsv: (path: string) => Promise<void>;\n },\n): Promise<void> {\n printLine(runtime.stdout, `Plan CSV: ${displayPath(runtime, options.csvPath)}`);\n printLine(runtime.stdout, `Rows in plan: ${options.totalRows}`);\n printLine(runtime.stdout, `Rows applied: ${options.appliedCount}`);\n printLine(runtime.stdout, `Rows skipped: ${options.skippedCount}`);\n if (options.autoClean) {\n await options.removeCsv(options.csvPath);\n printLine(runtime.stdout, \"Plan CSV auto-cleaned.\");\n }\n}\n","import { rm } from \"node:fs/promises\";\n\nimport { applyRenamePlanCsv } from \"../../rename-plan-csv\";\nimport type { CliRuntime } from \"../../types\";\nimport { assertNonEmpty } from \"../shared\";\nimport { printRenameApplyResult } from \"./reporting\";\n\nexport interface RenameApplyOptions {\n csv: string;\n autoClean?: boolean;\n}\n\nexport async function actionRenameApply(\n runtime: CliRuntime,\n options: RenameApplyOptions,\n): Promise<{ csvPath: string; appliedCount: number; totalRows: number; skippedCount: number }> {\n const csv = assertNonEmpty(options.csv, \"Rename plan CSV path\");\n const result = await applyRenamePlanCsv(runtime, csv);\n\n await printRenameApplyResult(runtime, {\n csvPath: result.csvPath,\n totalRows: result.totalRows,\n appliedCount: result.appliedCount,\n skippedCount: result.skippedCount,\n autoClean: options.autoClean ?? false,\n removeCsv: async (path) => {\n await rm(path, { force: true });\n },\n });\n\n return result;\n}\n","import { extname } from \"node:path\";\n\nexport type RenameInteractiveCodexScope = \"auto\" | \"images\" | \"docs\";\n\nexport interface RenameInteractiveCodexFlags {\n codexImages: boolean;\n codexDocs: boolean;\n}\n\nexport interface RenameCliCodexOptions {\n codex?: boolean;\n codexImages?: boolean;\n codexDocs?: boolean;\n}\n\nconst SUPPORTED_IMAGE_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".webp\",\n \".gif\",\n \".bmp\",\n \".tif\",\n \".tiff\",\n \".avif\",\n]);\n\nconst SUPPORTED_DOC_EXTENSIONS = new Set([\n \".md\",\n \".markdown\",\n \".txt\",\n \".json\",\n \".yaml\",\n \".yml\",\n \".toml\",\n \".xml\",\n \".html\",\n \".htm\",\n \".pdf\",\n \".docx\",\n]);\n\nexport function resolveAutoCodexFlagsForBatchProfile(profile: string): RenameInteractiveCodexFlags {\n switch (profile) {\n case \"images\":\n return { codexImages: true, codexDocs: false };\n case \"media\":\n return { codexImages: true, codexDocs: false };\n case \"docs\":\n return { codexImages: false, codexDocs: true };\n default:\n return { codexImages: true, codexDocs: true };\n }\n}\n\nexport function resolveAutoCodexFlagsForFilePath(path: string): RenameInteractiveCodexFlags {\n const ext = extname(path).toLowerCase();\n return {\n codexImages: SUPPORTED_IMAGE_EXTENSIONS.has(ext),\n codexDocs: SUPPORTED_DOC_EXTENSIONS.has(ext),\n };\n}\n\nexport function resolveAutoCodexFlagsForPaths(paths: string[]): RenameInteractiveCodexFlags {\n let codexImages = false;\n let codexDocs = false;\n\n for (const path of paths) {\n const flags = resolveAutoCodexFlagsForFilePath(path);\n codexImages = codexImages || flags.codexImages;\n codexDocs = codexDocs || flags.codexDocs;\n if (codexImages && codexDocs) {\n break;\n }\n }\n\n return { codexImages, codexDocs };\n}\n\nexport function resolveCodexFlagsFromScope(options: {\n scope: RenameInteractiveCodexScope;\n fallbackAuto: RenameInteractiveCodexFlags;\n}): RenameInteractiveCodexFlags {\n switch (options.scope) {\n case \"images\":\n return { codexImages: true, codexDocs: false };\n case \"docs\":\n return { codexImages: false, codexDocs: true };\n case \"auto\":\n default:\n return options.fallbackAuto;\n }\n}\n\nexport function resolveCodexFlagsFromCliOptions(options: {\n cli: RenameCliCodexOptions;\n fallbackAuto: RenameInteractiveCodexFlags;\n}): RenameInteractiveCodexFlags {\n const explicitImages = options.cli.codexImages ?? false;\n const explicitDocs = options.cli.codexDocs ?? false;\n const hasExplicitFlags = explicitImages || explicitDocs;\n\n if (hasExplicitFlags) {\n return {\n codexImages: explicitImages,\n codexDocs: explicitDocs,\n };\n }\n\n if (options.cli.codex ?? false) {\n return options.fallbackAuto;\n }\n\n return {\n codexImages: false,\n codexDocs: false,\n };\n}\n","import { access, readFile } from \"node:fs/promises\";\nimport { basename, extname, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport * as mammoth from \"mammoth\";\nimport * as pdfjs from \"pdfjs-dist/legacy/build/pdf.mjs\";\nimport { parseDocument as parseYamlDocument } from \"yaml\";\n\nimport { parseMarkdown } from \"../../markdown\";\nimport { parseTomlFrontmatter } from \"../../markdown/toml-simple\";\nimport {\n CODEX_FILENAME_TITLE_OUTPUT_SCHEMA,\n chunkItems,\n executeBatchesWithRetries,\n parseFilenameTitleSuggestions,\n startCodexReadOnlyThread,\n summarizeBatchErrors,\n} from \"./shared\";\n\nexport interface CodexDocumentRenameSuggestion {\n path: string;\n title: string;\n}\n\nexport interface CodexDocumentRenameReason {\n path: string;\n reason: string;\n}\n\nexport interface CodexDocumentRenameResult {\n suggestions: CodexDocumentRenameSuggestion[];\n reasons?: CodexDocumentRenameReason[];\n errorMessage?: string;\n}\n\ninterface SuggestDocumentTitlesOptions {\n documentPaths: string[];\n workingDirectory: string;\n timeoutMs?: number;\n retries?: number;\n batchSize?: number;\n}\n\ninterface DocumentTitleEvidence {\n filename: string;\n extension: string;\n detectedType: \"markdown\" | \"text\" | \"json\" | \"yaml\" | \"toml\" | \"html\" | \"xml\" | \"pdf\" | \"docx\";\n titleCandidates: string[];\n authorCandidates?: string[];\n headings?: string[];\n tocCandidates?: string[];\n leadText?: string;\n keySummary?: string[];\n metadata?: Record<string, unknown>;\n warnings?: string[];\n}\n\ninterface PromptDocumentTitleEvidence extends Omit<DocumentTitleEvidence, \"filename\"> {\n basename: string;\n filename: string;\n}\n\nconst DOC_MARKDOWN_EXTENSIONS = new Set([\".md\", \".markdown\"]);\nconst DOC_PLAIN_TEXT_EXTENSIONS = new Set([\".txt\"]);\nconst DOC_JSON_EXTENSIONS = new Set([\".json\"]);\nconst DOC_YAML_EXTENSIONS = new Set([\".yaml\", \".yml\"]);\nconst DOC_TOML_EXTENSIONS = new Set([\".toml\"]);\nconst DOC_HTML_EXTENSIONS = new Set([\".html\", \".htm\"]);\nconst DOC_XML_EXTENSIONS = new Set([\".xml\"]);\nconst DOC_PDF_EXTENSIONS = new Set([\".pdf\"]);\nconst DOC_DOCX_EXTENSIONS = new Set([\".docx\"]);\nconst MAX_TITLE_CANDIDATES = 4;\nconst MAX_HEADINGS = 8;\nconst MAX_LEAD_TEXT_CHARS = 800;\nconst MAX_KEY_SUMMARY = 12;\nlet pdfStandardFontDataUrlPromise: Promise<string | undefined> | undefined;\n\nfunction toSingleLine(value: string): string {\n return value.replace(/\\s+/g, \" \").trim();\n}\n\nfunction firstParagraph(lines: string[]): string | undefined {\n const paragraphLines: string[] = [];\n for (const rawLine of lines) {\n const line = rawLine.trim();\n if (!line) {\n if (paragraphLines.length > 0) {\n break;\n }\n continue;\n }\n paragraphLines.push(line);\n if (toSingleLine(paragraphLines.join(\" \")).length >= MAX_LEAD_TEXT_CHARS) {\n break;\n }\n }\n\n if (paragraphLines.length === 0) {\n return undefined;\n }\n\n return toSingleLine(paragraphLines.join(\" \")).slice(0, MAX_LEAD_TEXT_CHARS);\n}\n\nfunction getStringCandidate(data: Record<string, unknown> | null, keys: string[]): string | undefined {\n if (!data) {\n return undefined;\n }\n for (const key of keys) {\n const value = data[key];\n if (typeof value === \"string\") {\n const normalized = toSingleLine(value);\n if (normalized) {\n return normalized;\n }\n }\n }\n return undefined;\n}\n\nfunction getNestedStringCandidate(\n data: Record<string, unknown> | null,\n paths: string[][],\n): string | undefined {\n if (!data) {\n return undefined;\n }\n\n for (const path of paths) {\n let current: unknown = data;\n let ok = true;\n for (const segment of path) {\n if (!current || typeof current !== \"object\" || Array.isArray(current)) {\n ok = false;\n break;\n }\n current = (current as Record<string, unknown>)[segment];\n }\n if (!ok || typeof current !== \"string\") {\n continue;\n }\n const normalized = toSingleLine(current);\n if (normalized) {\n return normalized;\n }\n }\n\n return undefined;\n}\n\nfunction collectKeySummary(data: Record<string, unknown> | null): string[] | undefined {\n if (!data) {\n return undefined;\n }\n\n const keys = Object.keys(data)\n .map((key) => key.trim())\n .filter(Boolean)\n .slice(0, MAX_KEY_SUMMARY);\n\n return keys.length > 0 ? keys : undefined;\n}\n\nasync function resolvePdfStandardFontDataUrl(): Promise<string | undefined> {\n pdfStandardFontDataUrlPromise ??= (async () => {\n const candidates = [\n new URL(\"../../../node_modules/pdfjs-dist/standard_fonts/\", import.meta.url),\n new URL(\"../../../../node_modules/pdfjs-dist/standard_fonts/\", import.meta.url),\n ];\n\n for (const candidate of candidates) {\n try {\n await access(fileURLToPath(candidate));\n return candidate.href;\n } catch {\n // try next\n }\n }\n\n return undefined;\n })();\n\n return pdfStandardFontDataUrlPromise;\n}\n\nfunction buildStructuredLeadText(data: Record<string, unknown> | null): string | undefined {\n if (!data) {\n return undefined;\n }\n const candidates: string[] = [];\n for (const key of [\"description\", \"summary\", \"subtitle\"]) {\n const value = data[key];\n if (typeof value === \"string\") {\n const normalized = toSingleLine(value);\n if (normalized) {\n candidates.push(normalized);\n }\n }\n }\n if (candidates.length === 0) {\n return undefined;\n }\n return toSingleLine(candidates.join(\" \")).slice(0, MAX_LEAD_TEXT_CHARS);\n}\n\nfunction extractStructuredObjectEvidence(options: {\n path: string;\n data: Record<string, unknown> | null;\n detectedType: DocumentTitleEvidence[\"detectedType\"];\n}): DocumentTitleEvidence | { reason: string } {\n const { path, data, detectedType } = options;\n if (!data) {\n return { reason: \"doc_no_text\" };\n }\n\n const titleCandidates = [\n getStringCandidate(data, [\"title\", \"name\", \"subject\"]),\n getNestedStringCandidate(data, [\n [\"metadata\", \"title\"],\n [\"meta\", \"title\"],\n [\"package\", \"name\"],\n ]),\n ]\n .filter((value): value is string => Boolean(value))\n .map(toSingleLine);\n\n const authorCandidate = [\n getStringCandidate(data, [\"author\", \"creator\", \"owner\"]),\n getNestedStringCandidate(data, [\n [\"metadata\", \"author\"],\n [\"meta\", \"author\"],\n [\"package\", \"author\"],\n ]),\n ].find((value): value is string => Boolean(value));\n\n const leadText = buildStructuredLeadText(data);\n const keySummary = collectKeySummary(data);\n const dedupedTitles = [...new Set(titleCandidates)].slice(0, MAX_TITLE_CANDIDATES);\n\n if (dedupedTitles.length === 0 && !leadText && !(keySummary && keySummary.length > 0)) {\n return { reason: \"doc_no_title_signal\" };\n }\n\n return {\n filename: basename(path),\n extension: extname(path).toLowerCase(),\n detectedType,\n titleCandidates: dedupedTitles,\n authorCandidates: authorCandidate ? [authorCandidate] : undefined,\n leadText,\n keySummary,\n };\n}\n\nfunction stripHtmlTags(html: string): string {\n return html\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \" \")\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \" \")\n .replace(/<!--[\\s\\S]*?-->/g, \" \")\n .replace(/<[^>]+>/g, \" \")\n .replace(/ /gi, \" \")\n .replace(/&/gi, \"&\")\n .replace(/</gi, \"<\")\n .replace(/>/gi, \">\");\n}\n\nfunction extractHtmlTextLines(html: string): string[] {\n return stripHtmlTags(html)\n .replace(/\\r\\n/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => toSingleLine(line))\n .filter(Boolean);\n}\n\nfunction extractHtmlEvidence(path: string, content: string): DocumentTitleEvidence | { reason: string } {\n const titleCandidates: string[] = [];\n const headings: string[] = [];\n const warnings: string[] = [];\n\n const titleMatch = content.match(/<title[^>]*>([\\s\\S]*?)<\\/title>/i);\n if (titleMatch?.[1]) {\n const title = toSingleLine(stripHtmlTags(titleMatch[1]));\n if (title) {\n titleCandidates.push(title);\n }\n }\n\n const authorMetaMatch =\n content.match(/<meta[^>]+name=[\"']author[\"'][^>]+content=[\"']([^\"']+)[\"'][^>]*>/i) ??\n content.match(/<meta[^>]+content=[\"']([^\"']+)[\"'][^>]+name=[\"']author[\"'][^>]*>/i);\n const author = authorMetaMatch?.[1] ? toSingleLine(authorMetaMatch[1]) : undefined;\n\n for (const match of content.matchAll(/<h([1-6])[^>]*>([\\s\\S]*?)<\\/h\\1>/gi)) {\n const heading = toSingleLine(stripHtmlTags(match[2] ?? \"\"));\n if (!heading) {\n continue;\n }\n headings.push(heading);\n if ((match[1] ?? \"\") === \"1\") {\n titleCandidates.push(heading);\n }\n }\n\n const textLines = extractHtmlTextLines(content);\n const leadText = firstParagraph(textLines);\n if (!leadText) {\n warnings.push(\"no_lead_text\");\n }\n\n const dedupedTitles = [...new Set(titleCandidates)].slice(0, MAX_TITLE_CANDIDATES);\n const dedupedHeadings = [...new Set(headings)].slice(0, MAX_HEADINGS);\n\n if (dedupedTitles.length === 0 && !leadText && dedupedHeadings.length === 0) {\n return { reason: content.trim().length > 0 ? \"doc_no_title_signal\" : \"doc_no_text\" };\n }\n\n return {\n filename: basename(path),\n extension: extname(path).toLowerCase(),\n detectedType: \"html\",\n titleCandidates: dedupedTitles,\n authorCandidates: author ? [author] : undefined,\n headings: dedupedHeadings.length > 0 ? dedupedHeadings : undefined,\n leadText,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\nfunction extractXmlEvidence(path: string, content: string): DocumentTitleEvidence | { reason: string } {\n const titleCandidates: string[] = [];\n const warnings: string[] = [];\n\n const tagCandidates = [\"title\", \"name\", \"subject\"];\n for (const tag of tagCandidates) {\n const match = content.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)<\\\\/${tag}>`, \"i\"));\n if (!match?.[1]) {\n continue;\n }\n const text = toSingleLine(stripHtmlTags(match[1]));\n if (text) {\n titleCandidates.push(text);\n }\n }\n\n const textLines = extractHtmlTextLines(content);\n const leadText = firstParagraph(textLines);\n if (!leadText) {\n warnings.push(\"no_lead_text\");\n }\n\n const dedupedTitles = [...new Set(titleCandidates)].slice(0, MAX_TITLE_CANDIDATES);\n if (dedupedTitles.length === 0 && !leadText) {\n return { reason: content.trim().length > 0 ? \"doc_no_title_signal\" : \"doc_no_text\" };\n }\n\n return {\n filename: basename(path),\n extension: extname(path).toLowerCase(),\n detectedType: \"xml\",\n titleCandidates: dedupedTitles,\n leadText,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\nfunction extractPdfTitleAndSignals(options: {\n path: string;\n pageCount: number;\n metadataInfo?: Record<string, unknown>;\n outlineTitles: string[];\n firstPageText: string;\n warnings: string[];\n}): DocumentTitleEvidence | { reason: string } {\n const metadataInfo = options.metadataInfo;\n const metadataTitle =\n typeof metadataInfo?.Title === \"string\" ? toSingleLine(metadataInfo.Title) : undefined;\n const metadataAuthor =\n typeof metadataInfo?.Author === \"string\" ? toSingleLine(metadataInfo.Author) : undefined;\n\n const sentenceTitle =\n options.firstPageText\n .split(/(?<=[.!?])\\s+/)\n .map((part) => toSingleLine(part))\n .find(Boolean) ?? undefined;\n\n const titleCandidates = [metadataTitle, options.outlineTitles[0], sentenceTitle].filter(\n (value): value is string => Boolean(value),\n );\n const dedupedTitles = [...new Set(titleCandidates)].slice(0, MAX_TITLE_CANDIDATES);\n const dedupedOutline = [...new Set(options.outlineTitles)].slice(0, MAX_HEADINGS);\n const leadText = options.firstPageText ? options.firstPageText.slice(0, MAX_LEAD_TEXT_CHARS) : undefined;\n\n if (dedupedTitles.length === 0 && !metadataAuthor && !leadText && dedupedOutline.length === 0) {\n return { reason: options.firstPageText ? \"pdf_no_title_signal\" : \"pdf_no_text\" };\n }\n\n return {\n filename: basename(options.path),\n extension: extname(options.path).toLowerCase(),\n detectedType: \"pdf\",\n titleCandidates: dedupedTitles,\n authorCandidates: metadataAuthor ? [metadataAuthor] : undefined,\n headings: dedupedOutline.length > 0 ? dedupedOutline : undefined,\n tocCandidates: dedupedOutline.length > 0 ? dedupedOutline : undefined,\n leadText,\n metadata: {\n pageCount: options.pageCount,\n pdfTitle: metadataTitle,\n pdfAuthor: metadataAuthor,\n creator: typeof metadataInfo?.Creator === \"string\" ? metadataInfo.Creator : undefined,\n producer: typeof metadataInfo?.Producer === \"string\" ? metadataInfo.Producer : undefined,\n },\n warnings: options.warnings.length > 0 ? options.warnings : undefined,\n };\n}\n\nasync function extractPdfEvidence(path: string): Promise<DocumentTitleEvidence | { reason: string }> {\n let pdfDocument: any;\n try {\n const fileBytes = await readFile(path);\n const standardFontDataUrl = await resolvePdfStandardFontDataUrl();\n const loadingTask = (pdfjs as any).getDocument({\n data: new Uint8Array(fileBytes),\n worker: null,\n useWorkerFetch: false,\n standardFontDataUrl,\n isOffscreenCanvasSupported: false,\n isImageDecoderSupported: false,\n verbosity: (pdfjs as any).VerbosityLevel?.ERRORS ?? 0,\n });\n pdfDocument = await loadingTask.promise;\n const pageCount = Number(pdfDocument?.numPages ?? 0);\n const warnings: string[] = [];\n\n let metadataInfo: Record<string, unknown> | undefined;\n try {\n const metadata = await pdfDocument.getMetadata();\n metadataInfo = (metadata?.info ?? undefined) as Record<string, unknown> | undefined;\n } catch {\n warnings.push(\"pdf_metadata_unavailable\");\n }\n\n let outlineTitles: string[] = [];\n try {\n const outline = (await pdfDocument.getOutline()) as Array<{ title?: string }> | null;\n outlineTitles =\n outline\n ?.map((item) => toSingleLine(item.title ?? \"\"))\n .filter(Boolean)\n .slice(0, 20) ?? [];\n if (outlineTitles.length === 0) {\n warnings.push(\"pdf_outline_unavailable\");\n }\n } catch {\n warnings.push(\"pdf_outline_unavailable\");\n }\n\n let firstPageText = \"\";\n try {\n if (pageCount >= 1) {\n const page = await pdfDocument.getPage(1);\n const textContent = await page.getTextContent();\n const textItems = (textContent.items ?? []) as Array<{ str?: string }>;\n firstPageText = toSingleLine(\n textItems\n .map((item) => item.str ?? \"\")\n .join(\" \")\n .trim(),\n );\n }\n if (!firstPageText) {\n warnings.push(\"pdf_no_page1_text\");\n }\n } catch {\n warnings.push(\"pdf_no_page1_text\");\n }\n\n return extractPdfTitleAndSignals({\n path,\n pageCount,\n metadataInfo,\n outlineTitles,\n firstPageText,\n warnings,\n });\n } catch {\n return { reason: \"pdf_extract_error\" };\n } finally {\n try {\n await pdfDocument?.destroy?.();\n } catch {\n // ignore cleanup issues\n }\n }\n}\n\nasync function extractDocxEvidence(path: string): Promise<DocumentTitleEvidence | { reason: string }> {\n try {\n const buffer = await readFile(path);\n const [htmlResult, rawTextResult] = await Promise.all([\n mammoth.convertToHtml({ buffer }),\n mammoth.extractRawText({ buffer }),\n ]);\n\n const html = htmlResult.value ?? \"\";\n const rawText = rawTextResult.value ?? \"\";\n\n const titleCandidates: string[] = [];\n const headings: string[] = [];\n const warnings: string[] = [\"docx_metadata_unavailable\"];\n\n for (const match of html.matchAll(/<h([1-6])[^>]*>([\\s\\S]*?)<\\/h\\1>/gi)) {\n const heading = toSingleLine(stripHtmlTags(match[2] ?? \"\"));\n if (!heading) {\n continue;\n }\n headings.push(heading);\n if ((match[1] ?? \"\") === \"1\") {\n titleCandidates.push(heading);\n }\n }\n\n const rawLines = rawText\n .replace(/\\r\\n/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => toSingleLine(line))\n .filter(Boolean);\n if (rawLines.length > 0) {\n titleCandidates.push(rawLines[0]!);\n }\n\n const leadText = firstParagraph(rawLines);\n if (!leadText) {\n warnings.push(\"no_lead_text\");\n }\n\n const dedupedTitles = [...new Set(titleCandidates)].slice(0, MAX_TITLE_CANDIDATES);\n const dedupedHeadings = [...new Set(headings)].slice(0, MAX_HEADINGS);\n\n if (dedupedTitles.length === 0 && !leadText && dedupedHeadings.length === 0) {\n const hasAnyText = html.trim().length > 0 || rawText.trim().length > 0;\n return { reason: hasAnyText ? \"docx_no_title_signal\" : \"docx_extract_error\" };\n }\n\n return {\n filename: basename(path),\n extension: extname(path).toLowerCase(),\n detectedType: \"docx\",\n titleCandidates: dedupedTitles,\n headings: dedupedHeadings.length > 0 ? dedupedHeadings : undefined,\n tocCandidates: dedupedHeadings.length > 0 ? dedupedHeadings : undefined,\n leadText,\n metadata: {\n extractor: \"mammoth\",\n },\n warnings,\n };\n } catch {\n return { reason: \"docx_extract_error\" };\n }\n}\n\nfunction extractMarkdownEvidence(path: string, content: string): DocumentTitleEvidence | { reason: string } {\n const parsed = parseMarkdown(content);\n const titleCandidates: string[] = [];\n const headings: string[] = [];\n const warnings: string[] = [];\n\n const frontmatterTitle = getStringCandidate(parsed.data, [\"title\", \"name\"]);\n if (frontmatterTitle) {\n titleCandidates.push(frontmatterTitle);\n }\n const frontmatterAuthor = getStringCandidate(parsed.data, [\"author\", \"creator\"]);\n\n const contentLines = parsed.content.split(/\\r?\\n/);\n const nonHeadingLines: string[] = [];\n for (const rawLine of contentLines) {\n const trimmed = rawLine.trim();\n if (!trimmed) {\n nonHeadingLines.push(\"\");\n continue;\n }\n\n const headingMatch = trimmed.match(/^#{1,6}\\s+(.+)$/);\n if (headingMatch) {\n const headingText = toSingleLine(headingMatch[1] ?? \"\");\n if (headingText) {\n headings.push(headingText);\n if (headingMatch[0].startsWith(\"# \")) {\n titleCandidates.push(headingText);\n }\n }\n continue;\n }\n\n nonHeadingLines.push(trimmed);\n }\n\n const leadText = firstParagraph(nonHeadingLines);\n if (!leadText) {\n warnings.push(\"no_lead_text\");\n }\n\n const dedupedTitles = [...new Set(titleCandidates.map(toSingleLine).filter(Boolean))].slice(\n 0,\n MAX_TITLE_CANDIDATES,\n );\n const dedupedHeadings = [...new Set(headings)].slice(0, MAX_HEADINGS);\n\n if (dedupedTitles.length === 0 && !leadText && dedupedHeadings.length === 0) {\n const hasAnyText = content.trim().length > 0;\n return { reason: hasAnyText ? \"doc_no_title_signal\" : \"doc_no_text\" };\n }\n\n return {\n filename: basename(path),\n extension: extname(path).toLowerCase(),\n detectedType: \"markdown\",\n titleCandidates: dedupedTitles,\n authorCandidates: frontmatterAuthor ? [frontmatterAuthor] : undefined,\n headings: dedupedHeadings.length > 0 ? dedupedHeadings : undefined,\n leadText,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\nfunction extractPlainTextEvidence(path: string, content: string): DocumentTitleEvidence | { reason: string } {\n const lines = content.split(/\\r?\\n/);\n const nonEmpty = lines.map((line) => line.trim()).filter((line) => line.length > 0);\n if (nonEmpty.length === 0) {\n return { reason: \"doc_no_text\" };\n }\n\n const titleCandidates = [toSingleLine(nonEmpty[0] ?? \"\")].filter(Boolean).slice(0, MAX_TITLE_CANDIDATES);\n const leadText = firstParagraph(lines.map((line) => line.trim()));\n if (titleCandidates.length === 0 && !leadText) {\n return { reason: \"doc_no_title_signal\" };\n }\n\n return {\n filename: basename(path),\n extension: extname(path).toLowerCase(),\n detectedType: \"text\",\n titleCandidates,\n leadText,\n };\n}\n\nfunction extractJsonEvidence(path: string, content: string): DocumentTitleEvidence | { reason: string } {\n try {\n const parsed = JSON.parse(content) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return { reason: \"doc_no_title_signal\" };\n }\n return extractStructuredObjectEvidence({\n path,\n data: parsed as Record<string, unknown>,\n detectedType: \"json\",\n });\n } catch {\n return { reason: \"doc_extract_error\" };\n }\n}\n\nfunction extractYamlEvidence(path: string, content: string): DocumentTitleEvidence | { reason: string } {\n try {\n const doc = parseYamlDocument(content, { prettyErrors: false });\n if (doc.errors.length > 0) {\n return { reason: \"doc_extract_error\" };\n }\n const parsed = doc.toJSON();\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return { reason: \"doc_no_title_signal\" };\n }\n return extractStructuredObjectEvidence({\n path,\n data: parsed as Record<string, unknown>,\n detectedType: \"yaml\",\n });\n } catch {\n return { reason: \"doc_extract_error\" };\n }\n}\n\nfunction extractTomlEvidence(path: string, content: string): DocumentTitleEvidence | { reason: string } {\n try {\n const parsed = parseTomlFrontmatter(content);\n if (!parsed) {\n return { reason: \"doc_extract_error\" };\n }\n return extractStructuredObjectEvidence({\n path,\n data: parsed,\n detectedType: \"toml\",\n });\n } catch {\n return { reason: \"doc_extract_error\" };\n }\n}\n\nasync function extractEvidenceForPath(\n path: string,\n): Promise<{ evidence?: DocumentTitleEvidence; reason?: string }> {\n const ext = extname(path).toLowerCase();\n\n if (DOC_PDF_EXTENSIONS.has(ext)) {\n const extracted = await extractPdfEvidence(path);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n if (DOC_DOCX_EXTENSIONS.has(ext)) {\n const extracted = await extractDocxEvidence(path);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n let content: string;\n try {\n content = await readFile(path, \"utf8\");\n } catch {\n return { reason: \"doc_extract_error\" };\n }\n\n if (DOC_MARKDOWN_EXTENSIONS.has(ext)) {\n const extracted = extractMarkdownEvidence(path, content);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n if (DOC_PLAIN_TEXT_EXTENSIONS.has(ext)) {\n const extracted = extractPlainTextEvidence(path, content);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n if (DOC_JSON_EXTENSIONS.has(ext)) {\n const extracted = extractJsonEvidence(path, content);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n if (DOC_YAML_EXTENSIONS.has(ext)) {\n const extracted = extractYamlEvidence(path, content);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n if (DOC_TOML_EXTENSIONS.has(ext)) {\n const extracted = extractTomlEvidence(path, content);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n if (DOC_HTML_EXTENSIONS.has(ext)) {\n const extracted = extractHtmlEvidence(path, content);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n if (DOC_XML_EXTENSIONS.has(ext)) {\n const extracted = extractXmlEvidence(path, content);\n if (\"reason\" in extracted) {\n return { reason: extracted.reason };\n }\n return { evidence: extracted };\n }\n\n return { reason: \"doc_unsupported_type\" };\n}\n\nexport async function __testOnlyExtractDocumentTitleEvidenceForPath(\n path: string,\n): Promise<{ evidence?: DocumentTitleEvidence; reason?: string }> {\n return extractEvidenceForPath(path);\n}\n\nexport function __testOnlyBuildDocumentPrompt(options: {\n evidences: Array<{ path: string; evidence: DocumentTitleEvidence }>;\n workingDirectory: string;\n}): string {\n return buildPrompt(\n options.evidences.map((item) =>\n createPromptEvidence({\n evidence: item.evidence,\n path: item.path,\n workingDirectory: options.workingDirectory,\n }),\n ),\n );\n}\n\nfunction toPromptFilename(path: string, workingDirectory: string): string {\n return relative(workingDirectory, path).replaceAll(\"\\\\\", \"/\");\n}\n\nfunction createPromptEvidence(options: {\n evidence: DocumentTitleEvidence;\n path: string;\n workingDirectory: string;\n}): PromptDocumentTitleEvidence {\n return {\n ...options.evidence,\n basename: options.evidence.filename,\n filename: toPromptFilename(options.path, options.workingDirectory),\n };\n}\n\nfunction buildPrompt(evidences: PromptDocumentTitleEvidence[]): string {\n return [\n \"Generate concise semantic filename titles for these document files from extracted text evidence.\",\n \"Return JSON only following the provided schema.\",\n \"Rules:\",\n \"- One suggestion per listed filename when there is enough signal.\",\n \"- Use each item's exact `filename` value in the response so duplicate basenames stay disambiguated.\",\n \"- `title` should be 2-6 words.\",\n \"- No file extensions.\",\n \"- No punctuation except spaces and hyphens.\",\n \"- Prefer document topic/title over generic words like note/file/document.\",\n \"- If evidence is weak, use a cautious generic title based on available text only.\",\n \"\",\n \"Document evidence JSON:\",\n JSON.stringify(evidences, null, 2),\n ].join(\"\\n\");\n}\n\nasync function suggestSingleBatch(options: {\n evidences: Array<{ path: string; promptFilename: string; evidence: DocumentTitleEvidence }>;\n workingDirectory: string;\n timeoutMs?: number;\n}): Promise<CodexDocumentRenameResult> {\n if (options.evidences.length === 0) {\n return { suggestions: [] };\n }\n\n const thread = startCodexReadOnlyThread(options.workingDirectory);\n const promptEvidences = options.evidences.map((item) =>\n createPromptEvidence({\n evidence: item.evidence,\n path: item.path,\n workingDirectory: options.workingDirectory,\n }),\n );\n\n const turn = await thread.run(\n [{ type: \"text\", text: buildPrompt(promptEvidences) }],\n {\n outputSchema: CODEX_FILENAME_TITLE_OUTPUT_SCHEMA,\n signal: AbortSignal.timeout(options.timeoutMs ?? 30_000),\n },\n );\n\n const suggestionsByFilename = parseFilenameTitleSuggestions(turn.finalResponse);\n\n const suggestions: CodexDocumentRenameSuggestion[] = [];\n for (const item of options.evidences) {\n const title = suggestionsByFilename.get(item.promptFilename);\n if (!title) {\n continue;\n }\n suggestions.push({ path: item.path, title });\n }\n\n return { suggestions };\n}\n\nexport async function suggestDocumentRenameTitlesWithCodex(\n options: SuggestDocumentTitlesOptions,\n): Promise<CodexDocumentRenameResult> {\n if (options.documentPaths.length === 0) {\n return { suggestions: [] };\n }\n\n const reasons: CodexDocumentRenameReason[] = [];\n const evidenceItems: Array<{ path: string; promptFilename: string; evidence: DocumentTitleEvidence }> = [];\n\n for (const path of options.documentPaths) {\n const extracted = await extractEvidenceForPath(path);\n if (extracted.reason) {\n reasons.push({ path, reason: extracted.reason });\n continue;\n }\n if (extracted.evidence) {\n evidenceItems.push({\n path,\n promptFilename: toPromptFilename(path, options.workingDirectory),\n evidence: extracted.evidence,\n });\n }\n }\n\n if (evidenceItems.length === 0) {\n return { suggestions: [], reasons };\n }\n\n try {\n const batchSize = Math.max(1, Math.trunc(options.batchSize ?? evidenceItems.length));\n const retries = Math.max(0, Math.trunc(options.retries ?? 0));\n const batches = chunkItems(evidenceItems, batchSize);\n const { suggestions, batchErrors } = await executeBatchesWithRetries({\n batches,\n retries,\n runBatch: async (batch) =>\n suggestSingleBatch({\n evidences: batch,\n workingDirectory: options.workingDirectory,\n timeoutMs: options.timeoutMs,\n }),\n });\n\n const errorSummary = summarizeBatchErrors(batchErrors, suggestions.length > 0);\n if (!errorSummary) {\n return { suggestions, reasons };\n }\n\n return { suggestions, reasons, errorMessage: errorSummary };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { suggestions: [], reasons, errorMessage: message };\n }\n}\n","import { basename } from \"node:path\";\n\nimport {\n CODEX_FILENAME_TITLE_OUTPUT_SCHEMA,\n chunkItems,\n executeBatchesWithRetries,\n parseFilenameTitleSuggestions,\n startCodexReadOnlyThread,\n summarizeBatchErrors,\n} from \"./shared\";\n\nexport interface CodexImageRenameSuggestion {\n path: string;\n title: string;\n}\n\nexport interface CodexImageRenameResult {\n suggestions: CodexImageRenameSuggestion[];\n errorMessage?: string;\n}\n\ninterface SuggestImageTitlesOptions {\n imagePaths: string[];\n workingDirectory: string;\n timeoutMs?: number;\n retries?: number;\n batchSize?: number;\n}\n\nfunction buildPrompt(imagePaths: string[]): string {\n const fileList = imagePaths.map((path, index) => `${index + 1}. ${basename(path)}`).join(\"\\n\");\n return [\n \"Generate concise semantic titles for these image files.\",\n \"Return JSON only following the provided schema.\",\n \"Rules:\",\n \"- One suggestion per listed filename.\",\n \"- `title` should be 2-6 words.\",\n \"- Describe visible subject/content when possible.\",\n \"- No file extensions.\",\n \"- No punctuation except spaces and hyphens.\",\n \"- Lower risk of hallucination: if unclear, use a generic but plausible visual label.\",\n \"\",\n \"Filenames in order:\",\n fileList,\n ].join(\"\\n\");\n}\n\nasync function suggestSingleBatch(\n options: SuggestImageTitlesOptions,\n): Promise<CodexImageRenameResult> {\n if (options.imagePaths.length === 0) {\n return { suggestions: [] };\n }\n\n const thread = startCodexReadOnlyThread(options.workingDirectory);\n\n const input = [\n { type: \"text\", text: buildPrompt(options.imagePaths) } as const,\n ...options.imagePaths.map((path) => ({ type: \"local_image\", path } as const)),\n ];\n\n const turn = await thread.run(input, {\n outputSchema: CODEX_FILENAME_TITLE_OUTPUT_SCHEMA,\n signal: AbortSignal.timeout(options.timeoutMs ?? 30_000),\n });\n const suggestionsByFilename = parseFilenameTitleSuggestions(turn.finalResponse);\n\n const suggestions: CodexImageRenameSuggestion[] = [];\n for (const path of options.imagePaths) {\n const filename = basename(path);\n const title = suggestionsByFilename.get(filename);\n if (!title) {\n continue;\n }\n suggestions.push({ path, title });\n }\n\n return { suggestions };\n}\n\nexport async function suggestImageRenameTitlesWithCodex(\n options: SuggestImageTitlesOptions,\n): Promise<CodexImageRenameResult> {\n if (options.imagePaths.length === 0) {\n return { suggestions: [] };\n }\n\n try {\n const batchSize = Math.max(1, Math.trunc(options.batchSize ?? options.imagePaths.length));\n const retries = Math.max(0, Math.trunc(options.retries ?? 0));\n const batches = chunkItems(options.imagePaths, batchSize);\n const { suggestions, batchErrors } = await executeBatchesWithRetries({\n batches,\n retries,\n runBatch: async (batch) =>\n suggestSingleBatch({\n imagePaths: batch,\n workingDirectory: options.workingDirectory,\n timeoutMs: options.timeoutMs,\n }),\n });\n\n const errorSummary = summarizeBatchErrors(batchErrors, suggestions.length > 0);\n if (!errorSummary) {\n return { suggestions };\n }\n\n return { suggestions, errorMessage: errorSummary };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { suggestions: [], errorMessage: message };\n }\n}\n","import { stat } from \"node:fs/promises\";\nimport { extname } from \"node:path\";\n\nimport {\n suggestDocumentRenameTitlesWithCodex,\n type CodexDocumentRenameResult,\n} from \"../../../adapters/codex/document-rename-titles\";\nimport {\n suggestImageRenameTitlesWithCodex,\n type CodexImageRenameResult,\n} from \"../../../adapters/codex/image-rename-titles\";\nimport type { PlannedRename, CliRuntime } from \"../../types\";\nimport { printLine } from \"../shared\";\n\nexport type CodexImageRenameTitleSuggester = (options: {\n imagePaths: string[];\n workingDirectory: string;\n timeoutMs?: number;\n retries?: number;\n batchSize?: number;\n}) => Promise<CodexImageRenameResult>;\n\nexport type CodexDocumentRenameTitleSuggester = (options: {\n documentPaths: string[];\n workingDirectory: string;\n timeoutMs?: number;\n retries?: number;\n batchSize?: number;\n}) => Promise<CodexDocumentRenameResult>;\n\nexport interface RenameCodexCliOptions {\n codex?: boolean;\n codexImages?: boolean;\n codexImagesTimeoutMs?: number;\n codexImagesRetries?: number;\n codexImagesBatchSize?: number;\n codexImagesTitleSuggester?: CodexImageRenameTitleSuggester;\n codexDocs?: boolean;\n codexDocsTimeoutMs?: number;\n codexDocsRetries?: number;\n codexDocsBatchSize?: number;\n codexDocsTitleSuggester?: CodexDocumentRenameTitleSuggester;\n}\n\nexport interface RenameCodexEffectiveFlags {\n codexImages: boolean;\n codexDocs: boolean;\n}\n\ninterface RenameTitleAnalyzerSuggestion {\n path: string;\n title: string;\n}\n\ninterface RenameTitleAnalyzerSuggestionResult {\n suggestions: RenameTitleAnalyzerSuggestion[];\n errorMessage?: string;\n reasonByPath?: Map<string, string>;\n}\n\ninterface RenameTitleAnalyzerSelection {\n candidateCount: number;\n eligiblePaths: string[];\n skipReasonByPath: Map<string, string>;\n}\n\ninterface RenameTitleAnalyzerRunResult {\n candidateCount: number;\n eligibleCount: number;\n suggestedCount: number;\n errorMessage: string | null;\n titlesByPath?: Map<string, string>;\n reasonBySourcePath: Map<string, string>;\n}\n\ninterface RenameTitleAnalyzer {\n summaryLabel: string;\n progressLabelForCount: (eligibleCount: number) => string;\n selectCandidates: (plans: PlannedRename[]) => Promise<RenameTitleAnalyzerSelection>;\n suggestTitles: (options: {\n paths: string[];\n workingDirectory: string;\n timeoutMs?: number;\n retries?: number;\n batchSize?: number;\n }) => Promise<RenameTitleAnalyzerSuggestionResult>;\n}\n\ninterface RenameCodexChannelResult {\n summaryLabel: string;\n candidateCount: number;\n eligibleCount: number;\n suggestedCount: number;\n errorMessage: string | null;\n titlesByPath?: Map<string, string>;\n}\n\nexport interface RenameCodexAnalysisResult {\n effectiveFlags: RenameCodexEffectiveFlags;\n image?: RenameCodexChannelResult;\n doc?: RenameCodexChannelResult;\n titlesByPath: Map<string, string>;\n reasonBySourcePath: Map<string, string>;\n}\n\nconst IMAGE_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".webp\",\n \".gif\",\n \".bmp\",\n \".tif\",\n \".tiff\",\n \".avif\",\n]);\n\nconst CODEX_MAX_IMAGE_BYTES = 20 * 1024 * 1024;\nconst CODEX_STATIC_IMAGE_EXTENSIONS = new Set(\n [...IMAGE_EXTENSIONS].filter((ext) => ext !== \".gif\"),\n);\n\nconst CODEX_TEXT_DOCUMENT_EXTENSIONS = new Set([\n \".md\",\n \".markdown\",\n \".txt\",\n \".json\",\n \".yaml\",\n \".yml\",\n \".toml\",\n \".xml\",\n \".html\",\n \".htm\",\n]);\nconst CODEX_PDF_DOCUMENT_EXTENSIONS = new Set([\".pdf\"]);\nconst CODEX_DOCX_DOCUMENT_EXTENSIONS = new Set([\".docx\"]);\nconst CODEX_MAX_TEXT_DOCUMENT_BYTES = 512 * 1024;\nconst CODEX_MAX_PDF_DOCUMENT_BYTES = 20 * 1024 * 1024;\nconst CODEX_MAX_DOCX_DOCUMENT_BYTES = 10 * 1024 * 1024;\n\nfunction isCodexDocxExperimentalEnabled(): boolean {\n return process.env.CDX_CHORES_CODEX_DOCS_DOCX_EXPERIMENTAL === \"1\";\n}\n\nasync function selectCodexStaticImageCandidates(\n plans: PlannedRename[],\n): Promise<RenameTitleAnalyzerSelection> {\n const eligiblePaths: string[] = [];\n let candidateCount = 0;\n const skipReasonByPath = new Map<string, string>();\n\n for (const plan of plans) {\n const sourcePath = plan.fromPath;\n const ext = extname(sourcePath).toLowerCase();\n if (!IMAGE_EXTENSIONS.has(ext)) {\n continue;\n }\n\n candidateCount += 1;\n\n if (!CODEX_STATIC_IMAGE_EXTENSIONS.has(ext)) {\n skipReasonByPath.set(sourcePath, \"codex_skipped_non_static\");\n continue;\n }\n\n try {\n const fileStats = await stat(sourcePath);\n if (!fileStats.isFile()) {\n skipReasonByPath.set(sourcePath, \"codex_skipped_unreadable\");\n continue;\n }\n if (fileStats.size > CODEX_MAX_IMAGE_BYTES) {\n skipReasonByPath.set(sourcePath, \"codex_skipped_too_large\");\n continue;\n }\n } catch {\n skipReasonByPath.set(sourcePath, \"codex_skipped_unreadable\");\n continue;\n }\n\n eligiblePaths.push(sourcePath);\n }\n\n return { candidateCount, eligiblePaths, skipReasonByPath };\n}\n\nfunction createCodexStaticImageTitleAnalyzer(options: {\n titleSuggester?: CodexImageRenameTitleSuggester;\n}): RenameTitleAnalyzer {\n const titleSuggester = options.titleSuggester ?? suggestImageRenameTitlesWithCodex;\n return {\n summaryLabel: \"Codex image titles\",\n progressLabelForCount: (eligibleCount) => `Codex: analyzing ${eligibleCount} image file(s)`,\n selectCandidates: selectCodexStaticImageCandidates,\n suggestTitles: async ({ paths, workingDirectory, timeoutMs, retries, batchSize }) => {\n const result = await titleSuggester({\n imagePaths: paths,\n workingDirectory,\n timeoutMs,\n retries,\n batchSize,\n });\n return { suggestions: result.suggestions, errorMessage: result.errorMessage };\n },\n };\n}\n\nasync function selectCodexDocumentTextCandidates(\n plans: PlannedRename[],\n): Promise<RenameTitleAnalyzerSelection> {\n const eligiblePaths: string[] = [];\n let candidateCount = 0;\n const skipReasonByPath = new Map<string, string>();\n\n for (const plan of plans) {\n const sourcePath = plan.fromPath;\n const ext = extname(sourcePath).toLowerCase();\n const isTextLike = CODEX_TEXT_DOCUMENT_EXTENSIONS.has(ext);\n const isPdf = CODEX_PDF_DOCUMENT_EXTENSIONS.has(ext);\n const isDocx = CODEX_DOCX_DOCUMENT_EXTENSIONS.has(ext);\n if (!isTextLike && !isPdf && !isDocx) {\n continue;\n }\n\n candidateCount += 1;\n\n if (isDocx && !isCodexDocxExperimentalEnabled()) {\n skipReasonByPath.set(sourcePath, \"docx_experimental_disabled\");\n continue;\n }\n\n try {\n const fileStats = await stat(sourcePath);\n if (!fileStats.isFile()) {\n skipReasonByPath.set(\n sourcePath,\n isPdf\n ? \"pdf_skipped_unreadable\"\n : isDocx\n ? \"docx_skipped_unreadable\"\n : \"doc_skipped_unreadable\",\n );\n continue;\n }\n const sizeLimit = isPdf\n ? CODEX_MAX_PDF_DOCUMENT_BYTES\n : isDocx\n ? CODEX_MAX_DOCX_DOCUMENT_BYTES\n : CODEX_MAX_TEXT_DOCUMENT_BYTES;\n if (fileStats.size > sizeLimit) {\n skipReasonByPath.set(\n sourcePath,\n isPdf\n ? \"pdf_skipped_too_large\"\n : isDocx\n ? \"docx_skipped_too_large\"\n : \"doc_skipped_too_large\",\n );\n continue;\n }\n } catch {\n skipReasonByPath.set(\n sourcePath,\n isPdf\n ? \"pdf_skipped_unreadable\"\n : isDocx\n ? \"docx_skipped_unreadable\"\n : \"doc_skipped_unreadable\",\n );\n continue;\n }\n\n eligiblePaths.push(sourcePath);\n }\n\n return { candidateCount, eligiblePaths, skipReasonByPath };\n}\n\nfunction createCodexDocumentTextTitleAnalyzer(options: {\n titleSuggester?: CodexDocumentRenameTitleSuggester;\n}): RenameTitleAnalyzer {\n const titleSuggester = options.titleSuggester ?? suggestDocumentRenameTitlesWithCodex;\n return {\n summaryLabel: \"Codex doc titles\",\n progressLabelForCount: (eligibleCount) =>\n `Codex: analyzing ${eligibleCount} document file(s)`,\n selectCandidates: selectCodexDocumentTextCandidates,\n suggestTitles: async ({ paths, workingDirectory, timeoutMs, retries, batchSize }) => {\n const result = await titleSuggester({\n documentPaths: paths,\n workingDirectory,\n timeoutMs,\n retries,\n batchSize,\n });\n return {\n suggestions: result.suggestions,\n errorMessage: result.errorMessage,\n reasonByPath: result.reasons\n ? new Map(result.reasons.map((item) => [item.path, item.reason]))\n : undefined,\n };\n },\n };\n}\n\nfunction startAnalyzerProgress(\n runtime: CliRuntime,\n label: string,\n): { stop: (status: \"done\" | \"fallback\") => void } {\n const stream = runtime.stdout as NodeJS.WritableStream & { isTTY?: boolean };\n\n if (!stream.isTTY) {\n printLine(runtime.stdout, `${label}...`);\n return { stop: () => {} };\n }\n\n const frames = [\"-\", \"\\\\\", \"|\", \"/\"];\n let frameIndex = 0;\n const render = () => {\n const frame = frames[frameIndex % frames.length] ?? \"-\";\n frameIndex += 1;\n stream.write(`\\r${label}... ${frame}`);\n };\n\n render();\n const timer = setInterval(render, 120);\n\n return {\n stop: (status) => {\n clearInterval(timer);\n stream.write(`\\r${label}... ${status === \"done\" ? \"done\" : \"fallback\"}\\n`);\n },\n };\n}\n\nasync function runRenameTitleAnalyzer(\n runtime: CliRuntime,\n plans: PlannedRename[],\n analyzer: RenameTitleAnalyzer,\n options: {\n timeoutMs?: number;\n retries?: number;\n batchSize?: number;\n },\n): Promise<RenameTitleAnalyzerRunResult> {\n const selection = await analyzer.selectCandidates(plans);\n const reasonBySourcePath = new Map(selection.skipReasonByPath);\n let errorMessage: string | null = null;\n let titlesByPath: Map<string, string> | undefined;\n let suggestedCount = 0;\n\n if (selection.eligiblePaths.length > 0) {\n const progress = startAnalyzerProgress(\n runtime,\n analyzer.progressLabelForCount(selection.eligiblePaths.length),\n );\n const result = await analyzer.suggestTitles({\n paths: selection.eligiblePaths,\n workingDirectory: runtime.cwd,\n timeoutMs: options.timeoutMs,\n retries: options.retries,\n batchSize: options.batchSize,\n });\n progress.stop(result.errorMessage ? \"fallback\" : \"done\");\n errorMessage = result.errorMessage ?? null;\n\n if (result.suggestions.length > 0) {\n titlesByPath = new Map(result.suggestions.map((item) => [item.path, item.title]));\n suggestedCount = result.suggestions.length;\n }\n\n if (result.reasonByPath) {\n for (const [path, reason] of result.reasonByPath) {\n if (titlesByPath?.has(path)) {\n continue;\n }\n reasonBySourcePath.set(path, reason);\n }\n }\n\n for (const path of selection.eligiblePaths) {\n if (titlesByPath?.has(path)) {\n continue;\n }\n if (reasonBySourcePath.has(path)) {\n continue;\n }\n reasonBySourcePath.set(path, errorMessage ? \"codex_fallback_error\" : \"codex_no_suggestion\");\n }\n }\n\n return {\n candidateCount: selection.candidateCount,\n eligibleCount: selection.eligiblePaths.length,\n suggestedCount,\n errorMessage,\n titlesByPath,\n reasonBySourcePath,\n };\n}\n\nexport async function runRenameCodexAnalysis(\n runtime: CliRuntime,\n plans: PlannedRename[],\n options: {\n effectiveFlags: RenameCodexEffectiveFlags;\n cli: RenameCodexCliOptions;\n },\n): Promise<RenameCodexAnalysisResult> {\n let image: RenameCodexChannelResult | undefined;\n let doc: RenameCodexChannelResult | undefined;\n const reasonBySourcePath = new Map<string, string>();\n\n if (options.effectiveFlags.codexImages) {\n const analyzer = createCodexStaticImageTitleAnalyzer({\n titleSuggester: options.cli.codexImagesTitleSuggester,\n });\n const run = await runRenameTitleAnalyzer(runtime, plans, analyzer, {\n timeoutMs: options.cli.codexImagesTimeoutMs,\n retries: options.cli.codexImagesRetries,\n batchSize: options.cli.codexImagesBatchSize,\n });\n image = {\n summaryLabel: analyzer.summaryLabel,\n candidateCount: run.candidateCount,\n eligibleCount: run.eligibleCount,\n suggestedCount: run.suggestedCount,\n errorMessage: run.errorMessage,\n titlesByPath: run.titlesByPath,\n };\n for (const [path, reason] of run.reasonBySourcePath) {\n reasonBySourcePath.set(path, reason);\n }\n }\n\n if (options.effectiveFlags.codexDocs) {\n const analyzer = createCodexDocumentTextTitleAnalyzer({\n titleSuggester: options.cli.codexDocsTitleSuggester,\n });\n const run = await runRenameTitleAnalyzer(runtime, plans, analyzer, {\n timeoutMs: options.cli.codexDocsTimeoutMs,\n retries: options.cli.codexDocsRetries,\n batchSize: options.cli.codexDocsBatchSize,\n });\n doc = {\n summaryLabel: analyzer.summaryLabel,\n candidateCount: run.candidateCount,\n eligibleCount: run.eligibleCount,\n suggestedCount: run.suggestedCount,\n errorMessage: run.errorMessage,\n titlesByPath: run.titlesByPath,\n };\n for (const [path, reason] of run.reasonBySourcePath) {\n reasonBySourcePath.set(path, reason);\n }\n }\n\n return {\n effectiveFlags: options.effectiveFlags,\n image,\n doc,\n titlesByPath: new Map<string, string>([\n ...(image?.titlesByPath ?? []),\n ...(doc?.titlesByPath ?? []),\n ]),\n reasonBySourcePath,\n };\n}\n\nexport function printRenameBatchCodexSummary(\n runtime: CliRuntime,\n options: {\n analysis: RenameCodexAnalysisResult;\n totalCount: number;\n codexRequested: boolean;\n },\n): void {\n if (options.analysis.effectiveFlags.codexImages && options.analysis.image) {\n const image = options.analysis.image;\n printLine(\n runtime.stdout,\n `${image.summaryLabel}: ${image.suggestedCount}/${image.candidateCount} image file(s) suggested${image.errorMessage ? \" (fallback used for others)\" : \"\"}`,\n );\n if (options.totalCount > 0 && image.candidateCount === 0) {\n printLine(\n runtime.stdout,\n \"Codex note: no supported static image files in scope; other file types use deterministic rename.\",\n );\n } else if (image.candidateCount > 0 && image.eligibleCount === 0 && !image.errorMessage) {\n printLine(\n runtime.stdout,\n \"Codex note: image files were found, but none were eligible static-image inputs (see preview/CSV reasons).\",\n );\n }\n if (image.errorMessage && image.candidateCount > 0) {\n printLine(runtime.stdout, `Codex note: ${image.errorMessage}`);\n }\n }\n\n if (options.analysis.effectiveFlags.codexDocs && options.analysis.doc) {\n const doc = options.analysis.doc;\n printLine(\n runtime.stdout,\n `${doc.summaryLabel}: ${doc.suggestedCount}/${doc.candidateCount} document file(s) suggested${doc.errorMessage ? \" (fallback used for others)\" : \"\"}`,\n );\n if (options.totalCount > 0 && doc.candidateCount === 0) {\n printLine(\n runtime.stdout,\n \"Codex note: no supported document files in scope for --codex-docs; other file types use deterministic rename.\",\n );\n } else if (doc.candidateCount > 0 && doc.eligibleCount === 0 && !doc.errorMessage) {\n printLine(\n runtime.stdout,\n \"Codex note: document files were found, but none were eligible document inputs (see preview/CSV reasons).\",\n );\n }\n if (doc.errorMessage && doc.candidateCount > 0) {\n printLine(runtime.stdout, `Codex note: ${doc.errorMessage}`);\n }\n }\n\n if (\n options.codexRequested &&\n !options.analysis.effectiveFlags.codexImages &&\n !options.analysis.effectiveFlags.codexDocs\n ) {\n printLine(\n runtime.stdout,\n \"Codex note: no supported Codex analyzer inputs are in scope; deterministic rename is used.\",\n );\n }\n}\n\nexport function printRenameFileCodexSummary(\n runtime: CliRuntime,\n options: {\n analysis: RenameCodexAnalysisResult;\n sourcePath: string;\n codexRequested: boolean;\n },\n): void {\n if (options.analysis.effectiveFlags.codexImages && options.analysis.image) {\n const image = options.analysis.image;\n printLine(\n runtime.stdout,\n `${image.summaryLabel}: ${image.suggestedCount}/${image.candidateCount} image file(s) suggested${image.errorMessage ? \" (fallback used for others)\" : \"\"}`,\n );\n if (image.candidateCount === 0) {\n printLine(\n runtime.stdout,\n \"Codex note: this file is not a supported static image input; deterministic rename is used.\",\n );\n } else if (image.eligibleCount === 0 && !image.errorMessage) {\n printLine(\n runtime.stdout,\n \"Codex note: this image file is not an eligible static-image input (for example GIF, too large, or unreadable).\",\n );\n }\n if (image.errorMessage && image.candidateCount > 0) {\n printLine(runtime.stdout, `Codex note: ${image.errorMessage}`);\n }\n }\n\n if (options.analysis.effectiveFlags.codexDocs && options.analysis.doc) {\n const doc = options.analysis.doc;\n printLine(\n runtime.stdout,\n `${doc.summaryLabel}: ${doc.suggestedCount}/${doc.candidateCount} document file(s) suggested${doc.errorMessage ? \" (fallback used for others)\" : \"\"}`,\n );\n if (doc.candidateCount === 0) {\n printLine(\n runtime.stdout,\n \"Codex note: this file is not a supported document input for --codex-docs; deterministic rename is used.\",\n );\n } else if (\n options.analysis.reasonBySourcePath.get(options.sourcePath) === \"docx_experimental_disabled\"\n ) {\n printLine(\n runtime.stdout,\n \"Codex note: DOCX semantic titles are experimental and currently disabled (set CDX_CHORES_CODEX_DOCS_DOCX_EXPERIMENTAL=1 to opt in).\",\n );\n } else if (doc.eligibleCount === 0 && !doc.errorMessage) {\n printLine(\n runtime.stdout,\n \"Codex note: this document file is not an eligible document input (for example too large or unreadable).\",\n );\n }\n if (doc.errorMessage && doc.candidateCount > 0) {\n printLine(runtime.stdout, `Codex note: ${doc.errorMessage}`);\n }\n }\n\n if (\n options.codexRequested &&\n !options.analysis.effectiveFlags.codexImages &&\n !options.analysis.effectiveFlags.codexDocs\n ) {\n printLine(\n runtime.stdout,\n \"Codex note: this file is not a supported Codex analyzer input; deterministic rename is used.\",\n );\n }\n}\n","import { extname } from \"node:path\";\n\nimport { CliError } from \"../../errors\";\n\nexport interface RenameBatchFilterOptions {\n profile?: string;\n recursive?: boolean;\n maxDepth?: number;\n matchRegex?: string;\n skipRegex?: string;\n ext?: string[];\n skipExt?: string[];\n}\n\nconst DEFAULT_RENAME_BATCH_EXCLUDED_BASENAMES = new Set([\".DS_Store\", \"Thumbs.db\", \"desktop.ini\"]);\n\nconst RENAME_BATCH_PROFILE_EXTENSIONS = {\n images: [\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".webp\",\n \".gif\",\n \".bmp\",\n \".tif\",\n \".tiff\",\n \".avif\",\n \".heic\",\n \".heif\",\n \".svg\",\n ],\n media: [\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".webp\",\n \".gif\",\n \".bmp\",\n \".tif\",\n \".tiff\",\n \".avif\",\n \".heic\",\n \".heif\",\n \".svg\",\n \".mp4\",\n \".mov\",\n \".m4v\",\n \".mkv\",\n \".avi\",\n \".webm\",\n \".mp3\",\n \".wav\",\n \".m4a\",\n \".aac\",\n \".flac\",\n \".ogg\",\n \".opus\",\n ],\n docs: [\n \".txt\",\n \".md\",\n \".markdown\",\n \".pdf\",\n \".doc\",\n \".docx\",\n \".rtf\",\n \".odt\",\n \".csv\",\n \".tsv\",\n \".json\",\n \".yaml\",\n \".yml\",\n \".toml\",\n \".xml\",\n \".html\",\n \".htm\",\n ],\n} as const;\n\ntype RenameBatchProfileName = keyof typeof RENAME_BATCH_PROFILE_EXTENSIONS;\n\nfunction isDefaultRenameBatchExcludedEntryName(entryName: string): boolean {\n if (entryName.startsWith(\".\")) {\n return true;\n }\n\n if (entryName.startsWith(\"._\")) {\n return true;\n }\n\n return DEFAULT_RENAME_BATCH_EXCLUDED_BASENAMES.has(entryName);\n}\n\nfunction compileOptionalRegex(\n value: string | undefined,\n label: \"--match-regex\" | \"--skip-regex\",\n): RegExp | undefined {\n const pattern = value?.trim();\n if (!pattern) {\n return undefined;\n }\n\n try {\n return new RegExp(pattern);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new CliError(`Invalid ${label}: ${message}`, { code: \"INVALID_INPUT\", exitCode: 2 });\n }\n}\n\nfunction normalizeExtensions(values: string[] | undefined): Set<string> | undefined {\n if (!values || values.length === 0) {\n return undefined;\n }\n\n const normalized = values\n .map((value) => value.trim().toLowerCase())\n .filter((value) => value.length > 0)\n .map((value) => (value.startsWith(\".\") ? value : `.${value}`));\n\n if (normalized.length === 0) {\n return undefined;\n }\n\n return new Set(normalized);\n}\n\nfunction normalizeRenameBatchProfile(profile: string | undefined): Set<string> | undefined {\n const raw = profile?.trim().toLowerCase();\n if (!raw || raw === \"all\") {\n return undefined;\n }\n\n const values = RENAME_BATCH_PROFILE_EXTENSIONS[raw as RenameBatchProfileName];\n if (!values) {\n throw new CliError(\n `Invalid --profile value: ${profile}. Expected one of: all, images, media, docs`,\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n }\n\n return new Set(values);\n}\n\nexport function normalizeRenameBatchMaxDepth(\n options: Pick<RenameBatchFilterOptions, \"maxDepth\" | \"recursive\">,\n): number | undefined {\n const value = options.maxDepth;\n if (value === undefined) {\n return undefined;\n }\n\n if (!(options.recursive ?? false)) {\n throw new CliError(\"--max-depth requires --recursive.\", { code: \"INVALID_INPUT\", exitCode: 2 });\n }\n\n if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {\n throw new CliError(\"--max-depth must be a non-negative integer.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n return value;\n}\n\nexport function createRenameBatchFileFilter(\n options: Pick<\n RenameBatchFilterOptions,\n \"profile\" | \"matchRegex\" | \"skipRegex\" | \"ext\" | \"skipExt\"\n >,\n): (entryName: string) => boolean {\n const matchRegex = compileOptionalRegex(options.matchRegex, \"--match-regex\");\n const skipRegex = compileOptionalRegex(options.skipRegex, \"--skip-regex\");\n const profileExts = normalizeRenameBatchProfile(options.profile);\n const includeExts = normalizeExtensions(options.ext);\n const excludeExts = normalizeExtensions(options.skipExt);\n const effectiveIncludeExts =\n profileExts || includeExts\n ? new Set<string>([...(profileExts ?? []), ...(includeExts ?? [])])\n : undefined;\n\n return (entryName: string) => {\n if (isDefaultRenameBatchExcludedEntryName(entryName)) {\n return false;\n }\n\n if (matchRegex && !matchRegex.test(entryName)) {\n return false;\n }\n\n if (skipRegex && skipRegex.test(entryName)) {\n return false;\n }\n\n const ext = extname(entryName).toLowerCase();\n if (effectiveIncludeExts && !effectiveIncludeExts.has(ext)) {\n return false;\n }\n\n if (excludeExts?.has(ext)) {\n return false;\n }\n\n return true;\n };\n}\n","import { basename, extname } from \"node:path\";\n\nimport { slugifyName } from \"../../../utils/slug\";\nimport {\n createRenamePlanCsvRows,\n writeRenamePlanCsv,\n} from \"../../rename-plan-csv\";\nimport {\n rewriteTimestampPlaceholder,\n templateContainsLegacyTimestamp,\n type TimestampTimezone,\n} from \"../../rename-template\";\nimport type { CliRuntime, PlannedRename } from \"../../types\";\n\ntype RenameSkippedItem = {\n path: string;\n reason: string;\n};\n\nexport function resolveEffectivePattern(\n pattern: string | undefined,\n timestampTimezone: TimestampTimezone | undefined,\n): string | undefined {\n if (timestampTimezone === undefined) {\n return pattern;\n }\n if (pattern !== undefined && !templateContainsLegacyTimestamp(pattern)) {\n return pattern;\n }\n const target = pattern ?? \"{prefix}-{timestamp}-{stem}\";\n return rewriteTimestampPlaceholder(target, timestampTimezone);\n}\n\nexport function deriveTimestampTzMetadata(pattern: string | undefined): string {\n const p = pattern ?? \"{prefix}-{timestamp}-{stem}\";\n const hasLocal = /\\{\\s*timestamp_local(?:_(?:iso|12h))?\\s*\\}/.test(p);\n const hasUtc = /\\{\\s*(?:timestamp|timestamp_utc(?:_(?:iso|12h))?)\\s*\\}/.test(p);\n if (hasLocal && hasUtc) return \"\";\n if (hasLocal) return \"local\";\n if (hasUtc) return \"utc\";\n return \"\";\n}\n\nexport async function writeBatchRenameDryRunPlanCsv(\n runtime: CliRuntime,\n options: {\n plans: PlannedRename[];\n skippedItems: RenameSkippedItem[];\n codexTitlesByPath?: Map<string, string>;\n reasonBySourcePath: Map<string, string>;\n effectivePattern: string | undefined;\n },\n): Promise<string> {\n const cleanedStemBySourcePath = new Map<string, string>();\n for (const plan of options.plans) {\n const ext = extname(plan.fromPath);\n const stem = basename(plan.fromPath, ext);\n const sourceTitle = options.codexTitlesByPath?.get(plan.fromPath) ?? stem;\n cleanedStemBySourcePath.set(plan.fromPath, slugifyName(sourceTitle).slice(0, 48));\n }\n\n const { rows } = createRenamePlanCsvRows({\n runtime,\n plans: options.plans,\n cleanedStemBySourcePath,\n aiNameBySourcePath: options.codexTitlesByPath,\n reasonBySourcePath: options.reasonBySourcePath,\n skippedItems: options.skippedItems,\n aiProvider: \"codex\",\n aiModel: \"auto\",\n timestampTz: deriveTimestampTzMetadata(options.effectivePattern),\n });\n\n return writeRenamePlanCsv(runtime, rows);\n}\n\nexport async function writeSingleRenameDryRunPlanCsv(\n runtime: CliRuntime,\n options: {\n plan: PlannedRename;\n codexTitlesByPath: Map<string, string>;\n reasonBySourcePath: Map<string, string>;\n effectivePattern: string | undefined;\n },\n): Promise<string> {\n const ext = extname(options.plan.fromPath);\n const stem = basename(options.plan.fromPath, ext);\n const sourceTitle = options.codexTitlesByPath.get(options.plan.fromPath) ?? stem;\n const cleanedStemBySourcePath = new Map<string, string>([\n [options.plan.fromPath, slugifyName(sourceTitle).slice(0, 48)],\n ]);\n const { rows } = createRenamePlanCsvRows({\n runtime,\n plans: [options.plan],\n cleanedStemBySourcePath,\n aiNameBySourcePath: options.codexTitlesByPath.size > 0 ? options.codexTitlesByPath : undefined,\n reasonBySourcePath: options.reasonBySourcePath,\n aiProvider: \"codex\",\n aiModel: \"auto\",\n timestampTz: deriveTimestampTzMetadata(options.effectivePattern),\n });\n\n return writeRenamePlanCsv(runtime, rows);\n}\n","import { CliError } from \"../../errors\";\nimport { resolveAutoCodexFlagsForPaths, resolveCodexFlagsFromCliOptions } from \"../../rename-interactive-router\";\nimport {\n type RenameSerialOrder,\n type RenameSerialScope,\n type TimestampTimezone,\n} from \"../../rename-template\";\nimport { applyPlannedRenames, planBatchRename } from \"../../fs-utils\";\nimport type { CliRuntime } from \"../../types\";\nimport {\n type CodexDocumentRenameTitleSuggester,\n type CodexImageRenameTitleSuggester,\n printRenameBatchCodexSummary,\n runRenameCodexAnalysis,\n} from \"./codex\";\nimport {\n createRenameBatchFileFilter,\n normalizeRenameBatchMaxDepth,\n} from \"./filters\";\nimport {\n resolveEffectivePattern,\n writeBatchRenameDryRunPlanCsv,\n} from \"./plan-output\";\nimport {\n printRenameBatchApplyFooter,\n printRenameBatchDryRunFooter,\n printRenameBatchPreview,\n} from \"./reporting\";\nimport { assertNonEmpty, displayPath, printLine } from \"../shared\";\n\nexport interface RenameBatchOptions {\n directory: string;\n prefix?: string;\n pattern?: string;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope?: RenameSerialScope;\n timestampTimezone?: TimestampTimezone;\n profile?: string;\n dryRun?: boolean;\n previewSkips?: \"summary\" | \"detailed\";\n recursive?: boolean;\n maxDepth?: number;\n matchRegex?: string;\n skipRegex?: string;\n ext?: string[];\n skipExt?: string[];\n codex?: boolean;\n codexImages?: boolean;\n codexImagesTimeoutMs?: number;\n codexImagesRetries?: number;\n codexImagesBatchSize?: number;\n codexImagesTitleSuggester?: CodexImageRenameTitleSuggester;\n codexDocs?: boolean;\n codexDocsTimeoutMs?: number;\n codexDocsRetries?: number;\n codexDocsBatchSize?: number;\n codexDocsTitleSuggester?: CodexDocumentRenameTitleSuggester;\n}\n\nfunction normalizeRenamePreviewSkipsMode(\n mode: RenameBatchOptions[\"previewSkips\"],\n): \"summary\" | \"detailed\" {\n if (mode === undefined || mode === \"summary\") {\n return \"summary\";\n }\n if (mode === \"detailed\") {\n return \"detailed\";\n }\n throw new CliError(`Invalid --preview-skips value: ${mode}. Expected one of: summary, detailed`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n\nexport async function actionRenameBatch(\n runtime: CliRuntime,\n options: RenameBatchOptions,\n): Promise<{\n changedCount: number;\n totalCount: number;\n directoryPath: string;\n planCsvPath?: string;\n}> {\n const directory = assertNonEmpty(options.directory, \"Directory path\");\n const previewSkips = normalizeRenamePreviewSkipsMode(options.previewSkips);\n const maxDepth = normalizeRenameBatchMaxDepth(options);\n const fileFilter = createRenameBatchFileFilter(options);\n const effectivePattern = resolveEffectivePattern(options.pattern, options.timestampTimezone);\n const initial = await planBatchRename(runtime, directory, {\n prefix: options.prefix,\n pattern: effectivePattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n now: runtime.now(),\n fileFilter,\n recursive: options.recursive,\n maxDepth,\n });\n const directoryPath = initial.directoryPath;\n const skipped = initial.skipped;\n const effectiveCodexFlags = resolveCodexFlagsFromCliOptions({\n cli: {\n codex: options.codex,\n codexImages: options.codexImages,\n codexDocs: options.codexDocs,\n },\n fallbackAuto: resolveAutoCodexFlagsForPaths(initial.plans.map((plan) => plan.fromPath)),\n });\n const codexAnalysis = await runRenameCodexAnalysis(runtime, initial.plans, {\n effectiveFlags: effectiveCodexFlags,\n cli: {\n codex: options.codex,\n codexImages: options.codexImages,\n codexImagesTimeoutMs: options.codexImagesTimeoutMs,\n codexImagesRetries: options.codexImagesRetries,\n codexImagesBatchSize: options.codexImagesBatchSize,\n codexImagesTitleSuggester: options.codexImagesTitleSuggester,\n codexDocs: options.codexDocs,\n codexDocsTimeoutMs: options.codexDocsTimeoutMs,\n codexDocsRetries: options.codexDocsRetries,\n codexDocsBatchSize: options.codexDocsBatchSize,\n codexDocsTitleSuggester: options.codexDocsTitleSuggester,\n },\n });\n const titleOverrides =\n codexAnalysis.titlesByPath.size > 0 ? new Map(codexAnalysis.titlesByPath) : undefined;\n const codexTitlesByPath =\n codexAnalysis.titlesByPath.size > 0 ? new Map(codexAnalysis.titlesByPath) : undefined;\n\n const { plans } = titleOverrides\n ? await planBatchRename(runtime, directory, {\n prefix: options.prefix,\n pattern: effectivePattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n now: runtime.now(),\n titleOverrides,\n fileFilter,\n recursive: options.recursive,\n maxDepth,\n })\n : initial;\n\n const totalCount = plans.length;\n const changedCount = plans.filter((plan) => plan.changed).length;\n let planCsvPath: string | undefined;\n\n printLine(runtime.stdout, `Directory: ${displayPath(runtime, directoryPath)}`);\n printLine(runtime.stdout, `Files found: ${totalCount}`);\n printLine(runtime.stdout, `Files to rename: ${changedCount}`);\n if (skipped.length > 0) {\n printLine(runtime.stdout, `Entries skipped: ${skipped.length}`);\n }\n printRenameBatchCodexSummary(runtime, {\n analysis: codexAnalysis,\n totalCount,\n codexRequested: options.codex ?? false,\n });\n printLine(runtime.stdout);\n\n const { truncated } = printRenameBatchPreview(runtime, {\n plans,\n skipped,\n previewSkips,\n dryRun: options.dryRun ?? false,\n });\n\n if (options.dryRun ?? false) {\n planCsvPath = await writeBatchRenameDryRunPlanCsv(runtime, {\n plans,\n skippedItems: skipped,\n codexTitlesByPath,\n reasonBySourcePath: codexAnalysis.reasonBySourcePath,\n effectivePattern,\n });\n\n printRenameBatchDryRunFooter(runtime, {\n planCsvPath,\n truncated,\n });\n return { changedCount, totalCount, directoryPath, planCsvPath };\n }\n\n await applyPlannedRenames(plans);\n printRenameBatchApplyFooter(runtime, changedCount);\n\n return { changedCount, totalCount, directoryPath };\n}\n","import { slugifyName } from \"../../../utils/slug\";\n\nexport const CLEANUP_HINT_VALUES = [\"date\", \"timestamp\", \"serial\", \"uid\"] as const;\nexport type CleanupHint = (typeof CLEANUP_HINT_VALUES)[number];\nexport type CleanupTextStyle = \"preserve\" | \"slug\";\nexport type CleanupTimestampAction = \"keep\" | \"remove\";\n\ninterface CleanupTimestampMatch {\n prefix: string;\n suffix: string;\n normalizedTimestamp: string;\n}\n\ninterface CleanupDateMatch {\n prefix: string;\n suffix: string;\n normalizedDate: string;\n}\n\ninterface CleanupSerialMatch {\n prefix: string;\n}\n\ninterface CleanupUidMatch {\n prefix: string;\n suffix: string;\n}\n\nconst MACOS_TIMESTAMP_PATTERN =\n /\\b(\\d{4})-(\\d{2})-(\\d{2}) at (\\d{1,2})\\.(\\d{2})\\.(\\d{2}) (AM|PM)\\b/i;\nconst MACOS_TIMESTAMP_PATTERN_GLOBAL =\n /\\b(\\d{4})-(\\d{2})-(\\d{2}) at (\\d{1,2})\\.(\\d{2})\\.(\\d{2}) (AM|PM)\\b/gi;\nconst DATE_PATTERN_GLOBAL = /\\b(\\d{4})-(\\d{2})-(\\d{2})\\b/g;\n\nfunction normalizePreserveStem(value: string): string {\n const normalized = value\n .replace(/\\s+/g, \" \")\n .replace(/^[\\s._-]+|[\\s._-]+$/g, \"\")\n .trim();\n return normalized || \"file\";\n}\n\nfunction trimCleanupFragmentEdges(value: string): string {\n return value.replace(/^[\\s._-]+|[\\s._-]+$/g, \"\").trim();\n}\n\nfunction formatCleanupTimestamp(\n year: string,\n month: string,\n day: string,\n hourText: string,\n minute: string,\n second: string,\n meridiem: string,\n): string {\n const hour12 = Number(hourText);\n const normalizedMeridiem = meridiem.toUpperCase();\n const hour24 = normalizedMeridiem === \"PM\" ? (hour12 % 12) + 12 : hour12 % 12;\n return `${year}${month}${day}-${String(hour24).padStart(2, \"0\")}${minute}${second}`;\n}\n\nfunction buildNoMatchReason(hints: CleanupHint[]): string {\n if (hints.length === 0) {\n return \"no supported hint match\";\n }\n if (hints.length === 1) {\n return `no ${hints[0]} match`;\n }\n if (hints.length === 2 && hints.includes(\"timestamp\") && hints.includes(\"date\")) {\n return \"no date or timestamp match\";\n }\n return \"no selected hint match\";\n}\n\nfunction buildTextStyleStem(value: string, style: CleanupTextStyle): string {\n return style === \"slug\" ? slugifyName(value) : normalizePreserveStem(value);\n}\n\nfunction normalizeIntermediateCleanupStem(value: string): string {\n return normalizePreserveStem(value);\n}\n\nfunction findTimestampRanges(stem: string): Array<{ start: number; end: number }> {\n return [...stem.matchAll(MACOS_TIMESTAMP_PATTERN_GLOBAL)]\n .map((match) => {\n if (match.index === undefined) {\n return undefined;\n }\n return {\n start: match.index,\n end: match.index + match[0].length,\n };\n })\n .filter((range): range is { start: number; end: number } => range !== undefined);\n}\n\nexport function matchCleanupTimestamp(stem: string): CleanupTimestampMatch | undefined {\n const match = MACOS_TIMESTAMP_PATTERN.exec(stem);\n if (!match || match.index === undefined) {\n return undefined;\n }\n const [, year, month, day, hour, minute, second, meridiem] = match;\n if (!year || !month || !day || !hour || !minute || !second || !meridiem) {\n return undefined;\n }\n\n return {\n prefix: trimCleanupFragmentEdges(stem.slice(0, match.index)),\n suffix: trimCleanupFragmentEdges(stem.slice(match.index + match[0].length)),\n normalizedTimestamp: formatCleanupTimestamp(year, month, day, hour, minute, second, meridiem),\n };\n}\n\nexport function matchCleanupDate(stem: string): CleanupDateMatch | undefined {\n const timestampRanges = findTimestampRanges(stem);\n\n for (const match of stem.matchAll(DATE_PATTERN_GLOBAL)) {\n if (match.index === undefined) {\n continue;\n }\n const [fullText, year, month, day] = match;\n if (!fullText || !year || !month || !day) {\n continue;\n }\n\n const start = match.index;\n const end = start + fullText.length;\n const overlapsTimestamp = timestampRanges.some(\n (range) => start >= range.start && end <= range.end,\n );\n if (overlapsTimestamp) {\n continue;\n }\n\n return {\n prefix: trimCleanupFragmentEdges(stem.slice(0, start)),\n suffix: trimCleanupFragmentEdges(stem.slice(end)),\n normalizedDate: `${year}${month}${day}`,\n };\n }\n\n return undefined;\n}\n\nexport function matchCleanupSerial(stem: string): CleanupSerialMatch | undefined {\n const parenthesizedMatch = /^(.*?)(?:[\\s._-]*)\\((\\d{1,})\\)$/.exec(stem);\n if (parenthesizedMatch) {\n const [, rawPrefix, serial] = parenthesizedMatch;\n const prefix = trimCleanupFragmentEdges(rawPrefix ?? \"\");\n if (serial && prefix) {\n return { prefix };\n }\n }\n\n const separatedMatch = /^(.*?)(?:[\\s_-]+)(0\\d+)$/.exec(stem);\n if (!separatedMatch) {\n return undefined;\n }\n\n const [, rawPrefix, serial] = separatedMatch;\n const prefix = trimCleanupFragmentEdges(rawPrefix ?? \"\");\n if (!prefix || !serial) {\n return undefined;\n }\n\n if (/\\d$/.test(prefix)) {\n return undefined;\n }\n\n if (/^(img|dsc)$/i.test(prefix)) {\n return undefined;\n }\n\n return { prefix };\n}\n\nexport function matchCleanupUid(stem: string): CleanupUidMatch | undefined {\n const match = /(^|[\\s._-]+)(uid-[0-9a-hjkmnpqrstvwxyz]{10,16})(?=$|[\\s._-]+)(.*)$/i.exec(stem);\n if (!match || match.index === undefined) {\n return undefined;\n }\n\n return {\n prefix: trimCleanupFragmentEdges(stem.slice(0, match.index)),\n suffix: trimCleanupFragmentEdges(match[3] ?? \"\"),\n };\n}\n\nfunction buildTimestampCleanupStem(\n stem: string,\n _style: CleanupTextStyle,\n timestampAction: CleanupTimestampAction,\n): { nextStem: string; reason?: string } {\n const match = matchCleanupTimestamp(stem);\n if (!match) {\n return { nextStem: stem, reason: \"no timestamp match\" };\n }\n\n const parts = [match.prefix];\n if (timestampAction === \"keep\") {\n parts.push(match.normalizedTimestamp);\n }\n parts.push(match.suffix);\n return {\n nextStem: normalizeIntermediateCleanupStem(\n parts.filter((part) => part.length > 0).join(\" \"),\n ),\n };\n}\n\nfunction buildDateCleanupStem(\n stem: string,\n _style: CleanupTextStyle,\n): { nextStem: string; reason?: string } {\n const match = matchCleanupDate(stem);\n if (!match) {\n return { nextStem: stem, reason: \"no date match\" };\n }\n\n return {\n nextStem: normalizeIntermediateCleanupStem(\n [match.prefix, match.normalizedDate, match.suffix]\n .filter((part) => part.length > 0)\n .join(\" \"),\n ),\n };\n}\n\nfunction buildSerialCleanupStem(\n stem: string,\n _style: CleanupTextStyle,\n): { nextStem: string; reason?: string } {\n const match = matchCleanupSerial(stem);\n if (!match) {\n return { nextStem: stem, reason: \"no serial match\" };\n }\n\n return {\n nextStem: normalizeIntermediateCleanupStem(match.prefix),\n };\n}\n\nfunction buildUidCleanupStem(\n stem: string,\n _style: CleanupTextStyle,\n): { nextStem: string; reason?: string } {\n const match = matchCleanupUid(stem);\n if (!match) {\n return { nextStem: stem, reason: \"no uid match\" };\n }\n\n return {\n nextStem: normalizeIntermediateCleanupStem(\n [match.prefix, match.suffix].filter((part) => part.length > 0).join(\" \"),\n ),\n };\n}\n\nexport function buildTemporalCleanupStem(\n stem: string,\n hints: CleanupHint[],\n style: CleanupTextStyle,\n timestampAction: CleanupTimestampAction,\n): { nextStem: string; reason?: string } {\n let nextStem = stem;\n let matchedAny = false;\n\n const orderedHints: CleanupHint[] = [\"timestamp\", \"date\", \"serial\", \"uid\"];\n for (const hint of orderedHints) {\n if (!hints.includes(hint)) {\n continue;\n }\n\n const result =\n hint === \"timestamp\"\n ? buildTimestampCleanupStem(nextStem, style, timestampAction)\n : hint === \"date\"\n ? buildDateCleanupStem(nextStem, style)\n : hint === \"serial\"\n ? buildSerialCleanupStem(nextStem, style)\n : buildUidCleanupStem(nextStem, style);\n\n if (!result.reason) {\n nextStem = result.nextStem;\n matchedAny = true;\n }\n }\n\n if (matchedAny) {\n return { nextStem: buildTextStyleStem(nextStem, style) };\n }\n\n return { nextStem: stem, reason: buildNoMatchReason(hints) };\n}\n","import { readdir } from \"node:fs/promises\";\nimport { basename, extname, join } from \"node:path\";\n\nimport { createRenamePlanCsvRows } from \"../../rename-plan-csv\";\nimport type { CliRuntime, PlannedRename, SkippedRenameItem } from \"../../types\";\nimport { createRenameBatchFileFilter } from \"./filters\";\nimport { buildTemporalCleanupStem } from \"./cleanup-matchers\";\nimport { buildCleanupUidBasenames } from \"./cleanup-uid\";\nimport type {\n RenameCleanupConflictStrategy,\n RenameCleanupHint,\n RenameCleanupOptions,\n RenameCleanupStyle,\n RenameCleanupTimestampAction,\n} from \"./cleanup-contract\";\n\ninterface CleanupCandidate {\n sourcePath: string;\n directoryPath: string;\n currentName: string;\n stem: string;\n ext: string;\n}\n\nconst RENAME_PLAN_CSV_ARTIFACT_PATTERN = /^rename-plan-\\d{8}T\\d{6}Z-[a-f0-9]{8}\\.csv$/;\n\nfunction buildCleanupNumberConflictBasename(preferredBaseName: string, index: number): string {\n return index <= 0 ? preferredBaseName : `${preferredBaseName}-${index}`;\n}\n\nasync function buildCleanupUidConflictBasenames(\n sourcePath: string,\n preferredBaseName: string,\n): Promise<string[]> {\n const uidBasenames = await buildCleanupUidBasenames(sourcePath);\n return uidBasenames.map((uidBasename) => `${preferredBaseName}-${uidBasename}`);\n}\n\nexport async function resolveCleanupConflictBasename(\n options: {\n sourcePath: string;\n preferredBaseName: string;\n conflictStrategy: RenameCleanupConflictStrategy;\n },\n isAvailable: (baseName: string) => boolean,\n): Promise<string | undefined> {\n if (isAvailable(options.preferredBaseName)) {\n return options.preferredBaseName;\n }\n\n if (options.conflictStrategy === \"skip\") {\n return undefined;\n }\n\n if (options.conflictStrategy === \"number\") {\n for (let index = 1; index <= 10000; index += 1) {\n const nextBaseName = buildCleanupNumberConflictBasename(options.preferredBaseName, index);\n if (isAvailable(nextBaseName)) {\n return nextBaseName;\n }\n }\n return undefined;\n }\n\n const uidConflictBasenames = await buildCleanupUidConflictBasenames(\n options.sourcePath,\n options.preferredBaseName,\n );\n for (const nextBaseName of uidConflictBasenames) {\n if (isAvailable(nextBaseName)) {\n return nextBaseName;\n }\n }\n\n return undefined;\n}\n\nexport async function buildCleanupBasenameCandidates(\n sourcePath: string,\n stem: string,\n hints: RenameCleanupHint[],\n style: RenameCleanupStyle,\n timestampAction: RenameCleanupTimestampAction,\n): Promise<{ baseNames: string[]; reason?: string }> {\n const result = buildTemporalCleanupStem(stem, hints, style, timestampAction);\n if (result.reason) {\n return { baseNames: [stem], reason: result.reason };\n }\n\n return { baseNames: [result.nextStem] };\n}\n\nexport function buildCleanupSinglePlanCsvRows(\n runtime: CliRuntime,\n plan: PlannedRename,\n reason: string | undefined,\n): ReturnType<typeof createRenamePlanCsvRows>[\"rows\"] {\n const cleanedStemBySourcePath = new Map<string, string>([\n [plan.fromPath, basename(plan.toPath, extname(plan.toPath))],\n ]);\n const reasonBySourcePath = reason\n ? new Map<string, string>([[plan.fromPath, reason]])\n : new Map<string, string>();\n return createRenamePlanCsvRows({\n runtime,\n plans: [plan],\n cleanedStemBySourcePath,\n reasonBySourcePath,\n }).rows;\n}\n\nexport function buildCleanupBatchPlanCsvRows(\n runtime: CliRuntime,\n plans: PlannedRename[],\n skippedItems: SkippedRenameItem[],\n): ReturnType<typeof createRenamePlanCsvRows>[\"rows\"] {\n const cleanedStemBySourcePath = new Map<string, string>();\n for (const plan of plans) {\n cleanedStemBySourcePath.set(plan.fromPath, basename(plan.toPath, extname(plan.toPath)));\n }\n\n return createRenamePlanCsvRows({\n runtime,\n plans,\n skippedItems,\n cleanedStemBySourcePath,\n }).rows;\n}\n\nfunction isRenamePlanCsvArtifactName(entryName: string): boolean {\n return RENAME_PLAN_CSV_ARTIFACT_PATTERN.test(entryName);\n}\n\nexport async function collectDirectoryCleanupCandidates(\n directoryPath: string,\n options: Pick<\n RenameCleanupOptions,\n \"recursive\" | \"maxDepth\" | \"matchRegex\" | \"skipRegex\" | \"ext\" | \"skipExt\"\n >,\n): Promise<{\n candidates: CleanupCandidate[];\n skipped: SkippedRenameItem[];\n occupiedFilePaths: Set<string>;\n}> {\n const skipped: SkippedRenameItem[] = [];\n const candidates: CleanupCandidate[] = [];\n const occupiedFilePaths = new Set<string>();\n const recursive = options.recursive ?? false;\n const maxDepth = recursive ? (options.maxDepth ?? Number.POSITIVE_INFINITY) : 0;\n const fileFilter = createRenameBatchFileFilter({\n matchRegex: options.matchRegex,\n skipRegex: options.skipRegex,\n ext: options.ext,\n skipExt: options.skipExt,\n });\n\n const visitDirectory = async (currentDirectoryPath: string, depth: number): Promise<void> => {\n const entries = await readdir(currentDirectoryPath, { withFileTypes: true });\n const sortedEntries = [...entries].sort((left, right) => left.name.localeCompare(right.name));\n\n for (const entry of sortedEntries) {\n const entryPath = join(currentDirectoryPath, entry.name);\n\n if (entry.isSymbolicLink()) {\n skipped.push({ path: entryPath, reason: \"symlink\" });\n continue;\n }\n\n if (entry.isDirectory()) {\n if (recursive && depth < maxDepth) {\n await visitDirectory(entryPath, depth + 1);\n }\n continue;\n }\n\n if (!entry.isFile()) {\n continue;\n }\n\n occupiedFilePaths.add(entryPath);\n if (isRenamePlanCsvArtifactName(entry.name)) {\n continue;\n }\n if (!fileFilter(entry.name)) {\n continue;\n }\n\n const ext = extname(entry.name);\n candidates.push({\n sourcePath: entryPath,\n directoryPath: currentDirectoryPath,\n currentName: entry.name,\n stem: basename(entry.name, ext),\n ext,\n });\n }\n };\n\n await visitDirectory(directoryPath, 0);\n return { candidates, skipped, occupiedFilePaths };\n}\n\nexport async function buildDirectoryCleanupPlans(\n candidates: CleanupCandidate[],\n occupiedFilePaths: Set<string>,\n options: {\n hints: RenameCleanupHint[];\n style: RenameCleanupStyle;\n timestampAction: RenameCleanupTimestampAction;\n conflictStrategy: RenameCleanupConflictStrategy;\n },\n): Promise<{ plans: PlannedRename[]; skipped: SkippedRenameItem[] }> {\n const plans: PlannedRename[] = [];\n const skipped: SkippedRenameItem[] = [];\n const sourcePaths = new Set(candidates.map((candidate) => candidate.sourcePath));\n const tentativeBySourcePath = new Map<string, { targetPath: string; reason?: string }>();\n const unchangedTargetPaths = new Set<string>();\n const targetCounts = new Map<string, number>();\n\n for (const candidate of candidates) {\n const result = await buildCleanupBasenameCandidates(\n candidate.sourcePath,\n candidate.stem,\n options.hints,\n options.style,\n options.timestampAction,\n );\n if (result.reason) {\n tentativeBySourcePath.set(candidate.sourcePath, {\n targetPath: candidate.sourcePath,\n reason: result.reason,\n });\n unchangedTargetPaths.add(candidate.sourcePath);\n continue;\n }\n\n const preferredBaseName = result.baseNames[0] ?? candidate.stem;\n const resolvedBaseName = await resolveCleanupConflictBasename(\n {\n sourcePath: candidate.sourcePath,\n preferredBaseName,\n conflictStrategy: options.conflictStrategy,\n },\n (baseName) => {\n const candidatePath = join(candidate.directoryPath, `${baseName}${candidate.ext}`);\n const hasPlannedConflict = (targetCounts.get(candidatePath) ?? 0) > 0;\n const hasUnchangedConflict = unchangedTargetPaths.has(candidatePath);\n const hasExistingConflict =\n occupiedFilePaths.has(candidatePath) && !sourcePaths.has(candidatePath);\n return !hasPlannedConflict && !hasUnchangedConflict && !hasExistingConflict;\n },\n );\n const resolvedTargetPath = resolvedBaseName\n ? join(candidate.directoryPath, `${resolvedBaseName}${candidate.ext}`)\n : \"\";\n\n if (!resolvedTargetPath) {\n tentativeBySourcePath.set(candidate.sourcePath, {\n targetPath: candidate.sourcePath,\n reason: \"target conflict\",\n });\n unchangedTargetPaths.add(candidate.sourcePath);\n continue;\n }\n\n tentativeBySourcePath.set(candidate.sourcePath, { targetPath: resolvedTargetPath });\n targetCounts.set(resolvedTargetPath, (targetCounts.get(resolvedTargetPath) ?? 0) + 1);\n if (resolvedTargetPath === candidate.sourcePath) {\n unchangedTargetPaths.add(resolvedTargetPath);\n }\n }\n\n for (const candidate of candidates) {\n const tentative = tentativeBySourcePath.get(candidate.sourcePath)!;\n const targetPath = tentative.targetPath;\n\n if (tentative.reason) {\n skipped.push({ path: candidate.sourcePath, reason: tentative.reason });\n continue;\n }\n\n if (targetPath === candidate.sourcePath) {\n skipped.push({ path: candidate.sourcePath, reason: \"unchanged\" });\n continue;\n }\n\n if (targetCounts.get(targetPath)! > 1) {\n skipped.push({ path: candidate.sourcePath, reason: \"target conflict\" });\n continue;\n }\n\n if (unchangedTargetPaths.has(targetPath)) {\n skipped.push({ path: candidate.sourcePath, reason: \"target conflict\" });\n continue;\n }\n\n if (occupiedFilePaths.has(targetPath) && !sourcePaths.has(targetPath)) {\n skipped.push({ path: candidate.sourcePath, reason: \"target conflict\" });\n continue;\n }\n\n plans.push({\n fromPath: candidate.sourcePath,\n toPath: targetPath,\n changed: true,\n });\n }\n\n return { plans, skipped };\n}\n","import { lstat } from \"node:fs/promises\";\n\nimport { resolveFromCwd } from \"../../fs-utils\";\nimport { CliError } from \"../../errors\";\nimport type { CliRuntime } from \"../../types\";\n\nexport type RenameCleanupPathKind = \"file\" | \"directory\";\n\nexport interface RenameCleanupPathTarget {\n kind: RenameCleanupPathKind;\n path: string;\n}\n\nexport async function resolveRenameCleanupTarget(\n runtime: CliRuntime,\n inputPath: string,\n): Promise<RenameCleanupPathTarget> {\n const resolvedPath = resolveFromCwd(runtime, inputPath);\n\n let pathStats;\n try {\n pathStats = await lstat(resolvedPath);\n } catch {\n throw new CliError(`Cleanup path not found: ${resolvedPath}`, {\n code: \"FILE_NOT_FOUND\",\n exitCode: 2,\n });\n }\n\n if (pathStats.isSymbolicLink()) {\n throw new CliError(`Symlink inputs are not supported for rename cleanup: ${resolvedPath}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n if (pathStats.isFile()) {\n return { kind: \"file\", path: resolvedPath };\n }\n if (pathStats.isDirectory()) {\n return { kind: \"directory\", path: resolvedPath };\n }\n\n throw new CliError(`Cleanup path must be a file or directory: ${resolvedPath}`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n","import { readdir } from \"node:fs/promises\";\nimport { basename, dirname, extname, join } from \"node:path\";\n\nimport { writeRenamePlanCsv } from \"../../rename-plan-csv\";\nimport { applyPlannedRenames } from \"../../fs-utils\";\nimport type { CliRuntime, PlannedRename } from \"../../types\";\nimport { CliError } from \"../../errors\";\nimport { assertNonEmpty, displayPath, printLine } from \"../shared\";\nimport {\n printRenameBatchApplyFooter,\n printRenameBatchDryRunFooter,\n printRenameBatchPreview,\n printRenameFileApplyFooter,\n printRenameFileDryRunFooter,\n printRenameFilePreview,\n} from \"./reporting\";\nimport { CLEANUP_HINT_VALUES } from \"./cleanup-matchers\";\nimport type {\n RenameCleanupConflictStrategy,\n RenameCleanupHint,\n RenameCleanupOptions,\n RenameCleanupResult,\n RenameCleanupStyle,\n RenameCleanupTimestampAction,\n} from \"./cleanup-contract\";\nimport {\n buildCleanupBasenameCandidates,\n buildCleanupBatchPlanCsvRows,\n buildCleanupSinglePlanCsvRows,\n buildDirectoryCleanupPlans,\n collectDirectoryCleanupCandidates,\n resolveCleanupConflictBasename,\n} from \"./cleanup-planner\";\nimport { type RenameCleanupPathKind, resolveRenameCleanupTarget } from \"./cleanup-target\";\n\nexport type {\n RenameCleanupConflictStrategy,\n RenameCleanupHint,\n RenameCleanupOptions,\n RenameCleanupResult,\n RenameCleanupStyle,\n RenameCleanupTimestampAction,\n} from \"./cleanup-contract\";\n\nconst RENAME_CLEANUP_HINT_VALUES = CLEANUP_HINT_VALUES;\nconst RENAME_CLEANUP_CONFLICT_STRATEGY_VALUES = [\"skip\", \"number\", \"uid-suffix\"] as const;\n\nfunction normalizeCleanupHints(hints: string[]): RenameCleanupHint[] {\n if (hints.length === 0) {\n throw new CliError(\"At least one --hint is required.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n const normalized: RenameCleanupHint[] = [];\n const seen = new Set<RenameCleanupHint>();\n for (const hint of hints) {\n const next = hint.trim().toLowerCase();\n if (!(RENAME_CLEANUP_HINT_VALUES as readonly string[]).includes(next)) {\n throw new CliError(\n `Invalid --hint value: ${hint}. Expected one of: ${RENAME_CLEANUP_HINT_VALUES.join(\", \")}.`,\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n }\n\n const typed = next as RenameCleanupHint;\n if (!seen.has(typed)) {\n normalized.push(typed);\n seen.add(typed);\n }\n }\n\n return normalized;\n}\n\nfunction normalizeCleanupPreviewSkipsMode(\n mode: RenameCleanupOptions[\"previewSkips\"],\n): \"summary\" | \"detailed\" {\n if (mode === undefined || mode === \"summary\") {\n return \"summary\";\n }\n if (mode === \"detailed\") {\n return \"detailed\";\n }\n throw new CliError(`Invalid --preview-skips value: ${mode}. Expected one of: summary, detailed`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n}\n\nfunction normalizeCleanupConflictStrategy(\n strategy: RenameCleanupOptions[\"conflictStrategy\"],\n): RenameCleanupConflictStrategy {\n if (strategy === undefined) {\n return \"skip\";\n }\n\n if (\n (RENAME_CLEANUP_CONFLICT_STRATEGY_VALUES as readonly string[]).includes(strategy)\n ) {\n return strategy;\n }\n\n throw new CliError(\n `Invalid --conflict-strategy value: ${strategy}. Expected one of: ${RENAME_CLEANUP_CONFLICT_STRATEGY_VALUES.join(\", \")}.`,\n {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n },\n );\n}\n\nfunction assertDirectoryOnlyOptionAllowed(\n pathKind: RenameCleanupPathKind,\n enabled: boolean,\n flag: string,\n): void {\n if (pathKind === \"file\" && enabled) {\n throw new CliError(`${flag} is only supported when <path> is a directory.`, {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n}\n\nfunction validateCleanupModeOptions(\n pathKind: RenameCleanupPathKind,\n options: RenameCleanupOptions & { hints: RenameCleanupHint[] },\n): void {\n if (options.timestampAction !== undefined && !options.hints.includes(\"timestamp\")) {\n throw new CliError(\"--timestamp-action requires --hint timestamp.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n if (\n options.maxDepth !== undefined &&\n (!Number.isInteger(options.maxDepth) || options.maxDepth < 0)\n ) {\n throw new CliError(\"--max-depth must be a non-negative integer.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n\n normalizeCleanupPreviewSkipsMode(options.previewSkips);\n assertDirectoryOnlyOptionAllowed(pathKind, options.recursive ?? false, \"--recursive\");\n assertDirectoryOnlyOptionAllowed(pathKind, options.maxDepth !== undefined, \"--max-depth\");\n assertDirectoryOnlyOptionAllowed(pathKind, options.matchRegex !== undefined, \"--match-regex\");\n assertDirectoryOnlyOptionAllowed(pathKind, options.skipRegex !== undefined, \"--skip-regex\");\n assertDirectoryOnlyOptionAllowed(pathKind, (options.ext?.length ?? 0) > 0, \"--ext\");\n assertDirectoryOnlyOptionAllowed(pathKind, (options.skipExt?.length ?? 0) > 0, \"--skip-ext\");\n assertDirectoryOnlyOptionAllowed(pathKind, options.previewSkips !== undefined, \"--preview-skips\");\n\n if (pathKind === \"directory\" && options.maxDepth !== undefined && !(options.recursive ?? false)) {\n throw new CliError(\"--max-depth requires --recursive.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n}\n\nasync function runSingleTemporalCleanup(\n runtime: CliRuntime,\n sourcePath: string,\n options: {\n hints: RenameCleanupHint[];\n style: RenameCleanupStyle;\n timestampAction: RenameCleanupTimestampAction;\n conflictStrategy: RenameCleanupConflictStrategy;\n dryRun: boolean;\n },\n): Promise<RenameCleanupResult> {\n const sourceName = basename(sourcePath);\n const ext = extname(sourceName);\n const stem = basename(sourceName, ext);\n const directoryPath = dirname(sourcePath);\n const result = await buildCleanupBasenameCandidates(\n sourcePath,\n stem,\n options.hints,\n options.style,\n options.timestampAction,\n );\n let finalReason = result.reason;\n let targetPath = sourcePath;\n\n if (!finalReason) {\n const entries = await readdir(directoryPath, { withFileTypes: true });\n const occupiedNames = new Set(\n entries.map((entry) => entry.name).filter((entryName) => entryName !== sourceName),\n );\n const preferredBaseName = result.baseNames[0] ?? stem;\n const resolvedBaseName = await resolveCleanupConflictBasename(\n {\n sourcePath,\n preferredBaseName,\n conflictStrategy: options.conflictStrategy,\n },\n (baseName) => !occupiedNames.has(`${baseName}${ext}`),\n );\n\n if (resolvedBaseName) {\n targetPath = join(directoryPath, `${resolvedBaseName}${ext}`);\n }\n\n if (targetPath === sourcePath && preferredBaseName !== stem) {\n finalReason = \"target conflict\";\n }\n }\n\n const plan: PlannedRename = {\n fromPath: sourcePath,\n toPath: finalReason ? sourcePath : targetPath,\n changed: !finalReason && targetPath !== sourcePath,\n };\n\n printLine(runtime.stdout, `Directory: ${displayPath(runtime, directoryPath)}`);\n printLine(runtime.stdout, `File: ${displayPath(runtime, sourcePath)}`);\n printRenameFilePreview(runtime, plan);\n if (finalReason) {\n printLine(runtime.stdout, `Reason: ${finalReason}`);\n }\n\n if (options.dryRun) {\n const rows = buildCleanupSinglePlanCsvRows(runtime, plan, finalReason);\n const planCsvPath = await writeRenamePlanCsv(runtime, rows);\n printRenameFileDryRunFooter(runtime, planCsvPath);\n return {\n kind: \"file\",\n changed: plan.changed,\n filePath: sourcePath,\n directoryPath,\n planCsvPath,\n };\n }\n\n await applyPlannedRenames([plan]);\n printRenameFileApplyFooter(runtime, plan.changed);\n return {\n kind: \"file\",\n changed: plan.changed,\n filePath: sourcePath,\n directoryPath,\n };\n}\n\nasync function runDirectoryTemporalCleanup(\n runtime: CliRuntime,\n directoryPath: string,\n options: RenameCleanupOptions & {\n hints: RenameCleanupHint[];\n style: RenameCleanupStyle;\n timestampAction: RenameCleanupTimestampAction;\n conflictStrategy: RenameCleanupConflictStrategy;\n },\n): Promise<RenameCleanupResult> {\n const previewSkips = normalizeCleanupPreviewSkipsMode(options.previewSkips);\n const collected = await collectDirectoryCleanupCandidates(directoryPath, options);\n const planned = await buildDirectoryCleanupPlans(\n collected.candidates,\n collected.occupiedFilePaths,\n {\n hints: options.hints,\n style: options.style,\n timestampAction: options.timestampAction,\n conflictStrategy: options.conflictStrategy,\n },\n );\n const totalCount = collected.candidates.length;\n const changedCount = planned.plans.length;\n const skipped = [...collected.skipped, ...planned.skipped];\n\n printLine(runtime.stdout, `Directory: ${displayPath(runtime, directoryPath)}`);\n printLine(runtime.stdout, `Files found: ${totalCount}`);\n printLine(runtime.stdout, `Files to rename: ${changedCount}`);\n if (skipped.length > 0) {\n printLine(runtime.stdout, `Entries skipped: ${skipped.length}`);\n }\n printLine(runtime.stdout);\n\n const { truncated } = printRenameBatchPreview(runtime, {\n plans: planned.plans,\n skipped,\n previewSkips,\n dryRun: options.dryRun ?? false,\n });\n\n if (options.dryRun ?? false) {\n const rows = buildCleanupBatchPlanCsvRows(runtime, planned.plans, skipped);\n const planCsvPath = await writeRenamePlanCsv(runtime, rows);\n printRenameBatchDryRunFooter(runtime, { planCsvPath, truncated });\n return {\n kind: \"directory\",\n changedCount,\n totalCount,\n directoryPath,\n planCsvPath,\n };\n }\n\n await applyPlannedRenames(planned.plans);\n printRenameBatchApplyFooter(runtime, changedCount);\n return {\n kind: \"directory\",\n changedCount,\n totalCount,\n directoryPath,\n };\n}\n\nexport async function actionRenameCleanup(\n runtime: CliRuntime,\n options: RenameCleanupOptions,\n): Promise<RenameCleanupResult> {\n const inputPath = assertNonEmpty(options.path, \"Cleanup path\");\n const hints = normalizeCleanupHints(options.hints);\n const style = options.style ?? \"preserve\";\n const target = await resolveRenameCleanupTarget(runtime, inputPath);\n validateCleanupModeOptions(target.kind, { ...options, hints, style });\n const timestampAction = options.timestampAction ?? \"keep\";\n const conflictStrategy = normalizeCleanupConflictStrategy(options.conflictStrategy);\n\n if (target.kind === \"file\") {\n return await runSingleTemporalCleanup(runtime, target.path, {\n hints,\n style,\n timestampAction,\n conflictStrategy,\n dryRun: options.dryRun ?? false,\n });\n }\n\n return await runDirectoryTemporalCleanup(runtime, target.path, {\n ...options,\n hints,\n style,\n timestampAction,\n conflictStrategy,\n });\n}\n","import { readdir } from \"node:fs/promises\";\nimport { basename, extname, join, relative } from \"node:path\";\n\nimport type { CliRuntime } from \"../../types\";\nimport type { RenameCleanupPathKind } from \"./cleanup-target\";\nimport { resolveRenameCleanupTarget } from \"./cleanup-target\";\nimport type { RenameCleanupOptions } from \"./cleanup-contract\";\nimport { createRenameBatchFileFilter } from \"./filters\";\n\n// Analyzer evidence limits are intentionally conservative:\n// - sampleLimit bounds prompt payload and grouping cost\n// - groupLimit keeps grouped review and suggestion context readable\n// - examplesPerGroup balances pattern representativeness and output size\nexport const RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS = {\n sampleLimit: 40,\n groupLimit: 12,\n examplesPerGroup: 3,\n} as const;\nconst CLEANUP_ANALYZER_MACOS_TIMESTAMP_PATTERN =\n /\\b\\d{4}-\\d{2}-\\d{2} at \\d{1,2}\\.\\d{2}\\.\\d{2} (?:AM|PM)\\b/gi;\nconst CLEANUP_ANALYZER_DATE_PATTERN = /\\b\\d{4}-\\d{2}-\\d{2}\\b/gi;\nconst CLEANUP_ANALYZER_UID_PATTERN = /\\buid-[0-9a-hjkmnpqrstvwxyz]{10,16}\\b/gi;\nconst RENAME_PLAN_CSV_ARTIFACT_PATTERN = /^rename-plan-\\d{8}T\\d{6}Z-[a-f0-9]{8}\\.csv$/;\n\nexport interface RenameCleanupAnalyzerGroup {\n pattern: string;\n count: number;\n examples: string[];\n}\n\nexport interface RenameCleanupAnalyzerEvidence {\n targetKind: RenameCleanupPathKind;\n targetPath: string;\n totalCandidateCount: number;\n sampledCount: number;\n sampleNames: string[];\n groupedPatterns: RenameCleanupAnalyzerGroup[];\n}\n\nexport interface RenameCleanupAnalyzerEvidenceOptions\n extends Pick<\n RenameCleanupOptions,\n \"path\" | \"recursive\" | \"maxDepth\" | \"matchRegex\" | \"skipRegex\" | \"ext\" | \"skipExt\"\n > {\n sampleLimit?: number;\n groupLimit?: number;\n examplesPerGroup?: number;\n onProgress?: (phase: \"sampling\" | \"grouping\") => void;\n}\n\nfunction clampPositiveInteger(value: number | undefined, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) {\n return fallback;\n }\n const normalized = Math.trunc(value);\n return normalized > 0 ? normalized : fallback;\n}\n\nfunction normalizeCleanupAnalyzerPattern(fileName: string): string {\n const originalExtension = extname(fileName);\n const extension = originalExtension.toLowerCase();\n const stem = basename(fileName, originalExtension);\n\n const normalizedStem = stem\n .toLowerCase()\n .replace(CLEANUP_ANALYZER_MACOS_TIMESTAMP_PATTERN, \"{timestamp}\")\n .replace(CLEANUP_ANALYZER_DATE_PATTERN, \"{date}\")\n .replace(CLEANUP_ANALYZER_UID_PATTERN, \"{uid}\")\n .replace(/(?:[\\s._-]*)\\(\\d+\\)$/g, \"-{serial}\")\n .replace(/(?:[\\s_-]+)0\\d+$/g, \"-{serial}\")\n .replace(/\\d+/g, \"#\")\n .replace(/[\\s._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n\n return `${normalizedStem || \"file\"}${extension}`;\n}\n\nfunction buildGroupedPatterns(\n names: string[],\n options: { groupLimit: number; examplesPerGroup: number },\n): RenameCleanupAnalyzerGroup[] {\n const grouped = new Map<string, RenameCleanupAnalyzerGroup>();\n\n for (const name of names) {\n const pattern = normalizeCleanupAnalyzerPattern(basename(name));\n const existing = grouped.get(pattern);\n if (!existing) {\n grouped.set(pattern, {\n pattern,\n count: 1,\n examples: [name],\n });\n continue;\n }\n\n existing.count += 1;\n if (existing.examples.length < options.examplesPerGroup) {\n existing.examples.push(name);\n }\n }\n\n return [...grouped.values()]\n .sort((left, right) => right.count - left.count || left.pattern.localeCompare(right.pattern))\n .slice(0, options.groupLimit);\n}\n\nfunction toRelativeDisplayName(rootPath: string, filePath: string): string {\n const next = relative(rootPath, filePath);\n return next && next.length > 0 ? next : basename(filePath);\n}\n\nfunction isRenamePlanCsvArtifactName(entryName: string): boolean {\n return RENAME_PLAN_CSV_ARTIFACT_PATTERN.test(entryName);\n}\n\nasync function collectDirectoryCleanupAnalyzerSampling(\n directoryPath: string,\n options: Pick<\n RenameCleanupOptions,\n \"recursive\" | \"maxDepth\" | \"matchRegex\" | \"skipRegex\" | \"ext\" | \"skipExt\"\n > & {\n sampleLimit: number;\n },\n): Promise<{ totalCandidateCount: number; sampleNames: string[] }> {\n const sampleNames: string[] = [];\n let totalCandidateCount = 0;\n const recursive = options.recursive ?? false;\n const maxDepth = recursive ? (options.maxDepth ?? Number.POSITIVE_INFINITY) : 0;\n const fileFilter = createRenameBatchFileFilter({\n matchRegex: options.matchRegex,\n skipRegex: options.skipRegex,\n ext: options.ext,\n skipExt: options.skipExt,\n });\n\n const visitDirectory = async (currentDirectoryPath: string, depth: number): Promise<void> => {\n const entries = await readdir(currentDirectoryPath, { withFileTypes: true });\n const sortedEntries = [...entries].sort((left, right) => left.name.localeCompare(right.name));\n\n for (const entry of sortedEntries) {\n const entryPath = join(currentDirectoryPath, entry.name);\n\n if (entry.isSymbolicLink()) {\n continue;\n }\n\n if (entry.isDirectory()) {\n if (recursive && depth < maxDepth) {\n await visitDirectory(entryPath, depth + 1);\n }\n continue;\n }\n\n if (!entry.isFile()) {\n continue;\n }\n\n if (isRenamePlanCsvArtifactName(entry.name)) {\n continue;\n }\n if (!fileFilter(entry.name)) {\n continue;\n }\n\n totalCandidateCount += 1;\n if (sampleNames.length < options.sampleLimit) {\n sampleNames.push(toRelativeDisplayName(directoryPath, entryPath));\n }\n }\n };\n\n await visitDirectory(directoryPath, 0);\n return { totalCandidateCount, sampleNames };\n}\n\nexport async function collectRenameCleanupAnalyzerEvidence(\n runtime: CliRuntime,\n options: RenameCleanupAnalyzerEvidenceOptions,\n): Promise<RenameCleanupAnalyzerEvidence> {\n const target = await resolveRenameCleanupTarget(runtime, options.path);\n const sampleLimit = clampPositiveInteger(\n options.sampleLimit,\n RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS.sampleLimit,\n );\n const groupLimit = clampPositiveInteger(\n options.groupLimit,\n RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS.groupLimit,\n );\n const examplesPerGroup = clampPositiveInteger(\n options.examplesPerGroup,\n RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS.examplesPerGroup,\n );\n options.onProgress?.(\"sampling\");\n\n if (target.kind === \"file\") {\n const fileName = basename(target.path);\n options.onProgress?.(\"grouping\");\n return {\n targetKind: \"file\",\n targetPath: target.path,\n totalCandidateCount: 1,\n sampledCount: 1,\n sampleNames: [fileName],\n groupedPatterns: buildGroupedPatterns([fileName], { groupLimit, examplesPerGroup }),\n };\n }\n\n const sampled = await collectDirectoryCleanupAnalyzerSampling(target.path, {\n recursive: options.recursive,\n maxDepth: options.maxDepth,\n matchRegex: options.matchRegex,\n skipRegex: options.skipRegex,\n ext: options.ext,\n skipExt: options.skipExt,\n sampleLimit,\n });\n options.onProgress?.(\"grouping\");\n\n return {\n targetKind: \"directory\",\n targetPath: target.path,\n totalCandidateCount: sampled.totalCandidateCount,\n sampledCount: sampled.sampleNames.length,\n sampleNames: sampled.sampleNames,\n groupedPatterns: buildGroupedPatterns(sampled.sampleNames, { groupLimit, examplesPerGroup }),\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport { relative, resolve } from \"node:path\";\n\nimport { stringifyCsv } from \"../../../utils/csv\";\nimport { formatUtcFileDateTimeISO } from \"../../../utils/datetime\";\nimport { writeTextFileSafe } from \"../../fs-utils\";\nimport type { CliRuntime } from \"../../types\";\nimport type { RenameCleanupAnalyzerEvidence } from \"./cleanup-analyzer\";\nimport type { RenameCleanupCodexSuggestion } from \"./cleanup-codex\";\n\nexport const RENAME_CLEANUP_ANALYSIS_CSV_HEADERS = [\n \"report_id\",\n \"generated_at\",\n \"scope_kind\",\n \"scope_path\",\n \"total_candidate_count\",\n \"sampled_count\",\n \"group_index\",\n \"grouped_pattern\",\n \"group_count\",\n \"representative_examples\",\n \"recommended_hints\",\n \"recommended_style\",\n \"recommended_timestamp_action\",\n \"confidence\",\n \"reasoning_summary\",\n] as const;\n\nexport interface RenameCleanupAnalysisCsvRow {\n report_id: string;\n generated_at: string;\n scope_kind: RenameCleanupAnalyzerEvidence[\"targetKind\"];\n scope_path: string;\n total_candidate_count: string;\n sampled_count: string;\n group_index: string;\n grouped_pattern: string;\n group_count: string;\n representative_examples: string;\n recommended_hints: string;\n recommended_style: string;\n recommended_timestamp_action: string;\n confidence: string;\n reasoning_summary: string;\n}\n\nfunction toReportScopePath(cwd: string, absolutePath: string): string {\n const next = relative(cwd, absolutePath);\n if (!next || next.startsWith(\"..\")) {\n return absolutePath;\n }\n return next;\n}\n\nexport function createRenameCleanupAnalysisCsvRows(\n runtime: CliRuntime,\n options: {\n evidence: RenameCleanupAnalyzerEvidence;\n suggestion: RenameCleanupCodexSuggestion;\n },\n): { rows: RenameCleanupAnalysisCsvRow[]; reportId: string; generatedAt: string } {\n const generatedAt = runtime.now().toISOString();\n const reportId = `${formatUtcFileDateTimeISO(runtime.now())}-${randomUUID().slice(0, 8)}`;\n const rows = options.evidence.groupedPatterns.map((group, index) => ({\n report_id: reportId,\n generated_at: generatedAt,\n scope_kind: options.evidence.targetKind,\n scope_path: toReportScopePath(runtime.cwd, options.evidence.targetPath),\n total_candidate_count: String(options.evidence.totalCandidateCount),\n sampled_count: String(options.evidence.sampledCount),\n group_index: String(index + 1),\n grouped_pattern: group.pattern,\n group_count: String(group.count),\n representative_examples: group.examples.join(\" | \"),\n recommended_hints: options.suggestion.recommendedHints.join(\",\"),\n recommended_style: options.suggestion.recommendedStyle,\n recommended_timestamp_action: options.suggestion.recommendedTimestampAction ?? \"\",\n confidence: String(options.suggestion.confidence),\n reasoning_summary: options.suggestion.reasoningSummary,\n }));\n\n return { rows, reportId, generatedAt };\n}\n\nfunction stringifyRenameCleanupAnalysisCsv(rows: RenameCleanupAnalysisCsvRow[]): string {\n if (rows.length === 0) {\n return `${RENAME_CLEANUP_ANALYSIS_CSV_HEADERS.join(\",\")}\\n`;\n }\n return stringifyCsv(rows as unknown as Array<Record<string, unknown>>);\n}\n\nexport async function writeRenameCleanupAnalysisCsv(\n runtime: CliRuntime,\n options: {\n evidence: RenameCleanupAnalyzerEvidence;\n suggestion: RenameCleanupCodexSuggestion;\n },\n): Promise<string> {\n const { rows } = createRenameCleanupAnalysisCsvRows(runtime, options);\n const filename = `rename-cleanup-analysis-${formatUtcFileDateTimeISO(runtime.now())}-${randomUUID().slice(0, 8)}.csv`;\n const csvPath = resolve(runtime.cwd, filename);\n await writeTextFileSafe(csvPath, stringifyRenameCleanupAnalysisCsv(rows), { overwrite: false });\n return csvPath;\n}\n","import { startCodexReadOnlyThread } from \"../../../adapters/codex/shared\";\nimport type { RenameCleanupHint, RenameCleanupStyle, RenameCleanupTimestampAction } from \"./cleanup-contract\";\nimport {\n RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS,\n type RenameCleanupAnalyzerEvidence,\n} from \"./cleanup-analyzer\";\n\nconst CLEANUP_HINT_VALUES = [\"date\", \"timestamp\", \"serial\", \"uid\"] as const satisfies readonly RenameCleanupHint[];\nconst CLEANUP_STYLE_VALUES = [\"preserve\", \"slug\"] as const satisfies readonly RenameCleanupStyle[];\nconst CLEANUP_TIMESTAMP_ACTION_VALUES = [\"keep\", \"remove\"] as const satisfies readonly RenameCleanupTimestampAction[];\nconst RENAME_CLEANUP_CODEX_PROMPT_LIMITS = {\n maxSampleLines: RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS.sampleLimit,\n maxGroupedLines: RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS.groupLimit,\n maxSampleNameChars: 180,\n maxGroupedExamplesChars: 260,\n maxGroupedSectionChars: 3_000,\n} as const;\n\nconst CLEANUP_SUGGESTION_OUTPUT_SCHEMA = {\n type: \"object\",\n properties: {\n recommended_hints: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: CLEANUP_HINT_VALUES,\n },\n },\n recommended_style: {\n type: \"string\",\n enum: CLEANUP_STYLE_VALUES,\n },\n recommended_timestamp_action: {\n type: \"string\",\n enum: [...CLEANUP_TIMESTAMP_ACTION_VALUES, \"none\"],\n },\n confidence: {\n type: \"number\",\n minimum: 0,\n maximum: 1,\n },\n reasoning_summary: {\n type: \"string\",\n },\n },\n required: [\n \"recommended_hints\",\n \"recommended_style\",\n \"recommended_timestamp_action\",\n \"confidence\",\n \"reasoning_summary\",\n ],\n additionalProperties: false,\n} as const;\n\nexport interface RenameCleanupCodexSuggestion {\n recommendedHints: RenameCleanupHint[];\n recommendedStyle: RenameCleanupStyle;\n recommendedTimestampAction?: RenameCleanupTimestampAction;\n confidence: number;\n reasoningSummary: string;\n}\n\nexport interface RenameCleanupCodexSuggestionResult {\n suggestion?: RenameCleanupCodexSuggestion;\n errorMessage?: string;\n}\n\nexport type RenameCleanupCodexRunner = (options: {\n prompt: string;\n workingDirectory: string;\n timeoutMs?: number;\n}) => Promise<string>;\n\nexport interface SuggestRenameCleanupWithCodexOptions {\n evidence: RenameCleanupAnalyzerEvidence;\n workingDirectory: string;\n timeoutMs?: number;\n runner?: RenameCleanupCodexRunner;\n}\n\nfunction isCleanupHint(value: string): value is RenameCleanupHint {\n return CLEANUP_HINT_VALUES.includes(value as RenameCleanupHint);\n}\n\nfunction isCleanupStyle(value: string): value is RenameCleanupStyle {\n return CLEANUP_STYLE_VALUES.includes(value as RenameCleanupStyle);\n}\n\nfunction isCleanupTimestampAction(value: string): value is RenameCleanupTimestampAction {\n return CLEANUP_TIMESTAMP_ACTION_VALUES.includes(value as RenameCleanupTimestampAction);\n}\n\nfunction clampConfidence(value: unknown): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n return 0.5;\n }\n return Math.max(0, Math.min(1, value));\n}\n\nfunction parseRenameCleanupSuggestion(finalResponse: string): RenameCleanupCodexSuggestion {\n const parsed = JSON.parse(finalResponse) as {\n recommended_hints?: unknown;\n recommended_style?: unknown;\n recommended_timestamp_action?: unknown;\n confidence?: unknown;\n reasoning_summary?: unknown;\n };\n\n const recommendedHints = Array.isArray(parsed.recommended_hints)\n ? [...new Set(parsed.recommended_hints.filter((item): item is RenameCleanupHint => typeof item === \"string\" && isCleanupHint(item)))]\n : [];\n if (recommendedHints.length === 0) {\n throw new Error(\"Codex cleanup suggestion did not include any supported hints.\");\n }\n\n if (typeof parsed.recommended_style !== \"string\" || !isCleanupStyle(parsed.recommended_style)) {\n throw new Error(\"Codex cleanup suggestion returned an unsupported style.\");\n }\n\n const timestampValue =\n typeof parsed.recommended_timestamp_action === \"string\"\n ? parsed.recommended_timestamp_action\n : \"none\";\n if (recommendedHints.includes(\"timestamp\")) {\n if (!isCleanupTimestampAction(timestampValue)) {\n throw new Error(\"Codex cleanup suggestion must include a timestamp action for timestamp hints.\");\n }\n } else if (timestampValue !== \"none\" && !isCleanupTimestampAction(timestampValue)) {\n throw new Error(\"Codex cleanup suggestion returned an unsupported timestamp action.\");\n }\n\n const reasoningSummary =\n typeof parsed.reasoning_summary === \"string\" ? parsed.reasoning_summary.trim() : \"\";\n if (!reasoningSummary) {\n throw new Error(\"Codex cleanup suggestion did not include reasoning summary.\");\n }\n\n return {\n recommendedHints,\n recommendedStyle: parsed.recommended_style,\n recommendedTimestampAction: isCleanupTimestampAction(timestampValue)\n ? timestampValue\n : undefined,\n confidence: clampConfidence(parsed.confidence),\n reasoningSummary,\n };\n}\n\nfunction truncateForPrompt(value: string, maxChars: number): { value: string; truncated: boolean } {\n if (value.length <= maxChars) {\n return { value, truncated: false };\n }\n if (maxChars <= 3) {\n return { value: value.slice(0, maxChars), truncated: true };\n }\n return {\n value: `${value.slice(0, maxChars - 3)}...`,\n truncated: true,\n };\n}\n\nfunction buildCleanupAnalyzerPrompt(evidence: RenameCleanupAnalyzerEvidence): string {\n const promptSampleNames = evidence.sampleNames.slice(0, RENAME_CLEANUP_CODEX_PROMPT_LIMITS.maxSampleLines);\n const sampleLines =\n promptSampleNames.length > 0\n ? promptSampleNames.map((name, index) => {\n const truncated = truncateForPrompt(name, RENAME_CLEANUP_CODEX_PROMPT_LIMITS.maxSampleNameChars);\n return `${index + 1}. ${truncated.value}`;\n })\n : [\"(no sampled names)\"];\n if (evidence.sampleNames.length > promptSampleNames.length) {\n sampleLines.push(\n `... ${evidence.sampleNames.length - promptSampleNames.length} additional sample name(s) omitted for prompt safety.`,\n );\n }\n const sampleList = sampleLines.join(\"\\n\");\n\n const promptGroupedPatterns = evidence.groupedPatterns.slice(\n 0,\n RENAME_CLEANUP_CODEX_PROMPT_LIMITS.maxGroupedLines,\n );\n const groupedLines: string[] = [];\n let emittedGroupedPatternCount = 0;\n let groupedSectionChars = 0;\n for (const [index, group] of promptGroupedPatterns.entries()) {\n const truncatedExamples = truncateForPrompt(\n group.examples.join(\" | \"),\n RENAME_CLEANUP_CODEX_PROMPT_LIMITS.maxGroupedExamplesChars,\n );\n const nextLine = `${index + 1}. pattern=${group.pattern}; count=${group.count}; examples=${truncatedExamples.value}`;\n const projectedChars = groupedSectionChars + (groupedLines.length > 0 ? 1 : 0) + nextLine.length;\n if (projectedChars > RENAME_CLEANUP_CODEX_PROMPT_LIMITS.maxGroupedSectionChars) {\n break;\n }\n groupedLines.push(nextLine);\n emittedGroupedPatternCount += 1;\n groupedSectionChars = projectedChars;\n }\n if (groupedLines.length === 0) {\n groupedLines.push(\"(no grouped patterns)\");\n }\n const omittedByLineLimit = Math.max(0, evidence.groupedPatterns.length - promptGroupedPatterns.length);\n const omittedBySectionCap = Math.max(0, promptGroupedPatterns.length - groupedLines.length);\n const omittedGroupedCount = omittedByLineLimit + omittedBySectionCap;\n if (omittedGroupedCount > 0) {\n groupedLines.push(`... ${omittedGroupedCount} grouped pattern(s) omitted for prompt safety.`);\n }\n const groupedPatternList = groupedLines.join(\"\\n\");\n\n return [\n \"Analyze these filename cleanup candidates and recommend rename-cleanup settings.\",\n \"Return JSON only following the provided schema.\",\n \"Goal:\",\n \"- Infer likely cleanup hint families from filenames only.\",\n \"- Recommend the best cleanup style for the surviving text.\",\n \"- Recommend timestamp action only when timestamp hints are included.\",\n \"\",\n \"Rules:\",\n \"- Use only supported hints: date, timestamp, serial, uid.\",\n \"- Use only supported styles: preserve, slug.\",\n \"- Use recommended_timestamp_action = none when timestamp is not recommended.\",\n \"- Keep reasoning_summary short and concrete.\",\n \"- Do not invent regex rules or content-based reasoning.\",\n \"\",\n `Target kind: ${evidence.targetKind}`,\n `Total candidate count: ${evidence.totalCandidateCount}`,\n `Sampled count: ${evidence.sampledCount}`,\n \"\",\n `Sample filenames (showing ${promptSampleNames.length} of ${evidence.sampleNames.length}):`,\n sampleList,\n \"\",\n `Grouped filename patterns (showing ${emittedGroupedPatternCount} of ${evidence.groupedPatterns.length}):`,\n groupedPatternList,\n ].join(\"\\n\");\n}\n\nasync function runRenameCleanupCodexPrompt(options: {\n prompt: string;\n workingDirectory: string;\n timeoutMs?: number;\n}): Promise<string> {\n const thread = startCodexReadOnlyThread(options.workingDirectory);\n const turn = await thread.run([{ type: \"text\", text: options.prompt }], {\n outputSchema: CLEANUP_SUGGESTION_OUTPUT_SCHEMA,\n signal: AbortSignal.timeout(options.timeoutMs ?? 30_000),\n });\n return turn.finalResponse;\n}\n\nexport async function suggestRenameCleanupWithCodex(\n options: SuggestRenameCleanupWithCodexOptions,\n): Promise<RenameCleanupCodexSuggestionResult> {\n try {\n const runner = options.runner ?? runRenameCleanupCodexPrompt;\n const finalResponse = await runner({\n prompt: buildCleanupAnalyzerPrompt(options.evidence),\n workingDirectory: options.workingDirectory,\n timeoutMs: options.timeoutMs,\n });\n return {\n suggestion: parseRenameCleanupSuggestion(finalResponse),\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { errorMessage: message };\n }\n}\n","import { resolveAutoCodexFlagsForFilePath, resolveCodexFlagsFromCliOptions } from \"../../rename-interactive-router\";\nimport {\n type RenameSerialOrder,\n type RenameSerialScope,\n type TimestampTimezone,\n} from \"../../rename-template\";\nimport { applyPlannedRenames, planSingleRename } from \"../../fs-utils\";\nimport type { CliRuntime } from \"../../types\";\nimport {\n type CodexDocumentRenameTitleSuggester,\n type CodexImageRenameTitleSuggester,\n printRenameFileCodexSummary,\n runRenameCodexAnalysis,\n} from \"./codex\";\nimport {\n resolveEffectivePattern,\n writeSingleRenameDryRunPlanCsv,\n} from \"./plan-output\";\nimport {\n printRenameFileApplyFooter,\n printRenameFileDryRunFooter,\n printRenameFilePreview,\n} from \"./reporting\";\nimport { assertNonEmpty, displayPath, printLine } from \"../shared\";\n\nexport interface RenameFileOptions {\n path: string;\n prefix?: string;\n pattern?: string;\n codex?: boolean;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope?: RenameSerialScope;\n timestampTimezone?: TimestampTimezone;\n dryRun?: boolean;\n codexImages?: boolean;\n codexImagesTimeoutMs?: number;\n codexImagesRetries?: number;\n codexImagesBatchSize?: number;\n codexImagesTitleSuggester?: CodexImageRenameTitleSuggester;\n codexDocs?: boolean;\n codexDocsTimeoutMs?: number;\n codexDocsRetries?: number;\n codexDocsBatchSize?: number;\n codexDocsTitleSuggester?: CodexDocumentRenameTitleSuggester;\n}\n\nexport async function actionRenameFile(\n runtime: CliRuntime,\n options: RenameFileOptions,\n): Promise<{ changed: boolean; filePath: string; directoryPath: string; planCsvPath?: string }> {\n const inputPath = assertNonEmpty(options.path, \"File path\");\n const effectivePattern = resolveEffectivePattern(options.pattern, options.timestampTimezone);\n const initial = await planSingleRename(runtime, inputPath, {\n prefix: options.prefix,\n pattern: effectivePattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n now: runtime.now(),\n });\n const effectiveCodexFlags = resolveCodexFlagsFromCliOptions({\n cli: {\n codex: options.codex,\n codexImages: options.codexImages,\n codexDocs: options.codexDocs,\n },\n fallbackAuto: resolveAutoCodexFlagsForFilePath(initial.plan.fromPath),\n });\n const directoryPath = initial.directoryPath;\n let plan = initial.plan;\n const codexAnalysis = await runRenameCodexAnalysis(runtime, [initial.plan], {\n effectiveFlags: effectiveCodexFlags,\n cli: {\n codex: options.codex,\n codexImages: options.codexImages,\n codexImagesTimeoutMs: options.codexImagesTimeoutMs,\n codexImagesRetries: options.codexImagesRetries,\n codexImagesBatchSize: options.codexImagesBatchSize,\n codexImagesTitleSuggester: options.codexImagesTitleSuggester,\n codexDocs: options.codexDocs,\n codexDocsTimeoutMs: options.codexDocsTimeoutMs,\n codexDocsRetries: options.codexDocsRetries,\n codexDocsBatchSize: options.codexDocsBatchSize,\n codexDocsTitleSuggester: options.codexDocsTitleSuggester,\n },\n });\n const codexTitlesByPath = new Map<string, string>(codexAnalysis.titlesByPath);\n const titleOverride = codexTitlesByPath.get(initial.plan.fromPath);\n if (titleOverride) {\n const replanned = await planSingleRename(runtime, inputPath, {\n prefix: options.prefix,\n pattern: effectivePattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n now: runtime.now(),\n titleOverride,\n });\n plan = replanned.plan;\n }\n\n printLine(runtime.stdout, `Directory: ${displayPath(runtime, directoryPath)}`);\n printLine(runtime.stdout, `File: ${displayPath(runtime, plan.fromPath)}`);\n printRenameFileCodexSummary(runtime, {\n analysis: codexAnalysis,\n sourcePath: plan.fromPath,\n codexRequested: options.codex ?? false,\n });\n printRenameFilePreview(runtime, plan);\n\n if (options.dryRun ?? false) {\n const planCsvPath = await writeSingleRenameDryRunPlanCsv(runtime, {\n plan,\n codexTitlesByPath,\n reasonBySourcePath: codexAnalysis.reasonBySourcePath,\n effectivePattern,\n });\n\n printRenameFileDryRunFooter(runtime, planCsvPath);\n return { changed: plan.changed, filePath: plan.fromPath, directoryPath, planCsvPath };\n }\n\n await applyPlannedRenames([plan]);\n printRenameFileApplyFooter(runtime, plan.changed);\n\n return { changed: plan.changed, filePath: plan.fromPath, directoryPath };\n}\n","import { resolve } from \"node:path\";\n\nimport { requireCommandAvailable } from \"../deps\";\nimport { CliError } from \"../errors\";\nimport { defaultOutputPath } from \"../fs-utils\";\nimport { execCommand } from \"../process\";\nimport type { CliRuntime } from \"../types\";\nimport { assertNonEmpty, displayPath, ensureFileExists, printLine } from \"./shared\";\n\nexport interface VideoConvertOptions {\n input: string;\n output: string;\n overwrite?: boolean;\n}\n\nexport interface VideoResizeOptions {\n input: string;\n output: string;\n scale?: number;\n width?: number;\n height?: number;\n overwrite?: boolean;\n}\n\nexport interface VideoGifOptions {\n input: string;\n output?: string;\n width?: number;\n fps?: number;\n overwrite?: boolean;\n}\n\nasync function runFfmpeg(runtime: CliRuntime, args: string[]): Promise<void> {\n await requireCommandAvailable(\"ffmpeg\", runtime.platform);\n const result = await execCommand(\"ffmpeg\", args, { cwd: runtime.cwd });\n if (!result.ok) {\n throw new CliError(`ffmpeg failed (${result.code ?? \"unknown\"}): ${result.stderr || result.stdout}`.trim(), {\n code: \"PROCESS_FAILED\",\n exitCode: 1,\n });\n }\n}\n\nexport async function actionVideoConvert(runtime: CliRuntime, options: VideoConvertOptions): Promise<void> {\n const inputPath = resolve(runtime.cwd, assertNonEmpty(options.input, \"Input path\"));\n const outputPath = resolve(runtime.cwd, assertNonEmpty(options.output, \"Output path\"));\n await ensureFileExists(inputPath, \"Input\");\n\n const args = [options.overwrite ? \"-y\" : \"-n\", \"-i\", inputPath, outputPath];\n await runFfmpeg(runtime, args);\n printLine(runtime.stdout, `Wrote video: ${displayPath(runtime, outputPath)}`);\n}\n\nexport async function actionVideoResize(runtime: CliRuntime, options: VideoResizeOptions): Promise<void> {\n const inputPath = resolve(runtime.cwd, assertNonEmpty(options.input, \"Input path\"));\n const outputPath = resolve(runtime.cwd, assertNonEmpty(options.output, \"Output path\"));\n const hasScale = options.scale !== undefined;\n const hasWidth = options.width !== undefined;\n const hasHeight = options.height !== undefined;\n\n if (hasScale && (hasWidth || hasHeight)) {\n throw new CliError(\"Use either --scale or both --width and --height, not both.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n if (hasWidth !== hasHeight) {\n throw new CliError(\"Width and height must be provided together.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n if (!hasScale && !hasWidth && !hasHeight) {\n throw new CliError(\"Provide --scale or both --width and --height.\", {\n code: \"INVALID_INPUT\",\n exitCode: 2,\n });\n }\n if (hasScale && (!Number.isFinite(options.scale) || options.scale! <= 0)) {\n throw new CliError(\"Scale must be a positive number.\", { code: \"INVALID_INPUT\", exitCode: 2 });\n }\n if (hasWidth && (!Number.isFinite(options.width) || options.width! <= 0)) {\n throw new CliError(\"Width must be a positive number.\", { code: \"INVALID_INPUT\", exitCode: 2 });\n }\n if (hasHeight && (!Number.isFinite(options.height) || options.height! <= 0)) {\n throw new CliError(\"Height must be a positive number.\", { code: \"INVALID_INPUT\", exitCode: 2 });\n }\n await ensureFileExists(inputPath, \"Input\");\n\n const videoFilter = hasScale\n ? `scale=trunc(iw*${options.scale!}/2)*2:trunc(ih*${options.scale!}/2)*2`\n : `scale=${Math.trunc(options.width!)}:${Math.trunc(options.height!)}`;\n\n const args = [\n options.overwrite ? \"-y\" : \"-n\",\n \"-i\",\n inputPath,\n \"-vf\",\n videoFilter,\n outputPath,\n ];\n await runFfmpeg(runtime, args);\n printLine(runtime.stdout, `Wrote resized video: ${displayPath(runtime, outputPath)}`);\n}\n\nexport async function actionVideoGif(runtime: CliRuntime, options: VideoGifOptions): Promise<void> {\n const inputPath = resolve(runtime.cwd, assertNonEmpty(options.input, \"Input path\"));\n const outputPath = resolve(\n runtime.cwd,\n options.output?.trim() || defaultOutputPath(inputPath, \".gif\"),\n );\n await ensureFileExists(inputPath, \"Input\");\n\n const fps = Number.isFinite(options.fps) && (options.fps ?? 0) > 0 ? Math.trunc(options.fps!) : 10;\n const width = Number.isFinite(options.width) && (options.width ?? 0) > 0 ? Math.trunc(options.width!) : 480;\n\n const args = [\n options.overwrite ? \"-y\" : \"-n\",\n \"-i\",\n inputPath,\n \"-vf\",\n `fps=${fps},scale=${width}:-1:flags=lanczos`,\n outputPath,\n ];\n await runFfmpeg(runtime, args);\n printLine(runtime.stdout, `Wrote GIF: ${displayPath(runtime, outputPath)}`);\n}\n","export type PathPromptMode = \"auto\" | \"simple\";\n\nexport interface PathPromptAutocompleteConfig {\n enabled: boolean;\n minChars: number;\n maxSuggestions: number;\n includeHidden: boolean;\n}\n\nexport interface PathPromptRuntimeConfig {\n mode: PathPromptMode;\n autocomplete: PathPromptAutocompleteConfig;\n}\n\nfunction parseBooleanFlag(value: string | undefined, defaultValue: boolean): boolean {\n if (value == null) {\n return defaultValue;\n }\n\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) {\n return true;\n }\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) {\n return false;\n }\n\n return defaultValue;\n}\n\nfunction parsePositiveInt(value: string | undefined, defaultValue: number): number {\n if (value == null || value.trim().length === 0) {\n return defaultValue;\n }\n\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed < 0) {\n return defaultValue;\n }\n\n return parsed;\n}\n\nexport function resolvePathPromptRuntimeConfig(\n env: Record<string, string | undefined> = process.env,\n): PathPromptRuntimeConfig {\n const requestedMode = env.CDX_CHORES_PATH_PROMPT_MODE?.trim().toLowerCase();\n const mode: PathPromptMode = requestedMode === \"simple\" ? \"simple\" : \"auto\";\n\n const disableAutocomplete = parseBooleanFlag(env.CDX_CHORES_DISABLE_PATH_AUTOCOMPLETE, false);\n\n return {\n mode,\n autocomplete: {\n enabled: !disableAutocomplete,\n minChars: parsePositiveInt(env.CDX_CHORES_PATH_AUTOCOMPLETE_MIN_CHARS, 1),\n maxSuggestions: parsePositiveInt(env.CDX_CHORES_PATH_AUTOCOMPLETE_MAX_SUGGESTIONS, 12),\n includeHidden: parseBooleanFlag(env.CDX_CHORES_PATH_AUTOCOMPLETE_INCLUDE_HIDDEN, false),\n },\n };\n}\n\n","export function dim(text: string): string {\n return text.length > 0 ? `\\x1b[2m${text}\\x1b[22m` : \"\";\n}\n\nexport function beep(stdout: NodeJS.WritableStream): void {\n stdout.write(\"\\x07\");\n}\n\nexport function clearCurrentLine(stdout: NodeJS.WritableStream): void {\n stdout.write(\"\\r\\x1b[2K\");\n}\n\nexport function moveCursorLeft(stdout: NodeJS.WritableStream, count: number): void {\n if (count <= 0) {\n return;\n }\n stdout.write(`\\x1b[${count}D`);\n}\n\nexport function hideCursor(stdout: NodeJS.WritableStream): void {\n stdout.write(\"\\x1b[?25l\");\n}\n\nexport function showCursor(stdout: NodeJS.WritableStream): void {\n stdout.write(\"\\x1b[?25h\");\n}\n","import { emitKeypressEvents } from \"node:readline\";\nimport { hideCursor, showCursor } from \"./screen\";\n\nexport interface RawSessionKeypressInfo {\n name?: string;\n ctrl?: boolean;\n meta?: boolean;\n shift?: boolean;\n sequence?: string;\n}\n\nexport type RawSessionKeypressHandler = (str: string, key: RawSessionKeypressInfo) => void;\n\ntype RawModeReadStream = NodeJS.ReadStream & {\n setRawMode(flag: boolean): void;\n on(event: \"keypress\", listener: RawSessionKeypressHandler): NodeJS.ReadStream;\n off(event: \"keypress\", listener: RawSessionKeypressHandler): NodeJS.ReadStream;\n};\n\nexport interface RawSession {\n addKeypressListener(handler: RawSessionKeypressHandler): void;\n close(): void;\n}\n\nexport interface StartRawSessionOptions {\n stdin: NodeJS.ReadStream;\n stdout: NodeJS.WritableStream;\n onTeardown?: () => void;\n}\n\nexport function supportsRawSessionIO(\n stdin: NodeJS.ReadStream,\n stdout: NodeJS.WritableStream,\n): stdin is RawModeReadStream {\n const stdoutWithTTY = stdout as NodeJS.WritableStream & { isTTY?: boolean };\n return Boolean(\n stdin.isTTY &&\n stdoutWithTTY.isTTY &&\n typeof (stdin as Partial<RawModeReadStream>).setRawMode === \"function\",\n );\n}\n\nexport function startRawSession(options: StartRawSessionOptions): RawSession {\n if (!supportsRawSessionIO(options.stdin, options.stdout)) {\n throw new Error(\"Raw session requires TTY stdin/stdout with raw mode support\");\n }\n\n const stdin = options.stdin;\n const stdout = options.stdout;\n const handlers = new Set<RawSessionKeypressHandler>();\n let closed = false;\n\n emitKeypressEvents(stdin);\n if (typeof stdin.resume === \"function\") {\n stdin.resume();\n }\n stdin.setRawMode(true);\n hideCursor(stdout);\n\n return {\n addKeypressListener(handler): void {\n if (closed) {\n throw new Error(\"Cannot add keypress listener to a closed raw session\");\n }\n handlers.add(handler);\n stdin.on(\"keypress\", handler);\n },\n close(): void {\n if (closed) {\n return;\n }\n closed = true;\n\n try {\n options.onTeardown?.();\n } catch {\n // Ignore teardown failures so terminal restoration still runs.\n }\n\n for (const handler of handlers) {\n stdin.off(\"keypress\", handler);\n }\n handlers.clear();\n\n stdin.setRawMode(false);\n if (typeof stdin.pause === \"function\") {\n stdin.pause();\n }\n showCursor(stdout);\n },\n };\n}\n","import type { RawSessionKeypressInfo } from \"./raw-session\";\n\nexport type ParsedKeypressEvent =\n | { kind: \"keypress\"; str: string; key: RawSessionKeypressInfo }\n | { kind: \"arrow\"; direction: \"left\" | \"right\" | \"up\" | \"down\" }\n | { kind: \"incomplete\" };\n\nexport interface CreateKeypressParserOptions {\n onEscapeAbort?: () => void;\n escapeAbortDelayMs?: number;\n}\n\nexport interface KeypressParser {\n handle(str: string | undefined, key?: RawSessionKeypressInfo): ParsedKeypressEvent;\n dispose(): void;\n}\n\nconst DEFAULT_ESCAPE_ABORT_DELAY_MS = 120;\n\nfunction normalizeKeypressChunk(str: string | undefined, key: RawSessionKeypressInfo): string {\n if (typeof str === \"string\") {\n return str;\n }\n if (typeof key.sequence === \"string\") {\n return key.sequence;\n }\n return \"\";\n}\n\nfunction isPotentialEscapeSequenceBuffer(value: string): boolean {\n return /^\\x1b(?:\\[[0-9;?]*|O[0-9;?]*)$/.test(value);\n}\n\nfunction parseSpecialEscapeSequence(\n value: string,\n): ParsedKeypressEvent | undefined {\n if (value === \"\\x1b[C\") {\n return { kind: \"arrow\", direction: \"right\" };\n }\n if (value === \"\\x1b[D\") {\n return { kind: \"arrow\", direction: \"left\" };\n }\n if (value === \"\\x1b[A\") {\n return { kind: \"arrow\", direction: \"up\" };\n }\n if (value === \"\\x1b[B\") {\n return { kind: \"arrow\", direction: \"down\" };\n }\n if (value === \"\\x1b[27;2;13~\" || value === \"\\x1b[13;2u\") {\n return {\n kind: \"keypress\",\n str: \"\",\n key: {\n name: \"return\",\n sequence: value,\n shift: true,\n },\n };\n }\n return undefined;\n}\n\nexport function createKeypressParser(options: CreateKeypressParserOptions = {}): KeypressParser {\n let escapeSequenceBuffer = \"\";\n let pendingEscapeAbortTimer: ReturnType<typeof setTimeout> | undefined;\n const escapeAbortDelayMs = options.escapeAbortDelayMs ?? DEFAULT_ESCAPE_ABORT_DELAY_MS;\n\n const clearPendingEscapeAbort = (): void => {\n if (!pendingEscapeAbortTimer) {\n return;\n }\n clearTimeout(pendingEscapeAbortTimer);\n pendingEscapeAbortTimer = undefined;\n };\n\n const resetEscapeState = (): void => {\n clearPendingEscapeAbort();\n escapeSequenceBuffer = \"\";\n };\n\n const scheduleEscapeAbort = (): void => {\n clearPendingEscapeAbort();\n pendingEscapeAbortTimer = setTimeout(() => {\n pendingEscapeAbortTimer = undefined;\n escapeSequenceBuffer = \"\";\n options.onEscapeAbort?.();\n }, escapeAbortDelayMs);\n };\n\n return {\n handle(str, key = {}): ParsedKeypressEvent {\n const chunk = normalizeKeypressChunk(str, key);\n\n if (key.name !== \"escape\") {\n clearPendingEscapeAbort();\n }\n\n if (escapeSequenceBuffer.length > 0 && key.name !== \"escape\") {\n escapeSequenceBuffer += chunk;\n\n if (key.name === \"right\" || key.name === \"left\" || key.name === \"up\" || key.name === \"down\") {\n resetEscapeState();\n return {\n kind: \"arrow\",\n direction: key.name,\n };\n }\n\n const parsedEscape = parseSpecialEscapeSequence(escapeSequenceBuffer);\n if (parsedEscape) {\n resetEscapeState();\n return parsedEscape;\n }\n\n if (isPotentialEscapeSequenceBuffer(escapeSequenceBuffer)) {\n return { kind: \"incomplete\" };\n }\n\n const completedSequence = escapeSequenceBuffer;\n escapeSequenceBuffer = \"\";\n return {\n kind: \"keypress\",\n str: chunk,\n key: {\n ...key,\n sequence: completedSequence,\n },\n };\n }\n\n if (key.name === \"escape\") {\n escapeSequenceBuffer = \"\\x1b\";\n scheduleEscapeAbort();\n return { kind: \"incomplete\" };\n }\n\n if (key.name === \"right\") {\n return { kind: \"arrow\", direction: \"right\" };\n }\n\n if (key.name === \"left\") {\n return { kind: \"arrow\", direction: \"left\" };\n }\n\n if (key.name === \"up\") {\n return { kind: \"arrow\", direction: \"up\" };\n }\n\n if (key.name === \"down\") {\n return { kind: \"arrow\", direction: \"down\" };\n }\n\n return {\n kind: \"keypress\",\n str: chunk,\n key,\n };\n },\n dispose(): void {\n resetEscapeState();\n },\n };\n}\n","export interface CycleState {\n replacements: string[];\n index: number;\n}\n\nexport interface SiblingPreviewState {\n scopeKey: string;\n replacements: string[];\n activeIndex: number;\n}\n\nexport interface SiblingPreviewCandidateSet {\n scopeKey: string;\n replacements: string[];\n}\n\nexport type SiblingPreviewDirection = \"previous\" | \"next\";\n\nexport interface InlinePromptInteractionState {\n cycleState?: CycleState;\n siblingPreviewState?: SiblingPreviewState;\n}\n\nexport function clearInteractionState(): InlinePromptInteractionState {\n return {};\n}\n\nexport function clearCycleState(\n state: InlinePromptInteractionState,\n): InlinePromptInteractionState {\n if (!state.cycleState) {\n return state;\n }\n\n return {\n ...state,\n cycleState: undefined,\n };\n}\n\nexport function clearSiblingPreviewState(\n state: InlinePromptInteractionState,\n): InlinePromptInteractionState {\n if (!state.siblingPreviewState) {\n return state;\n }\n\n return {\n ...state,\n siblingPreviewState: undefined,\n };\n}\n\nexport function setCycleState(\n state: InlinePromptInteractionState,\n cycleState: CycleState | undefined,\n): InlinePromptInteractionState {\n if (!cycleState) {\n return clearCycleState(state);\n }\n\n return {\n cycleState,\n siblingPreviewState: undefined,\n };\n}\n\nexport function enterSiblingPreviewState(\n state: InlinePromptInteractionState,\n siblingPreviewState: SiblingPreviewState | undefined,\n): InlinePromptInteractionState {\n if (!siblingPreviewState) {\n return clearSiblingPreviewState(clearCycleState(state));\n }\n\n return {\n cycleState: undefined,\n siblingPreviewState,\n };\n}\n\nexport function getActiveSiblingPreviewReplacement(\n state: InlinePromptInteractionState,\n): string | undefined {\n const siblingPreviewState = state.siblingPreviewState;\n if (!siblingPreviewState) {\n return undefined;\n }\n\n return siblingPreviewState.replacements[siblingPreviewState.activeIndex];\n}\n\nexport function deriveGhostSuffixFromPreview(\n value: string,\n previewReplacement: string | undefined,\n): string {\n if (\n !previewReplacement ||\n !previewReplacement.startsWith(value) ||\n previewReplacement.length <= value.length\n ) {\n return \"\";\n }\n\n return previewReplacement.slice(value.length);\n}\n\nexport function derivePreferredGhostSuffix(options: {\n value: string;\n state: InlinePromptInteractionState;\n fallbackReplacement?: string;\n}): string {\n const previewGhostSuffix = deriveGhostSuffixFromPreview(\n options.value,\n getActiveSiblingPreviewReplacement(options.state),\n );\n if (previewGhostSuffix.length > 0) {\n return previewGhostSuffix;\n }\n\n const fallbackReplacement = options.fallbackReplacement;\n if (\n !fallbackReplacement ||\n !fallbackReplacement.startsWith(options.value) ||\n fallbackReplacement.length <= options.value.length\n ) {\n return \"\";\n }\n\n return fallbackReplacement.slice(options.value.length);\n}\n\nexport function acceptSiblingPreview(\n value: string,\n state: InlinePromptInteractionState,\n): {\n accepted: boolean;\n nextState: InlinePromptInteractionState;\n nextValue: string;\n} {\n const previewReplacement = getActiveSiblingPreviewReplacement(state);\n if (!previewReplacement) {\n return {\n accepted: false,\n nextState: state,\n nextValue: value,\n };\n }\n\n return {\n accepted: true,\n nextState: clearInteractionState(),\n nextValue: previewReplacement,\n };\n}\n\nexport function advanceSiblingPreview(\n state: InlinePromptInteractionState,\n candidates: SiblingPreviewCandidateSet,\n direction: SiblingPreviewDirection,\n): {\n changed: boolean;\n nextState: InlinePromptInteractionState;\n previewReplacement?: string;\n} {\n if (candidates.replacements.length === 0) {\n return {\n changed: false,\n nextState: clearInteractionState(),\n };\n }\n\n const activePreview = state.siblingPreviewState;\n const isSameScope = activePreview?.scopeKey === candidates.scopeKey;\n const delta = direction === \"next\" ? 1 : -1;\n\n const nextIndex = isSameScope\n ? (activePreview.activeIndex + delta + candidates.replacements.length) %\n candidates.replacements.length\n : direction === \"next\"\n ? 0\n : candidates.replacements.length - 1;\n\n const nextState = enterSiblingPreviewState(state, {\n scopeKey: candidates.scopeKey,\n replacements: candidates.replacements,\n activeIndex: nextIndex,\n });\n\n return {\n changed: true,\n nextState,\n previewReplacement: candidates.replacements[nextIndex],\n };\n}\n","import { readdir } from \"node:fs/promises\";\nimport { extname, resolve } from \"node:path\";\n\nexport type PathSuggestionKind = \"file\" | \"directory\";\nexport type PathSuggestionTargetKind = \"any\" | PathSuggestionKind;\n\nexport interface PathSuggestion {\n kind: PathSuggestionKind;\n label: string;\n name: string;\n replacement: string;\n absolutePath: string;\n}\n\nexport interface ResolvePathSuggestionsOptions {\n cwd: string;\n input: string;\n maxSuggestions?: number;\n minChars?: number;\n includeHidden?: boolean;\n targetKind?: PathSuggestionTargetKind;\n fileExtensions?: string[];\n enforceTrigger?: boolean;\n}\n\ninterface SuggestionDirEntry {\n name: string;\n isDirectory: boolean;\n isFile: boolean;\n}\n\nexport interface ParsedPathSuggestionInput {\n rawInput: string;\n directoryInput: string;\n fragment: string;\n baseDirectoryPath: string;\n}\n\nfunction findLastSeparatorIndex(value: string): number {\n return Math.max(value.lastIndexOf(\"/\"), value.lastIndexOf(\"\\\\\"));\n}\n\nexport function parsePathSuggestionInput(cwd: string, input: string): ParsedPathSuggestionInput {\n const lastSeparatorIndex = findLastSeparatorIndex(input);\n const directoryInput = lastSeparatorIndex >= 0 ? input.slice(0, lastSeparatorIndex + 1) : \"\";\n const fragment = lastSeparatorIndex >= 0 ? input.slice(lastSeparatorIndex + 1) : input;\n const baseDirectoryPath = resolve(cwd, directoryInput || \".\");\n return {\n rawInput: input,\n directoryInput,\n fragment,\n baseDirectoryPath,\n };\n}\n\nfunction normalizeExtensions(extensions: string[] | undefined): Set<string> | undefined {\n if (!extensions || extensions.length === 0) {\n return undefined;\n }\n\n return new Set(\n extensions\n .map((value) => value.trim().toLowerCase())\n .filter((value) => value.length > 0)\n .map((value) => (value.startsWith(\".\") ? value : `.${value}`)),\n );\n}\n\nfunction compareSuggestionEntries(a: SuggestionDirEntry, b: SuggestionDirEntry): number {\n if (a.isDirectory !== b.isDirectory) {\n return a.isDirectory ? -1 : 1;\n }\n return a.name.localeCompare(b.name);\n}\n\nasync function readSuggestionEntries(directoryPath: string): Promise<SuggestionDirEntry[]> {\n const entries = await readdir(directoryPath, { withFileTypes: true });\n const normalized: SuggestionDirEntry[] = [];\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n normalized.push({ name: entry.name, isDirectory: true, isFile: false });\n continue;\n }\n\n if (entry.isFile()) {\n normalized.push({ name: entry.name, isDirectory: false, isFile: true });\n }\n }\n\n return normalized;\n}\n\nexport function shouldSuggestForPathInput(\n input: string,\n options: { minChars?: number } = {},\n): boolean {\n const minChars = options.minChars ?? 1;\n\n if (input.length >= minChars) {\n return true;\n }\n\n return input === \"./\" || input === \"../\" || input === \"/\";\n}\n\nexport async function resolvePathSuggestions(\n options: ResolvePathSuggestionsOptions,\n): Promise<PathSuggestion[]> {\n const maxSuggestions = Math.max(0, options.maxSuggestions ?? 12);\n if (maxSuggestions === 0) {\n return [];\n }\n\n const minChars = Math.max(0, options.minChars ?? 1);\n const enforceTrigger = options.enforceTrigger ?? true;\n if (enforceTrigger && !shouldSuggestForPathInput(options.input, { minChars })) {\n return [];\n }\n\n const parsed = parsePathSuggestionInput(options.cwd, options.input);\n const extensionFilter = normalizeExtensions(options.fileExtensions);\n const targetKind = options.targetKind ?? \"any\";\n const includeHidden = options.includeHidden ?? false;\n const effectiveIncludeHidden = includeHidden || parsed.fragment.startsWith(\".\");\n\n let entries: SuggestionDirEntry[];\n try {\n entries = await readSuggestionEntries(parsed.baseDirectoryPath);\n } catch {\n return [];\n }\n\n const filtered = entries\n .filter((entry) => (effectiveIncludeHidden ? true : !entry.name.startsWith(\".\")))\n .filter((entry) => entry.name.startsWith(parsed.fragment))\n .filter((entry) => {\n if (targetKind === \"directory\") {\n return entry.isDirectory;\n }\n if (targetKind === \"file\") {\n return entry.isFile;\n }\n return true;\n })\n .filter((entry) => {\n if (!extensionFilter || !entry.isFile) {\n return true;\n }\n\n return extensionFilter.has(extname(entry.name).toLowerCase());\n })\n .sort(compareSuggestionEntries)\n .slice(0, maxSuggestions);\n\n return filtered.map((entry) => {\n const suffix = entry.isDirectory ? \"/\" : \"\";\n const label = `${entry.name}${suffix}`;\n const replacement = `${parsed.directoryInput}${entry.name}${suffix}`;\n const absolutePath = resolve(parsed.baseDirectoryPath, entry.name);\n\n return {\n kind: entry.isDirectory ? \"directory\" : \"file\",\n name: entry.name,\n label,\n replacement,\n absolutePath,\n };\n });\n}\n","import {\n parsePathSuggestionInput,\n resolvePathSuggestions,\n type PathSuggestionTargetKind,\n} from \"./path-suggestions\";\n\nexport interface SiblingPreviewCandidateSet {\n scopeKey: string;\n replacements: string[];\n}\n\nexport interface ResolveSiblingPreviewCandidatesOptions {\n cwd: string;\n input: string;\n includeHidden?: boolean;\n maxSuggestions?: number;\n targetKind?: PathSuggestionTargetKind;\n fileExtensions?: string[];\n}\n\nfunction normalizeScopeExtensions(extensions: string[] | undefined): string {\n if (!extensions || extensions.length === 0) {\n return \"\";\n }\n\n return extensions\n .map((value) => value.trim().toLowerCase())\n .filter((value) => value.length > 0)\n .sort()\n .join(\",\");\n}\n\nexport function deriveSiblingPreviewScopeKey(\n options: ResolveSiblingPreviewCandidatesOptions,\n): string {\n const parsed = parsePathSuggestionInput(options.cwd, options.input);\n const hiddenMode =\n (options.includeHidden ?? false) || parsed.fragment.startsWith(\".\") ? \"include\" : \"exclude\";\n\n return [\n parsed.baseDirectoryPath,\n parsed.directoryInput,\n parsed.fragment,\n hiddenMode,\n options.targetKind ?? \"any\",\n normalizeScopeExtensions(options.fileExtensions),\n ].join(\"\\u0000\");\n}\n\nexport async function resolveSiblingPreviewCandidates(\n options: ResolveSiblingPreviewCandidatesOptions,\n): Promise<SiblingPreviewCandidateSet> {\n const suggestions = await resolvePathSuggestions({\n cwd: options.cwd,\n input: options.input,\n includeHidden: options.includeHidden,\n maxSuggestions: options.maxSuggestions,\n targetKind: options.targetKind,\n fileExtensions: options.fileExtensions,\n minChars: 0,\n enforceTrigger: false,\n });\n\n const replacements = Array.from(new Set(suggestions.map((item) => item.replacement)));\n\n return {\n scopeKey: deriveSiblingPreviewScopeKey(options),\n replacements,\n };\n}\n","import {\n beep,\n clearCurrentLine,\n createKeypressParser,\n dim,\n moveCursorLeft,\n startRawSession,\n supportsRawSessionIO,\n type RawSession,\n type RawSessionKeypressInfo,\n} from \"../tui\";\nimport type { PathPromptRuntimeConfig } from \"./path-config\";\nimport {\n advanceSiblingPreview,\n acceptSiblingPreview,\n clearInteractionState,\n deriveGhostSuffixFromPreview,\n derivePreferredGhostSuffix,\n setCycleState,\n type SiblingPreviewDirection,\n type InlinePromptInteractionState,\n} from \"./path-inline-state\";\nimport {\n deriveSiblingPreviewScopeKey,\n resolveSiblingPreviewCandidates,\n} from \"./path-sibling-preview\";\nimport {\n resolvePathSuggestions,\n type PathSuggestion,\n type ResolvePathSuggestionsOptions,\n} from \"./path-suggestions\";\n\ntype ValidationFn = (value: string) => true | string | Promise<true | string>;\n\ntype SuggestionFilter =\n | { targetKind: \"any\" | \"directory\"; fileExtensions?: string[] }\n | { targetKind: \"any\" | \"directory\"; fileExtensions?: undefined };\n\nexport interface InlinePathPromptOptions {\n message: string;\n cwd: string;\n kindLabel?: string;\n optional?: boolean;\n defaultHint?: string;\n defaultHintLabel?: string;\n runtimeConfig: PathPromptRuntimeConfig;\n stdin: NodeJS.ReadStream;\n stdout: NodeJS.WritableStream;\n validate: ValidationFn;\n suggestionFilter: SuggestionFilter;\n resolveSuggestions?: (options: ResolvePathSuggestionsOptions) => Promise<PathSuggestion[]>;\n}\n\ntype KeypressInfo = RawSessionKeypressInfo;\n\nfunction createPromptAbortError(): Error {\n const error = new Error(\"User aborted prompt\");\n error.name = \"ExitPromptError\";\n return error;\n}\n\nfunction buildPromptLine(options: {\n message: string;\n value: string;\n ghostSuffix: string;\n showGhost: boolean;\n}): { line: string; cursorBackCount: number } {\n const ghostText = options.showGhost ? options.ghostSuffix : \"\";\n const renderedGhost = ghostText.length > 0 ? dim(ghostText) : \"\";\n const line = `${options.message} ${options.value}${renderedGhost}`;\n return {\n line,\n cursorBackCount: ghostText.length,\n };\n}\n\nfunction isPrintableInput(str: string | undefined, key: KeypressInfo): boolean {\n if (typeof str !== \"string\") {\n return false;\n }\n if (str.length === 0) {\n return false;\n }\n if (key.ctrl || key.meta) {\n return false;\n }\n return key.name !== \"return\" && key.name !== \"enter\" && key.name !== \"tab\";\n}\n\nfunction findLastPathSeparatorIndex(value: string): number {\n return Math.max(value.lastIndexOf(\"/\"), value.lastIndexOf(\"\\\\\"));\n}\n\nfunction moveToParentPathSegmentValue(value: string): string | undefined {\n if (value.length === 0) {\n return undefined;\n }\n\n let end = value.length;\n while (end > 0 && (value[end - 1] === \"/\" || value[end - 1] === \"\\\\\")) {\n end -= 1;\n }\n\n if (end === 0) {\n return undefined;\n }\n\n const trimmed = value.slice(0, end);\n const lastSeparatorIndex = findLastPathSeparatorIndex(trimmed);\n if (lastSeparatorIndex < 0) {\n return \"\";\n }\n\n return value.slice(0, lastSeparatorIndex + 1);\n}\n\nexport async function promptPathInlineGhost(\n options: InlinePathPromptOptions,\n): Promise<string> {\n if (!supportsRawSessionIO(options.stdin, options.stdout)) {\n throw new Error(\"Inline path prompt requires TTY stdin/stdout with raw mode support\");\n }\n\n const stdout = options.stdout;\n const resolveSuggestions = options.resolveSuggestions ?? resolvePathSuggestions;\n\n let value = \"\";\n let ghostSuffix = \"\";\n let interactionState: InlinePromptInteractionState = clearInteractionState();\n let renderScheduled = false;\n let resolvingSuggestions = false;\n let needsRefreshAgain = false;\n let activeRefreshSeq = 0;\n let closed = false;\n\n const render = (): void => {\n if (closed) {\n return;\n }\n clearCurrentLine(stdout);\n const { line, cursorBackCount } = buildPromptLine({\n message: options.message,\n value,\n ghostSuffix,\n showGhost: true,\n });\n stdout.write(line);\n moveCursorLeft(stdout, cursorBackCount);\n };\n\n const scheduleRender = (): void => {\n if (closed) {\n return;\n }\n if (renderScheduled) {\n return;\n }\n renderScheduled = true;\n queueMicrotask(() => {\n renderScheduled = false;\n render();\n });\n };\n\n const computeGhostSuffix = async (): Promise<void> => {\n if (closed) {\n return;\n }\n const refreshSeq = ++activeRefreshSeq;\n const previewGhostSuffix = derivePreferredGhostSuffix({\n value,\n state: interactionState,\n });\n if (previewGhostSuffix.length > 0) {\n ghostSuffix = previewGhostSuffix;\n return;\n }\n\n const suggestions = await resolveSuggestions({\n cwd: options.cwd,\n input: value,\n minChars: options.runtimeConfig.autocomplete.minChars,\n maxSuggestions: options.runtimeConfig.autocomplete.maxSuggestions,\n includeHidden: options.runtimeConfig.autocomplete.includeHidden,\n targetKind: options.suggestionFilter.targetKind,\n fileExtensions: options.suggestionFilter.fileExtensions,\n });\n\n if (closed || refreshSeq !== activeRefreshSeq) {\n return;\n }\n\n ghostSuffix = derivePreferredGhostSuffix({\n value,\n state: interactionState,\n fallbackReplacement: suggestions[0]?.replacement,\n });\n };\n\n const refreshGhost = async (): Promise<void> => {\n if (closed) {\n return;\n }\n if (resolvingSuggestions) {\n needsRefreshAgain = true;\n return;\n }\n\n resolvingSuggestions = true;\n try {\n await computeGhostSuffix();\n } finally {\n resolvingSuggestions = false;\n }\n\n if (closed) {\n return;\n }\n\n scheduleRender();\n if (needsRefreshAgain) {\n needsRefreshAgain = false;\n void refreshGhost();\n }\n };\n\n const startOrAdvanceCycle = async (): Promise<boolean> => {\n const cycleState = interactionState.cycleState;\n if (cycleState && cycleState.replacements.length > 0) {\n const nextIndex = (cycleState.index + 1) % cycleState.replacements.length;\n interactionState = setCycleState(interactionState, {\n ...cycleState,\n index: nextIndex,\n });\n value = cycleState.replacements[nextIndex] ?? value;\n ghostSuffix = \"\";\n scheduleRender();\n return true;\n }\n\n const suggestions = await resolveSuggestions({\n cwd: options.cwd,\n input: value,\n minChars: options.runtimeConfig.autocomplete.minChars,\n maxSuggestions: options.runtimeConfig.autocomplete.maxSuggestions,\n includeHidden: options.runtimeConfig.autocomplete.includeHidden,\n targetKind: options.suggestionFilter.targetKind,\n fileExtensions: options.suggestionFilter.fileExtensions,\n });\n\n const replacements = suggestions.map((item) => item.replacement);\n if (replacements.length === 0) {\n return false;\n }\n\n const deduped: string[] = [];\n for (const replacement of replacements) {\n if (!deduped.includes(replacement)) {\n deduped.push(replacement);\n }\n }\n\n if (deduped.length === 0) {\n return false;\n }\n\n interactionState = setCycleState(interactionState, {\n replacements: deduped,\n index: 0,\n });\n value = deduped[0] ?? value;\n ghostSuffix = \"\";\n scheduleRender();\n return true;\n };\n\n const resetInteractionState = (): void => {\n interactionState = clearInteractionState();\n };\n\n const acceptGhostSuffix = async (): Promise<boolean> => {\n const previewAccepted = await acceptActiveSiblingPreview();\n if (previewAccepted) {\n return true;\n }\n\n if (ghostSuffix.length === 0) {\n return false;\n }\n\n value += ghostSuffix;\n ghostSuffix = \"\";\n resetInteractionState();\n await refreshGhost();\n return true;\n };\n\n const acceptActiveSiblingPreview = async (): Promise<boolean> => {\n const siblingPreviewAcceptance = acceptSiblingPreview(value, interactionState);\n if (siblingPreviewAcceptance.accepted) {\n value = siblingPreviewAcceptance.nextValue;\n interactionState = siblingPreviewAcceptance.nextState;\n ghostSuffix = \"\";\n await refreshGhost();\n return true;\n }\n\n return false;\n };\n\n const moveToParentPathSegment = async (): Promise<boolean> => {\n const nextValue = moveToParentPathSegmentValue(value);\n if (nextValue == null || nextValue === value) {\n return false;\n }\n\n value = nextValue;\n ghostSuffix = \"\";\n resetInteractionState();\n await refreshGhost();\n return true;\n };\n\n const browseSiblingPreview = async (direction: SiblingPreviewDirection): Promise<boolean> => {\n const scopeKey = deriveSiblingPreviewScopeKey({\n cwd: options.cwd,\n input: value,\n includeHidden: options.runtimeConfig.autocomplete.includeHidden,\n maxSuggestions: options.runtimeConfig.autocomplete.maxSuggestions,\n targetKind: options.suggestionFilter.targetKind,\n fileExtensions: options.suggestionFilter.fileExtensions,\n });\n\n const cachedPreviewState = interactionState.siblingPreviewState;\n const candidates =\n cachedPreviewState?.scopeKey === scopeKey\n ? {\n scopeKey: cachedPreviewState.scopeKey,\n replacements: cachedPreviewState.replacements,\n }\n : await resolveSiblingPreviewCandidates({\n cwd: options.cwd,\n input: value,\n includeHidden: options.runtimeConfig.autocomplete.includeHidden,\n maxSuggestions: options.runtimeConfig.autocomplete.maxSuggestions,\n targetKind: options.suggestionFilter.targetKind,\n fileExtensions: options.suggestionFilter.fileExtensions,\n });\n\n const previewAdvance = advanceSiblingPreview(interactionState, candidates, direction);\n interactionState = previewAdvance.nextState;\n\n if (!previewAdvance.changed) {\n ghostSuffix = \"\";\n return false;\n }\n\n ghostSuffix = deriveGhostSuffixFromPreview(value, previewAdvance.previewReplacement);\n scheduleRender();\n return true;\n };\n\n await refreshGhost();\n scheduleRender();\n\n return await new Promise<string>((resolve, reject) => {\n let settled = false;\n let session: RawSession | undefined;\n const keyParser = createKeypressParser({\n onEscapeAbort: () => {\n settleReject(createPromptAbortError());\n },\n });\n\n const settleResolve = (result: string): void => {\n if (settled) {\n return;\n }\n settled = true;\n closed = true;\n activeRefreshSeq += 1;\n cleanup();\n clearCurrentLine(stdout);\n stdout.write(`${options.message} ${result}\\n`);\n resolve(result);\n };\n\n const settleReject = (error: unknown): void => {\n if (settled) {\n return;\n }\n settled = true;\n closed = true;\n activeRefreshSeq += 1;\n cleanup();\n clearCurrentLine(stdout);\n stdout.write(\"\\n\");\n reject(error);\n };\n\n const keypressHandler = (str: string, key: KeypressInfo = {}): void => {\n void (async () => {\n const parsed = keyParser.handle(str, key);\n\n if (parsed.kind === \"incomplete\") {\n return;\n }\n\n if (parsed.kind === \"arrow\") {\n if (parsed.direction === \"right\") {\n const accepted = await acceptGhostSuffix();\n if (!accepted) {\n beep(stdout);\n scheduleRender();\n }\n return;\n }\n\n if (parsed.direction === \"left\") {\n const moved = await moveToParentPathSegment();\n if (!moved) {\n beep(stdout);\n scheduleRender();\n }\n return;\n }\n\n const navigated = await browseSiblingPreview(\n parsed.direction === \"up\" ? \"previous\" : \"next\",\n );\n if (!navigated) {\n beep(stdout);\n scheduleRender();\n }\n return;\n }\n\n const nextStr = parsed.str;\n const nextKey = parsed.key;\n\n if (nextKey.ctrl && nextKey.name === \"c\") {\n settleReject(createPromptAbortError());\n return;\n }\n\n if (nextKey.name === \"return\" || nextKey.name === \"enter\") {\n const validation = await options.validate(value);\n if (validation === true) {\n settleResolve(value);\n return;\n }\n beep(stdout);\n scheduleRender();\n return;\n }\n\n if (nextKey.name === \"tab\") {\n const acceptedPreview = await acceptActiveSiblingPreview();\n if (acceptedPreview) {\n return;\n }\n\n const cycled = await startOrAdvanceCycle();\n if (!cycled) {\n beep(stdout);\n scheduleRender();\n }\n return;\n }\n\n if (nextKey.ctrl && nextKey.name === \"u\") {\n value = \"\";\n ghostSuffix = \"\";\n resetInteractionState();\n await refreshGhost();\n return;\n }\n\n if (nextKey.name === \"backspace\") {\n if (value.length === 0) {\n beep(stdout);\n scheduleRender();\n return;\n }\n value = value.slice(0, -1);\n ghostSuffix = \"\";\n resetInteractionState();\n await refreshGhost();\n return;\n }\n\n if (isPrintableInput(nextStr, nextKey)) {\n value += nextStr;\n ghostSuffix = \"\";\n resetInteractionState();\n await refreshGhost();\n return;\n }\n\n // Ignore unsupported keys for MVP (arrows/home/end/etc.).\n scheduleRender();\n })().catch((error) => {\n settleReject(error);\n });\n };\n\n const cleanup = (): void => {\n session?.close();\n };\n\n try {\n if (options.defaultHint && options.defaultHint.trim().length > 0) {\n const label = options.defaultHintLabel?.trim() || \"Default path\";\n stdout.write(`${dim(`${label}: ${options.defaultHint}`)}\\n`);\n }\n session = startRawSession({\n stdin: options.stdin,\n stdout,\n onTeardown: () => {\n keyParser.dispose();\n },\n });\n session.addKeypressListener(keypressHandler);\n } catch (error) {\n settleReject(error);\n }\n });\n}\n","import { input, select } from \"@inquirer/prompts\";\n\nimport { defaultOutputPath, formatPathForDisplay, resolveFromCwd } from \"../fs-utils\";\nimport type { CliRuntime } from \"../types\";\nimport type { PathPromptRuntimeConfig } from \"./path-config\";\nimport { promptPathInlineGhost } from \"./path-inline\";\n\nexport type PathPromptKind = \"path\" | \"file\" | \"directory\" | \"csv\";\n\nexport interface PromptPathOptions {\n message: string;\n kind?: PathPromptKind;\n optional?: boolean;\n defaultValue?: string;\n defaultHint?: string;\n runtimeConfig?: PathPromptRuntimeConfig;\n cwd?: string;\n stdin?: NodeJS.ReadStream;\n stdout?: NodeJS.WritableStream;\n promptImpls?: {\n simpleInput?: typeof input;\n advancedInline?: typeof promptPathInlineGhost;\n };\n}\n\nfunction formatPromptMessage(options: PromptPathOptions): string {\n if (options.defaultHint && options.defaultHint.trim().length > 0) {\n return `${options.message} (optional, default: ${options.defaultHint})`;\n }\n\n return options.message;\n}\n\nfunction formatInlinePromptMessage(options: PromptPathOptions): string {\n if ((options.optional ?? false) && options.defaultHint && options.defaultHint.trim().length > 0) {\n return `${options.message} (custom)`;\n }\n\n if (options.optional ?? false) {\n return `${options.message} (optional)`;\n }\n\n return options.message;\n}\n\nfunction formatInlineDefaultHintLabel(options: PromptPathOptions): string | undefined {\n if (!options.defaultHint || options.defaultHint.trim().length === 0) {\n return undefined;\n }\n\n return `${options.message} default (Enter to use)`;\n}\n\nfunction buildPathValidator(options: PromptPathOptions): (value: string) => true | string {\n return (value) => {\n if (options.optional ?? false) {\n return true;\n }\n return value.trim().length > 0 ? true : \"Required\";\n };\n}\n\nexport async function promptPath(options: PromptPathOptions): Promise<string> {\n if (shouldUseAdvancedPathPrompt(options)) {\n return await promptPathAdvanced(options);\n }\n\n return await promptPathSimple(options);\n}\n\nfunction shouldUseAdvancedPathPrompt(options: PromptPathOptions): boolean {\n if (!options.runtimeConfig) {\n return false;\n }\n\n if (options.runtimeConfig.mode === \"simple\") {\n return false;\n }\n\n if (!options.runtimeConfig.autocomplete.enabled) {\n return false;\n }\n\n const hasCwd = typeof options.cwd === \"string\" && options.cwd.length > 0;\n const stdoutWithTTY = options.stdout as (NodeJS.WritableStream & { isTTY?: boolean }) | undefined;\n const hasTTYStreams = Boolean(options.stdin?.isTTY && stdoutWithTTY?.isTTY);\n return hasCwd && hasTTYStreams;\n}\n\nfunction isPromptCancelError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const name = error.name.toLowerCase();\n const message = error.message.toLowerCase();\n return (\n name.includes(\"exitprompt\") ||\n name.includes(\"abort\") ||\n message.includes(\"force closed\") ||\n message.includes(\"user aborted\")\n );\n}\n\nfunction pathKindToSuggestionFilter(\n kind: PathPromptKind | undefined,\n): { targetKind: \"any\" | \"directory\"; fileExtensions?: string[] } {\n if (kind === \"directory\") {\n return { targetKind: \"directory\" };\n }\n\n if (kind === \"csv\") {\n return { targetKind: \"any\", fileExtensions: [\"csv\"] };\n }\n\n return { targetKind: \"any\" };\n}\n\nasync function promptPathAdvanced(options: PromptPathOptions): Promise<string> {\n try {\n const filter = pathKindToSuggestionFilter(options.kind);\n const advancedInline = options.promptImpls?.advancedInline ?? promptPathInlineGhost;\n return await advancedInline({\n message: formatInlinePromptMessage(options),\n cwd: options.cwd!,\n optional: options.optional,\n defaultHint: options.defaultHint,\n defaultHintLabel: formatInlineDefaultHintLabel(options),\n runtimeConfig: options.runtimeConfig!,\n stdin: options.stdin!,\n stdout: options.stdout!,\n validate: buildPathValidator(options),\n suggestionFilter: filter,\n });\n } catch (error) {\n if (isPromptCancelError(error)) {\n throw error;\n }\n\n return await promptPathSimple(options);\n }\n}\n\nasync function promptPathSimple(options: PromptPathOptions): Promise<string> {\n const simpleInput = options.promptImpls?.simpleInput ?? input;\n return await simpleInput({\n message: formatPromptMessage(options),\n default: options.defaultValue,\n validate: buildPathValidator(options),\n });\n}\n\nexport async function promptRequiredPath(message: string, kind: PathPromptKind = \"path\"): Promise<string> {\n return await promptPath({ message, kind });\n}\n\nexport async function promptOptionalPathWithHint(options: {\n message: string;\n defaultHint: string;\n kind?: PathPromptKind;\n runtimeConfig?: PathPromptRuntimeConfig;\n cwd?: string;\n stdin?: NodeJS.ReadStream;\n stdout?: NodeJS.WritableStream;\n}): Promise<string | undefined> {\n const value = await promptPath({\n message: options.message,\n kind: options.kind ?? \"path\",\n optional: true,\n defaultHint: options.defaultHint,\n runtimeConfig: options.runtimeConfig,\n cwd: options.cwd,\n stdin: options.stdin,\n stdout: options.stdout,\n });\n\n return value.trim().length > 0 ? value : undefined;\n}\n\nexport async function promptOptionalOutputPathChoice(options: {\n message: string;\n defaultHint: string;\n kind?: PathPromptKind;\n runtimeConfig?: PathPromptRuntimeConfig;\n cwd?: string;\n stdin?: NodeJS.ReadStream;\n stdout?: NodeJS.WritableStream;\n customMessage?: string;\n}): Promise<string | undefined> {\n const choice = await select<\"default\" | \"custom\">({\n message: `${options.message} destination`,\n choices: [\n {\n name: \"Use default output\",\n value: \"default\",\n description: options.defaultHint,\n },\n {\n name: \"Custom output path\",\n value: \"custom\",\n description: \"Type a custom path with inline completion\",\n },\n ],\n });\n\n if (choice === \"default\") {\n return undefined;\n }\n\n return await promptRequiredPathWithConfig(options.customMessage ?? \"Custom output path\", {\n kind: options.kind ?? \"file\",\n runtimeConfig: options.runtimeConfig,\n cwd: options.cwd,\n stdin: options.stdin,\n stdout: options.stdout,\n });\n}\n\nexport async function promptRequiredPathWithConfig(\n message: string,\n options: {\n kind?: PathPromptKind;\n runtimeConfig?: PathPromptRuntimeConfig;\n cwd?: string;\n stdin?: NodeJS.ReadStream;\n stdout?: NodeJS.WritableStream;\n } = {},\n): Promise<string> {\n return await promptPath({\n message,\n kind: options.kind ?? \"path\",\n runtimeConfig: options.runtimeConfig,\n cwd: options.cwd,\n stdin: options.stdin,\n stdout: options.stdout,\n });\n}\n\nexport function formatDefaultOutputPathHint(\n runtime: CliRuntime,\n inputPath: string,\n nextExtension: string,\n): string {\n const derived = defaultOutputPath(inputPath, nextExtension);\n return formatPathForDisplay(runtime, resolveFromCwd(runtime, derived));\n}\n","import { stat } from \"node:fs/promises\";\nimport { extname } from \"node:path\";\n\nimport { confirm, editor, input, select } from \"@inquirer/prompts\";\n\nimport { actionDataQuery, type DataQueryOptions } from \"../actions\";\nimport { printLine, displayPath } from \"../actions/shared\";\nimport { getCliColors } from \"../colors\";\nimport {\n buildDataQueryCodexIntentEditorTemplate,\n draftDataQueryWithCodex,\n normalizeDataQueryCodexEditorIntent,\n normalizeDataQueryCodexIntent,\n} from \"../data-query/codex\";\nimport {\n DATA_QUERY_INPUT_FORMAT_VALUES,\n collectDataQuerySourceIntrospection,\n createDuckDbConnection,\n detectDataQueryInputFormat,\n listDataQuerySources,\n quoteSqlIdentifier,\n type DataQueryInputFormat,\n type DataQuerySourceIntrospection,\n} from \"../duckdb/query\";\nimport { createDuckDbExtensionInstallCommand } from \"../duckdb/extensions\";\nimport { CliError } from \"../errors\";\nimport { resolveFromCwd } from \"../fs-utils\";\nimport { createInteractiveAnalyzerStatus } from \"./analyzer-status\";\nimport type { InteractivePathPromptContext } from \"./shared\";\nimport { promptRequiredPathWithConfig } from \"../prompts/path\";\nimport type { CliRuntime } from \"../types\";\n\nconst DATA_QUERY_INTERACTIVE_SAMPLE_ROWS = 5;\n\ntype DataQueryInteractiveMode = \"manual\" | \"formal-guide\" | \"Codex Assistant\";\ntype OutputPromptSelection = Pick<DataQueryOptions, \"json\" | \"output\" | \"overwrite\" | \"pretty\" | \"rows\">;\ntype FormalGuideFilterOperator = \"=\" | \"!=\" | \">\" | \">=\" | \"<\" | \"<=\" | \"contains\";\ntype FormalGuideAggregateKind = \"none\" | \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n\ninterface FormalGuideFilter {\n column: string;\n operator: FormalGuideFilterOperator;\n value: string;\n}\n\ninterface FormalGuideAnswers {\n aggregateColumn?: string;\n aggregateKind: FormalGuideAggregateKind;\n filters: FormalGuideFilter[];\n groupByColumns: string[];\n orderBySpecs: OrderBySpec[];\n selectAllColumns: boolean;\n selectedColumns: string[];\n}\n\ninterface OrderBySpec {\n column: string;\n direction: \"asc\" | \"desc\";\n}\n\nfunction isDataQuerySqlExecutionError(error: unknown): boolean {\n return (\n error instanceof CliError &&\n (error.code === \"DATA_QUERY_FAILED\" ||\n (error.code === \"INVALID_INPUT\" &&\n /data query requires a sql statement that returns rows/i.test(error.message)))\n );\n}\n\nfunction isOutputExistsError(error: unknown): boolean {\n return (\n error instanceof CliError ||\n (typeof error === \"object\" && error !== null && \"code\" in error)\n )\n ? (error as { code?: unknown }).code === \"OUTPUT_EXISTS\"\n : false;\n}\n\nfunction isDuckDbExtensionUnavailableError(error: unknown): error is CliError | { code: string } {\n return (\n (error instanceof CliError && error.code === \"DUCKDB_EXTENSION_UNAVAILABLE\") ||\n (typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"DUCKDB_EXTENSION_UNAVAILABLE\")\n );\n}\n\nfunction formatSupportsManagedDuckDbExtensionInstall(\n format: DataQueryInputFormat,\n): format is \"sqlite\" | \"excel\" {\n return format === \"sqlite\" || format === \"excel\";\n}\n\nfunction canSuggestManagedDuckDbExtensionInstall(\n error: Error | { code: string; message?: string },\n): boolean {\n const message = error instanceof Error ? error.message : String(error.message ?? \"\");\n return !/cannot install or cache it/i.test(message);\n}\n\nfunction renderDuckDbExtensionRemediationCommand(\n runtime: CliRuntime,\n format: \"sqlite\" | \"excel\",\n): void {\n printLine(runtime.stderr, \"\");\n printLine(\n runtime.stderr,\n `Install the missing DuckDB extension with: ${createDuckDbExtensionInstallCommand(format)}`,\n );\n}\n\nfunction escapeSqlString(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction parseCommaSeparatedColumns(value: string): string[] {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n}\n\nfunction validateKnownColumns(value: string, allowedColumns: readonly string[]): true | string {\n const columns = parseCommaSeparatedColumns(value);\n if (columns.length === 0) {\n return \"Enter one or more columns.\";\n }\n\n for (const column of columns) {\n if (!allowedColumns.includes(column)) {\n return `Unknown column: ${column}.`;\n }\n }\n\n return true;\n}\n\nfunction parseOrderBySpecs(value: string, allowedColumns: readonly string[]): OrderBySpec[] {\n const specs: OrderBySpec[] = [];\n for (const rawToken of value.split(\",\").map((item) => item.trim()).filter((item) => item.length > 0)) {\n const parts = rawToken.split(\":\").map((part) => part.trim());\n const column = parts[0] ?? \"\";\n if (!allowedColumns.includes(column)) {\n throw new Error(`Unknown order-by column: ${column}.`);\n }\n\n const directionValue = (parts[1] ?? \"asc\").toLowerCase();\n if (directionValue !== \"asc\" && directionValue !== \"desc\") {\n throw new Error(`Invalid order direction for ${column}: ${directionValue}. Use asc or desc.`);\n }\n\n specs.push({\n column,\n direction: directionValue,\n });\n }\n\n return specs;\n}\n\nfunction getFormalGuideOrderableColumns(\n knownColumns: readonly string[],\n answers: Pick<FormalGuideAnswers, \"aggregateKind\" | \"groupByColumns\">,\n): string[] {\n if (answers.aggregateKind === \"none\") {\n return [...knownColumns];\n }\n\n const aggregateAlias = answers.aggregateKind === \"count\" ? \"row_count\" : \"summary_value\";\n return [...new Set([...answers.groupByColumns, aggregateAlias])];\n}\n\nfunction buildFormalGuideSql(answers: FormalGuideAnswers): string {\n const statements: string[] = [];\n if (answers.aggregateKind === \"none\") {\n const selectClause = answers.selectAllColumns\n ? \"*\"\n : answers.selectedColumns.map((column) => quoteSqlIdentifier(column)).join(\", \");\n statements.push(`select ${selectClause}`);\n } else {\n const groupByClause = answers.groupByColumns.map((column) => quoteSqlIdentifier(column));\n const aggregateExpression =\n answers.aggregateKind === \"count\"\n ? \"count(*) as row_count\"\n : `${answers.aggregateKind}(${quoteSqlIdentifier(answers.aggregateColumn ?? \"\")}) as summary_value`;\n statements.push(`select ${[...groupByClause, aggregateExpression].join(\", \")}`);\n }\n\n statements.push(\"from file\");\n\n if (answers.filters.length > 0) {\n const whereClause = answers.filters\n .map((filter) => {\n const column = quoteSqlIdentifier(filter.column);\n const value = escapeSqlString(filter.value);\n if (filter.operator === \"contains\") {\n return `lower(cast(${column} as varchar)) like '%' || lower(${value}) || '%'`;\n }\n return `${column} ${filter.operator} ${value}`;\n })\n .join(\" and \");\n statements.push(`where ${whereClause}`);\n }\n\n if (answers.aggregateKind !== \"none\" && answers.groupByColumns.length > 0) {\n statements.push(`group by ${answers.groupByColumns.map((column) => quoteSqlIdentifier(column)).join(\", \")}`);\n }\n\n if (answers.orderBySpecs.length > 0) {\n statements.push(\n `order by ${answers.orderBySpecs\n .map((spec) => `${quoteSqlIdentifier(spec.column)} ${spec.direction}`)\n .join(\", \")}`,\n );\n }\n\n return statements.join(\"\\n\");\n}\n\nfunction renderIntrospectionSummary(\n runtime: CliRuntime,\n options: {\n format: DataQueryInputFormat;\n inputPath: string;\n introspection: DataQuerySourceIntrospection;\n },\n): void {\n const pc = getCliColors(runtime);\n const lines = [\n `${pc.bold(pc.cyan(\"Input\"))}: ${pc.white(displayPath(runtime, options.inputPath))}`,\n `${pc.bold(pc.cyan(\"Format\"))}: ${pc.white(options.format)}`,\n ...(options.introspection.selectedSource\n ? [`${pc.bold(pc.cyan(\"Source\"))}: ${pc.white(options.introspection.selectedSource)}`]\n : []),\n `${pc.bold(pc.cyan(\"Schema\"))}:`,\n ...(options.introspection.columns.length > 0\n ? options.introspection.columns.map((column) => `- ${pc.bold(column.name)}: ${pc.dim(column.type)}`)\n : [`- ${pc.dim(\"(no columns available)\")}`]),\n `${pc.bold(pc.cyan(\"Sample Rows\"))}:`,\n ...(options.introspection.sampleRows.length > 0\n ? options.introspection.sampleRows.map(\n (row, index) => `- ${pc.dim(`${index + 1}.`)} ${pc.white(JSON.stringify(row))}`,\n )\n : [`- ${pc.dim(\"(no sample rows available)\")}`]),\n ];\n\n for (const line of lines) {\n printLine(runtime.stderr, line);\n }\n}\n\nfunction renderCandidateSql(runtime: CliRuntime, sql: string): void {\n const pc = getCliColors(runtime);\n printLine(runtime.stderr, \"\");\n printLine(runtime.stderr, `${pc.bold(pc.green(\"SQL\"))}:`);\n printLine(runtime.stderr, pc.yellow(sql));\n}\n\nfunction renderCodexIntentPreview(runtime: CliRuntime, intent: string): void {\n const pc = getCliColors(runtime);\n printLine(runtime.stderr, \"\");\n printLine(runtime.stderr, `${pc.bold(pc.cyan(\"Intent\"))}: ${pc.white(intent)}`);\n}\n\nasync function promptInteractiveInputFormat(\n runtime: CliRuntime,\n inputPath: string,\n): Promise<DataQueryInputFormat> {\n let detected: DataQueryInputFormat | undefined;\n try {\n detected = detectDataQueryInputFormat(inputPath);\n } catch (error) {\n if (!(error instanceof CliError)) {\n throw error;\n }\n }\n\n if (!detected) {\n printLine(runtime.stdout, \"Automatic format detection could not determine the query input type.\");\n return await select<DataQueryInputFormat>({\n message: \"Input format\",\n choices: DATA_QUERY_INPUT_FORMAT_VALUES.map((format) => ({\n name: format,\n value: format,\n })),\n });\n }\n\n const useDetected = await confirm({\n message: `Use detected input format: ${detected}?`,\n default: true,\n });\n if (useDetected) {\n return detected;\n }\n\n return await select<DataQueryInputFormat>({\n message: \"Override input format\",\n choices: DATA_QUERY_INPUT_FORMAT_VALUES.map((format) => ({\n name: format,\n value: format,\n })),\n });\n}\n\nasync function promptOptionalSourceSelection(\n format: DataQueryInputFormat,\n sources: readonly string[] | undefined,\n): Promise<string | undefined> {\n if (!sources || sources.length === 0) {\n return undefined;\n }\n\n return await select<string>({\n message: format === \"sqlite\" ? \"Choose a SQLite source\" : \"Choose an Excel sheet\",\n choices: sources.map((source) => ({\n name: source,\n value: source,\n })),\n });\n}\n\nasync function promptOutputSelection(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n): Promise<OutputPromptSelection> {\n const selection = await select<\"table\" | \"json\" | \"file\">({\n message: \"Output mode\",\n choices: [\n {\n name: \"table\",\n value: \"table\",\n description: \"Bounded terminal table output\",\n },\n {\n name: \"json stdout\",\n value: \"json\",\n description: \"Write full JSON results to stdout\",\n },\n {\n name: \"file output\",\n value: \"file\",\n description: \"Write full results to a .json or .csv file\",\n },\n ],\n });\n\n if (selection === \"table\") {\n const rowsInput = await input({\n message: \"Rows to show (optional)\",\n default: \"\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return true;\n }\n const parsed = Number(trimmed);\n return Number.isInteger(parsed) && parsed > 0 ? true : \"Enter a positive integer.\";\n },\n });\n return {\n rows: rowsInput.trim().length > 0 ? Number(rowsInput) : undefined,\n };\n }\n\n if (selection === \"json\") {\n return {\n json: true,\n pretty: await confirm({ message: \"Pretty-print JSON?\", default: true }),\n };\n }\n\n let outputPath = \"\";\n let overwrite = false;\n while (true) {\n const nextPath = await promptRequiredPathWithConfig(\"Output file path\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const extension = extname(nextPath).toLowerCase();\n if (extension === \".json\" || extension === \".csv\") {\n outputPath = nextPath;\n const normalizedOutputPath = resolveFromCwd(runtime, outputPath);\n try {\n await stat(normalizedOutputPath);\n overwrite = await confirm({ message: \"Overwrite if exists?\", default: false });\n if (overwrite) {\n break;\n }\n printLine(runtime.stdout, \"Choose a different output file path.\");\n continue;\n } catch {\n overwrite = false;\n break;\n }\n }\n printLine(runtime.stdout, \"Output file must end with .json or .csv.\");\n }\n\n const pretty = extname(outputPath).toLowerCase() === \".json\"\n ? await confirm({ message: \"Pretty-print JSON?\", default: true })\n : undefined;\n\n return {\n output: outputPath,\n overwrite,\n pretty,\n };\n}\n\nasync function executeInteractiveCandidate(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n options: {\n format: DataQueryInputFormat;\n input: string;\n selectedSource?: string;\n sql: string;\n },\n): Promise<\"executed\" | \"revise\"> {\n renderCandidateSql(runtime, options.sql);\n const confirmed = await confirm({ message: \"Execute this SQL?\", default: true });\n if (!confirmed) {\n return \"revise\";\n }\n\n while (true) {\n const outputOptions = await promptOutputSelection(runtime, pathPromptContext);\n try {\n await actionDataQuery(runtime, {\n input: options.input,\n inputFormat: options.format,\n json: outputOptions.json,\n output: outputOptions.output,\n overwrite: outputOptions.overwrite,\n pretty: outputOptions.pretty,\n rows: outputOptions.rows,\n source: options.selectedSource,\n sql: options.sql,\n });\n return \"executed\";\n } catch (error) {\n if (isOutputExistsError(error)) {\n runtime.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n continue;\n }\n if (!isDataQuerySqlExecutionError(error)) {\n throw error;\n }\n runtime.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n return \"revise\";\n }\n }\n}\n\nasync function runManualInteractiveQuery(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n options: {\n format: DataQueryInputFormat;\n input: string;\n selectedSource?: string;\n },\n): Promise<void> {\n let lastSql = \"\";\n while (true) {\n const sql = await input({\n message: \"SQL query\",\n default: lastSql,\n validate: (value) => (value.trim().length > 0 ? true : \"Enter a SQL query.\"),\n });\n lastSql = sql.trim();\n const result = await executeInteractiveCandidate(runtime, pathPromptContext, {\n ...options,\n sql: lastSql,\n });\n if (result === \"executed\") {\n return;\n }\n }\n}\n\nasync function promptFormalGuideAnswers(\n introspection: DataQuerySourceIntrospection,\n): Promise<FormalGuideAnswers> {\n const knownColumns = introspection.columns.map((column) => column.name);\n const selectedColumnsInput = await input({\n message: \"Columns to select (`all` or comma-separated)\",\n default: \"all\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed || trimmed.toLowerCase() === \"all\") {\n return true;\n }\n return validateKnownColumns(trimmed, knownColumns);\n },\n });\n\n const filters: FormalGuideFilter[] = [];\n let addAnotherFilter = await confirm({ message: \"Add a filter?\", default: false });\n while (addAnotherFilter) {\n const column = await select<string>({\n message: \"Filter column\",\n choices: knownColumns.map((name) => ({ name, value: name })),\n });\n const operator = await select<FormalGuideFilterOperator>({\n message: \"Filter operator\",\n choices: [\n { name: \"=\", value: \"=\" },\n { name: \"!=\", value: \"!=\" },\n { name: \">\", value: \">\" },\n { name: \">=\", value: \">=\" },\n { name: \"<\", value: \"<\" },\n { name: \"<=\", value: \"<=\" },\n { name: \"contains\", value: \"contains\" },\n ],\n });\n const value = await input({\n message: \"Filter value\",\n validate: (nextValue) => (nextValue.trim().length > 0 ? true : \"Enter a filter value.\"),\n });\n filters.push({\n column,\n operator,\n value: value.trim(),\n });\n addAnotherFilter = await confirm({ message: \"Add another filter?\", default: false });\n }\n\n const aggregateKind = await select<FormalGuideAggregateKind>({\n message: \"Aggregate summary\",\n choices: [\n { name: \"none\", value: \"none\" },\n { name: \"count rows\", value: \"count\" },\n { name: \"sum column\", value: \"sum\" },\n { name: \"average column\", value: \"avg\" },\n { name: \"minimum column\", value: \"min\" },\n { name: \"maximum column\", value: \"max\" },\n ],\n });\n\n let aggregateColumn: string | undefined;\n let groupByColumns: string[] = [];\n if (aggregateKind !== \"none\") {\n if (aggregateKind !== \"count\") {\n aggregateColumn = await select<string>({\n message: \"Aggregate column\",\n choices: knownColumns.map((name) => ({ name, value: name })),\n });\n }\n\n const groupByInput = await input({\n message: \"Group by columns (comma-separated, optional)\",\n default: \"\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return true;\n }\n return validateKnownColumns(trimmed, knownColumns);\n },\n });\n groupByColumns = parseCommaSeparatedColumns(groupByInput);\n }\n\n const allowedOrderByColumns = getFormalGuideOrderableColumns(knownColumns, {\n aggregateKind,\n groupByColumns,\n });\n\n const orderByInput = await input({\n message: \"Order by (column[:asc|desc], comma-separated, optional)\",\n default: \"\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return true;\n }\n try {\n parseOrderBySpecs(trimmed, allowedOrderByColumns);\n return true;\n } catch (error) {\n return error instanceof Error ? error.message : String(error);\n }\n },\n });\n\n const selectedColumns = parseCommaSeparatedColumns(selectedColumnsInput);\n return {\n aggregateColumn,\n aggregateKind,\n filters,\n groupByColumns,\n orderBySpecs:\n orderByInput.trim().length > 0 ? parseOrderBySpecs(orderByInput, allowedOrderByColumns) : [],\n selectedColumns,\n selectAllColumns:\n selectedColumnsInput.trim().length === 0 || selectedColumnsInput.trim().toLowerCase() === \"all\",\n };\n}\n\nasync function runFormalGuideInteractiveQuery(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n options: {\n format: DataQueryInputFormat;\n input: string;\n introspection: DataQuerySourceIntrospection;\n selectedSource?: string;\n },\n): Promise<void> {\n while (true) {\n const answers = await promptFormalGuideAnswers(options.introspection);\n const sql = buildFormalGuideSql(answers);\n const result = await executeInteractiveCandidate(runtime, pathPromptContext, {\n format: options.format,\n input: options.input,\n selectedSource: options.selectedSource,\n sql,\n });\n if (result === \"executed\") {\n return;\n }\n }\n}\n\nasync function runCodexInteractiveQuery(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n options: {\n format: DataQueryInputFormat;\n input: string;\n introspection: DataQuerySourceIntrospection;\n selectedSource?: string;\n },\n): Promise<void> {\n let lastIntent = \"\";\n let preferMultilineEditor = false;\n\n while (true) {\n const useMultilineEditor = await confirm({\n message: \"Use multiline editor?\",\n default: preferMultilineEditor,\n });\n preferMultilineEditor = useMultilineEditor;\n const intent = useMultilineEditor\n ? await (async (): Promise<string> => {\n while (true) {\n const intentValue = await editor({\n default: buildDataQueryCodexIntentEditorTemplate({\n format: options.format,\n intent: lastIntent,\n introspection: options.introspection,\n }),\n message: \"Describe the query intent\",\n postfix: \".md\",\n validate: (value) =>\n normalizeDataQueryCodexEditorIntent(value).length > 0 ? true : \"Enter a query intent.\",\n });\n const cleanedIntent = normalizeDataQueryCodexEditorIntent(intentValue);\n renderCodexIntentPreview(runtime, cleanedIntent);\n const confirmed = await confirm({\n message: \"Send this intent to Codex drafting?\",\n default: true,\n });\n if (confirmed) {\n return cleanedIntent;\n }\n lastIntent = cleanedIntent;\n }\n })()\n : normalizeDataQueryCodexIntent(\n await input({\n default: lastIntent,\n message: \"Describe the query intent\",\n validate: (value) =>\n normalizeDataQueryCodexIntent(value).length > 0 ? true : \"Enter a query intent.\",\n }),\n );\n lastIntent = intent;\n\n while (true) {\n const statusStream = runtime.stdout as NodeJS.WritableStream & { isTTY?: boolean };\n const status = statusStream.isTTY\n ? createInteractiveAnalyzerStatus(runtime.stdout, runtime.colorEnabled)\n : {\n start() {},\n update() {},\n wait() {},\n stop() {},\n };\n\n try {\n status.wait(\"Drafting SQL with Codex\");\n const draftResult = await draftDataQueryWithCodex({\n format: options.format,\n intent,\n introspection: options.introspection,\n workingDirectory: runtime.cwd,\n });\n status.stop();\n\n if (!draftResult.draft) {\n printLine(runtime.stderr, `Codex drafting failed: ${draftResult.errorMessage ?? \"Unknown error.\"}`);\n } else {\n const executionResult = await executeInteractiveCandidate(runtime, pathPromptContext, {\n format: options.format,\n input: options.input,\n selectedSource: options.selectedSource,\n sql: draftResult.draft.sql,\n });\n if (executionResult === \"executed\") {\n return;\n }\n }\n } finally {\n status.stop();\n }\n\n const nextStep = await select<\"regenerate\" | \"revise\" | \"cancel\">({\n message: \"Codex Assistant next step\",\n choices: [\n { name: \"regenerate SQL\", value: \"regenerate\" },\n { name: \"revise intent\", value: \"revise\" },\n { name: \"cancel\", value: \"cancel\" },\n ],\n });\n if (nextStep === \"regenerate\") {\n continue;\n }\n if (nextStep === \"cancel\") {\n return;\n }\n break;\n }\n }\n}\n\nexport async function runInteractiveDataQuery(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n): Promise<void> {\n const input = await promptRequiredPathWithConfig(\"Input data file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const inputPath = resolveFromCwd(runtime, input);\n const format = await promptInteractiveInputFormat(runtime, inputPath);\n\n let connection;\n try {\n connection = await createDuckDbConnection();\n const sources = await listDataQuerySources(connection, inputPath, format);\n const selectedSource = await promptOptionalSourceSelection(format, sources);\n const introspection = await collectDataQuerySourceIntrospection(\n connection,\n inputPath,\n format,\n selectedSource,\n DATA_QUERY_INTERACTIVE_SAMPLE_ROWS,\n );\n renderIntrospectionSummary(runtime, {\n format,\n inputPath,\n introspection,\n });\n\n const mode = await select<DataQueryInteractiveMode>({\n message: \"Choose mode\",\n choices: [\n { name: \"manual\", value: \"manual\" },\n { name: \"formal-guide\", value: \"formal-guide\" },\n { name: \"Codex Assistant\", value: \"Codex Assistant\" },\n ],\n });\n\n if (mode === \"manual\") {\n await runManualInteractiveQuery(runtime, pathPromptContext, {\n format,\n input,\n selectedSource,\n });\n return;\n }\n\n if (mode === \"formal-guide\") {\n await runFormalGuideInteractiveQuery(runtime, pathPromptContext, {\n format,\n input,\n introspection,\n selectedSource,\n });\n return;\n }\n\n await runCodexInteractiveQuery(runtime, pathPromptContext, {\n format,\n input,\n introspection,\n selectedSource,\n });\n } catch (error) {\n if (\n isDuckDbExtensionUnavailableError(error) &&\n formatSupportsManagedDuckDbExtensionInstall(format) &&\n canSuggestManagedDuckDbExtensionInstall(error)\n ) {\n renderDuckDbExtensionRemediationCommand(runtime, format);\n }\n throw error;\n } finally {\n connection?.closeSync();\n }\n}\n","import type { PathPromptRuntimeConfig } from \"../prompts/path-config\";\nimport type { CliRuntime } from \"../types\";\n\nexport interface InteractivePathPromptContext {\n runtimeConfig: PathPromptRuntimeConfig;\n cwd: CliRuntime[\"cwd\"];\n stdin: CliRuntime[\"stdin\"];\n stdout: CliRuntime[\"stdout\"];\n}\n\nexport function assertNeverInteractiveAction(action: never): never {\n throw new Error(`Unhandled interactive action: ${String(action)}`);\n}\n","import { confirm, input } from \"@inquirer/prompts\";\n\nimport {\n actionCsvToJson,\n actionDataParquetPreview,\n actionDataPreview,\n actionJsonToCsv,\n loadDataPreviewSource,\n} from \"../actions\";\nimport {\n assertContainsFilterColumns,\n parseContainsFilterValue,\n type DataPreviewContainsFilter,\n type DataPreviewSource,\n} from \"../data-preview/source\";\nimport {\n formatDefaultOutputPathHint,\n promptOptionalOutputPathChoice,\n promptRequiredPathWithConfig,\n} from \"../prompts/path\";\nimport type { CliRuntime } from \"../types\";\nimport { runInteractiveDataQuery } from \"./data-query\";\nimport type { DataInteractiveActionKey } from \"./menu\";\nimport { assertNeverInteractiveAction, type InteractivePathPromptContext } from \"./shared\";\n\nfunction toContainsValidationMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nasync function promptContainsFilters(\n runtime: CliRuntime,\n inputPath: string,\n): Promise<string[] | undefined> {\n let sourcePromise: Promise<DataPreviewSource> | undefined;\n const getSource = async (): Promise<DataPreviewSource> => {\n sourcePromise ??= loadDataPreviewSource(runtime, inputPath).then((loaded) => loaded.source);\n return await sourcePromise;\n };\n\n const validateContains = async (\n value: string,\n options: { allowBlank: boolean },\n ): Promise<true | string> => {\n const trimmed = value.trim();\n if (!trimmed) {\n return options.allowBlank ? true : \"Enter a contains filter in column:keyword format.\";\n }\n\n let parsedFilter: DataPreviewContainsFilter;\n try {\n parsedFilter = parseContainsFilterValue(trimmed);\n } catch (error) {\n return toContainsValidationMessage(error);\n }\n\n try {\n assertContainsFilterColumns(await getSource(), [parsedFilter]);\n } catch (error) {\n return toContainsValidationMessage(error);\n }\n\n return true;\n };\n\n const firstContainsInput = await input({\n message: \"Contains filter (column:keyword, optional)\",\n default: \"\",\n validate: async (value) => await validateContains(value, { allowBlank: true }),\n });\n\n const contains = firstContainsInput.trim() ? [firstContainsInput.trim()] : [];\n while (contains.length > 0 && await confirm({ message: \"Add another contains filter?\", default: false })) {\n const nextContainsInput = await input({\n message: \"Another contains filter (column:keyword)\",\n default: \"\",\n validate: async (value) => await validateContains(value, { allowBlank: false }),\n });\n contains.push(nextContainsInput.trim());\n }\n\n return contains.length > 0 ? contains : undefined;\n}\n\nexport async function handleDataInteractiveAction(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n action: DataInteractiveActionKey,\n): Promise<void> {\n if (action === \"data:query\") {\n await runInteractiveDataQuery(runtime, pathPromptContext);\n return;\n }\n\n if (action === \"data:preview\") {\n const inputPath = await promptRequiredPathWithConfig(\"Input CSV or JSON file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const rowsInput = await input({\n message: \"Rows to show (optional)\",\n default: \"\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return true;\n }\n const parsed = Number(trimmed);\n return Number.isInteger(parsed) && parsed > 0 ? true : \"Enter a positive integer.\";\n },\n });\n const offsetInput = await input({\n message: \"Row offset (optional)\",\n default: \"\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return true;\n }\n const parsed = Number(trimmed);\n return Number.isInteger(parsed) && parsed >= 0 ? true : \"Enter a non-negative integer.\";\n },\n });\n const columnsInput = await input({\n message: \"Columns to show (comma-separated, optional)\",\n default: \"\",\n });\n const columns = columnsInput\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n const contains = await promptContainsFilters(runtime, inputPath);\n\n await actionDataPreview(runtime, {\n columns: columns.length > 0 ? columns : undefined,\n contains,\n input: inputPath,\n offset: offsetInput.trim() ? Number(offsetInput) : undefined,\n rows: rowsInput.trim() ? Number(rowsInput) : undefined,\n });\n return;\n }\n\n if (action === \"data:parquet-preview\") {\n const inputPath = await promptRequiredPathWithConfig(\"Input Parquet file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const rowsInput = await input({\n message: \"Rows to show (optional)\",\n default: \"\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return true;\n }\n const parsed = Number(trimmed);\n return Number.isInteger(parsed) && parsed > 0 ? true : \"Enter a positive integer.\";\n },\n });\n const offsetInput = await input({\n message: \"Row offset (optional)\",\n default: \"\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return true;\n }\n const parsed = Number(trimmed);\n return Number.isInteger(parsed) && parsed >= 0 ? true : \"Enter a non-negative integer.\";\n },\n });\n const columnsInput = await input({\n message: \"Columns to show (comma-separated, optional)\",\n default: \"\",\n });\n const columns = columnsInput\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n\n await actionDataParquetPreview(runtime, {\n columns: columns.length > 0 ? columns : undefined,\n input: inputPath,\n offset: offsetInput.trim() ? Number(offsetInput) : undefined,\n rows: rowsInput.trim() ? Number(rowsInput) : undefined,\n });\n return;\n }\n\n if (action === \"data:json-to-csv\") {\n const inputPath = await promptRequiredPathWithConfig(\"Input JSON file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const outputHint = formatDefaultOutputPathHint(runtime, inputPath, \".csv\");\n const outputPath = await promptOptionalOutputPathChoice({\n message: \"Output CSV file\",\n defaultHint: outputHint,\n kind: \"file\",\n ...pathPromptContext,\n customMessage: \"Custom CSV output path\",\n });\n const overwrite = await confirm({ message: \"Overwrite if exists?\", default: false });\n await actionJsonToCsv(runtime, { input: inputPath, output: outputPath, overwrite });\n return;\n }\n\n if (action !== \"data:csv-to-json\") {\n assertNeverInteractiveAction(action);\n }\n\n const inputPath = await promptRequiredPathWithConfig(\"Input CSV file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const outputHint = formatDefaultOutputPathHint(runtime, inputPath, \".json\");\n const outputPath = await promptOptionalOutputPathChoice({\n message: \"Output JSON file\",\n defaultHint: outputHint,\n kind: \"file\",\n ...pathPromptContext,\n customMessage: \"Custom JSON output path\",\n });\n const pretty = await confirm({ message: \"Pretty-print JSON?\", default: true });\n const overwrite = await confirm({ message: \"Overwrite if exists?\", default: false });\n await actionCsvToJson(runtime, {\n input: inputPath,\n output: outputPath,\n pretty,\n overwrite,\n });\n}\n","import { confirm, select } from \"@inquirer/prompts\";\n\nimport { actionMdFrontmatterToJson, actionMdToDocx } from \"../actions\";\nimport {\n formatDefaultOutputPathHint,\n promptOptionalOutputPathChoice,\n promptRequiredPathWithConfig,\n} from \"../prompts/path\";\nimport type { CliRuntime } from \"../types\";\nimport type { MarkdownInteractiveActionKey } from \"./menu\";\nimport { assertNeverInteractiveAction, type InteractivePathPromptContext } from \"./shared\";\n\nexport async function handleMarkdownInteractiveAction(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n action: MarkdownInteractiveActionKey,\n): Promise<void> {\n if (action === \"md:to-docx\") {\n const inputPath = await promptRequiredPathWithConfig(\"Input Markdown file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const outputHint = formatDefaultOutputPathHint(runtime, inputPath, \".docx\");\n const outputPath = await promptOptionalOutputPathChoice({\n message: \"Output DOCX file\",\n defaultHint: outputHint,\n kind: \"file\",\n ...pathPromptContext,\n customMessage: \"Custom DOCX output path\",\n });\n const overwrite = await confirm({ message: \"Overwrite if exists?\", default: false });\n await actionMdToDocx(runtime, {\n input: inputPath,\n output: outputPath,\n overwrite,\n });\n return;\n }\n\n if (action !== \"md:frontmatter-to-json\") {\n assertNeverInteractiveAction(action);\n }\n\n const inputPath = await promptRequiredPathWithConfig(\"Input Markdown file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const outputMode = await select<\"stdout\" | \"file\">({\n message: \"JSON output destination\",\n choices: [\n { name: \"Print to stdout (default)\", value: \"stdout\" },\n { name: \"Write to file\", value: \"file\" },\n ],\n });\n const outputShape = await select<\"wrapper\" | \"data-only\">({\n message: \"JSON output shape\",\n choices: [\n {\n name: \"Wrapper (default)\",\n value: \"wrapper\",\n description: \"{ frontmatterType, data }\",\n },\n {\n name: \"Data only\",\n value: \"data-only\",\n description: \"Only the parsed frontmatter object\",\n },\n ],\n });\n const pretty = await confirm({ message: \"Pretty-print JSON?\", default: true });\n\n let outputPath: string | undefined;\n let overwrite = false;\n if (outputMode === \"file\") {\n const outputHint = formatDefaultOutputPathHint(runtime, inputPath, \".frontmatter.json\");\n outputPath = await promptOptionalOutputPathChoice({\n message: \"Output JSON file\",\n defaultHint: outputHint,\n kind: \"file\",\n ...pathPromptContext,\n customMessage: \"Custom JSON output path\",\n });\n overwrite = await confirm({ message: \"Overwrite if exists?\", default: false });\n }\n\n await actionMdFrontmatterToJson(runtime, {\n input: inputPath,\n toStdout: outputMode === \"stdout\",\n output: outputPath,\n overwrite,\n pretty,\n dataOnly: outputShape === \"data-only\",\n });\n}\n","import { select } from \"@inquirer/prompts\";\n\nexport type InteractiveActionKey =\n | \"doctor\"\n | \"data:preview\"\n | \"data:query\"\n | \"data:parquet-preview\"\n | \"data:json-to-csv\"\n | \"data:csv-to-json\"\n | \"md:to-docx\"\n | \"md:frontmatter-to-json\"\n | \"rename:file\"\n | \"rename:batch\"\n | \"rename:cleanup\"\n | \"rename:apply\"\n | \"video:convert\"\n | \"video:resize\"\n | \"video:gif\";\n\nexport type DataInteractiveActionKey = Extract<InteractiveActionKey, `data:${string}`>;\nexport type MarkdownInteractiveActionKey = Extract<InteractiveActionKey, `md:${string}`>;\nexport type RenameInteractiveActionKey = Extract<InteractiveActionKey, `rename:${string}`>;\nexport type VideoInteractiveActionKey = Extract<InteractiveActionKey, `video:${string}`>;\n\ntype InteractiveRootChoice = \"doctor\" | \"data\" | \"md\" | \"rename\" | \"video\" | \"cancel\";\ntype InteractiveSubmenuGroup = Exclude<InteractiveRootChoice, \"doctor\" | \"cancel\">;\ntype InteractiveSubmenuChoice = InteractiveActionKey | \"back\" | \"cancel\";\n\ntype InteractiveMenuChoice<T extends string> = {\n name: string;\n value: T;\n description?: string;\n};\n\ntype InteractiveSubmenuConfig = {\n message: string;\n choices: Array<InteractiveMenuChoice<InteractiveActionKey>>;\n};\n\nconst INTERACTIVE_ROOT_CHOICES: Array<InteractiveMenuChoice<InteractiveRootChoice>> = [\n { name: \"doctor\", value: \"doctor\", description: \"Check dependencies and capabilities\" },\n { name: \"data\", value: \"data\", description: \"Preview and convert tabular data\" },\n { name: \"md\", value: \"md\", description: \"Markdown utilities\" },\n { name: \"rename\", value: \"rename\", description: \"File/batch rename workflows\" },\n { name: \"video\", value: \"video\", description: \"Video conversion tools\" },\n { name: \"cancel\", value: \"cancel\" },\n];\n\nconst INTERACTIVE_SUBMENUS: Record<InteractiveSubmenuGroup, InteractiveSubmenuConfig> = {\n data: {\n message: \"Choose a data command\",\n choices: [\n { name: \"preview\", value: \"data:preview\" },\n { name: \"query\", value: \"data:query\" },\n { name: \"parquet preview\", value: \"data:parquet-preview\" },\n { name: \"json-to-csv\", value: \"data:json-to-csv\" },\n { name: \"csv-to-json\", value: \"data:csv-to-json\" },\n ],\n },\n md: {\n message: \"Choose a markdown command\",\n choices: [\n { name: \"to-docx\", value: \"md:to-docx\" },\n { name: \"frontmatter-to-json\", value: \"md:frontmatter-to-json\" },\n ],\n },\n rename: {\n message: \"Choose a rename command\",\n choices: [\n { name: \"file\", value: \"rename:file\" },\n { name: \"batch\", value: \"rename:batch\" },\n { name: \"cleanup\", value: \"rename:cleanup\" },\n { name: \"apply\", value: \"rename:apply\" },\n ],\n },\n video: {\n message: \"Choose a video command\",\n choices: [\n { name: \"convert\", value: \"video:convert\" },\n { name: \"resize\", value: \"video:resize\" },\n { name: \"gif\", value: \"video:gif\" },\n ],\n },\n};\n\nexport async function selectInteractiveAction(): Promise<InteractiveActionKey | \"cancel\"> {\n while (true) {\n const rootChoice = await select<InteractiveRootChoice>({\n message: \"Choose a command\",\n choices: INTERACTIVE_ROOT_CHOICES,\n });\n\n if (rootChoice === \"cancel\") {\n return \"cancel\";\n }\n\n if (rootChoice === \"doctor\") {\n return \"doctor\";\n }\n\n const submenu = INTERACTIVE_SUBMENUS[rootChoice];\n const submenuChoice = await select<InteractiveSubmenuChoice>({\n message: submenu.message,\n choices: [\n ...submenu.choices,\n { name: \"Back\", value: \"back\", description: \"Return to the main command menu\" },\n { name: \"Cancel\", value: \"cancel\", description: \"Exit interactive mode\" },\n ],\n });\n\n if (submenuChoice === \"back\") {\n continue;\n }\n\n if (submenuChoice === \"cancel\") {\n return \"cancel\";\n }\n\n return submenuChoice;\n }\n}\n","export type TemplateCandidateScope = \"root\" | \"timestamp\" | \"date\";\n\nexport interface TemplateCompletionMatch {\n candidates: string[];\n fragment: string;\n fragmentStart: number;\n scope: TemplateCandidateScope;\n scopeKey: string;\n}\n\nconst ROOT_TEMPLATE_CANDIDATES = [\n \"{prefix}\",\n \"{timestamp}\",\n \"{date}\",\n \"{stem}\",\n \"{uid}\",\n \"{serial}\",\n] as const;\n\nconst TIMESTAMP_TEMPLATE_CANDIDATES = [\n \"{timestamp}\",\n \"{timestamp_local}\",\n \"{timestamp_utc}\",\n \"{timestamp_local_iso}\",\n \"{timestamp_utc_iso}\",\n \"{timestamp_local_12h}\",\n \"{timestamp_utc_12h}\",\n] as const;\n\nconst DATE_TEMPLATE_CANDIDATES = [\n \"{date}\",\n \"{date_local}\",\n \"{date_utc}\",\n] as const;\n\nfunction resolveTemplateCandidateScope(fragment: string): TemplateCandidateScope {\n if (fragment.startsWith(\"{timestamp\")) {\n return \"timestamp\";\n }\n if (fragment.startsWith(\"{date\")) {\n return \"date\";\n }\n return \"root\";\n}\n\nfunction getCandidatesForScope(scope: TemplateCandidateScope): readonly string[] {\n if (scope === \"timestamp\") {\n return TIMESTAMP_TEMPLATE_CANDIDATES;\n }\n if (scope === \"date\") {\n return DATE_TEMPLATE_CANDIDATES;\n }\n return ROOT_TEMPLATE_CANDIDATES;\n}\n\nexport function resolveTemplateCompletionMatch(value: string): TemplateCompletionMatch | undefined {\n const fragmentStart = value.lastIndexOf(\"{\");\n const lastClose = value.lastIndexOf(\"}\");\n if (fragmentStart < 0 || fragmentStart < lastClose) {\n return undefined;\n }\n\n const fragment = value.slice(fragmentStart);\n if (fragment.length === 0) {\n return undefined;\n }\n\n const scope = resolveTemplateCandidateScope(fragment);\n const candidates = getCandidatesForScope(scope).filter((candidate) => candidate.startsWith(fragment));\n if (candidates.length === 0) {\n return undefined;\n }\n\n return {\n candidates,\n fragment,\n fragmentStart,\n scope,\n scopeKey: `${scope}:${fragment}`,\n };\n}\n\nexport function deriveTemplateGhostSuffix(fragment: string, candidate: string): string {\n if (!candidate.startsWith(fragment)) {\n return \"\";\n }\n return candidate.slice(fragment.length);\n}\n","import { input } from \"@inquirer/prompts\";\n\nimport {\n beep,\n clearCurrentLine,\n createKeypressParser,\n dim,\n moveCursorLeft,\n startRawSession,\n supportsRawSessionIO,\n type RawSession,\n type RawSessionKeypressInfo,\n} from \"../tui\";\nimport type { PathPromptRuntimeConfig } from \"./path-config\";\nimport {\n deriveTemplateGhostSuffix,\n resolveTemplateCompletionMatch,\n type TemplateCompletionMatch,\n} from \"./text-template-candidates\";\n\ntype ValidationFn = (value: string) => true | string | Promise<true | string>;\n\nexport interface InlineTextPromptOptions {\n message: string;\n helpLines?: string[];\n ghostHintLabel?: string;\n ghostText: string;\n completionKind?: \"none\" | \"rename-template\";\n runtimeConfig?: PathPromptRuntimeConfig;\n stdin?: NodeJS.ReadStream;\n stdout?: NodeJS.WritableStream;\n validate: ValidationFn;\n promptImpls?: {\n simpleInput?: typeof input;\n advancedInline?: typeof promptTextInlineGhost;\n };\n}\n\ntype KeypressInfo = RawSessionKeypressInfo;\n\nfunction createPromptAbortError(): Error {\n const error = new Error(\"User aborted prompt\");\n error.name = \"ExitPromptError\";\n return error;\n}\n\nfunction buildPromptLine(options: {\n message: string;\n value: string;\n ghostText: string;\n}): { line: string; cursorBackCount: number } {\n const showGhost = options.ghostText.length > 0;\n const renderedGhost = showGhost ? dim(options.ghostText) : \"\";\n const line = `${options.message} ${options.value}${renderedGhost}`;\n return {\n line,\n cursorBackCount: showGhost ? options.ghostText.length : 0,\n };\n}\n\nfunction isPrintableInput(str: string | undefined, key: KeypressInfo): boolean {\n if (typeof str !== \"string\") {\n return false;\n }\n if (str.length === 0) {\n return false;\n }\n if (key.ctrl || key.meta) {\n return false;\n }\n return key.name !== \"return\" && key.name !== \"enter\" && key.name !== \"tab\";\n}\n\nfunction isPromptCancelError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const name = error.name.toLowerCase();\n const message = error.message.toLowerCase();\n return (\n name.includes(\"exitprompt\") ||\n name.includes(\"abort\") ||\n message.includes(\"force closed\") ||\n message.includes(\"user aborted\")\n );\n}\n\nfunction shouldUseAdvancedTextPrompt(options: InlineTextPromptOptions): boolean {\n if (!options.runtimeConfig) {\n return false;\n }\n\n if (options.runtimeConfig.mode === \"simple\") {\n return false;\n }\n\n const stdoutWithTTY = options.stdout as (NodeJS.WritableStream & { isTTY?: boolean }) | undefined;\n return Boolean(options.stdin?.isTTY && stdoutWithTTY?.isTTY);\n}\n\nexport async function promptTextWithGhost(options: InlineTextPromptOptions): Promise<string> {\n if (shouldUseAdvancedTextPrompt(options)) {\n try {\n const advancedInline = options.promptImpls?.advancedInline ?? promptTextInlineGhost;\n return await advancedInline({\n message: options.message,\n helpLines: options.helpLines,\n ghostHintLabel: options.ghostHintLabel,\n ghostText: options.ghostText,\n completionKind: options.completionKind,\n stdin: options.stdin!,\n stdout: options.stdout!,\n validate: options.validate,\n });\n } catch (error) {\n if (isPromptCancelError(error)) {\n throw error;\n }\n }\n }\n\n const simpleInput = options.promptImpls?.simpleInput ?? input;\n if (options.helpLines && options.helpLines.length > 0 && options.stdout) {\n options.stdout.write(`${options.helpLines.join(\"\\n\")}\\n`);\n }\n if (options.ghostHintLabel && options.ghostText.length > 0 && options.stdout) {\n options.stdout.write(`${dim(`${options.ghostHintLabel}: ${options.ghostText}`)}\\n`);\n }\n return await simpleInput({\n message: options.message,\n validate: options.validate,\n });\n}\n\nexport async function promptTextInlineGhost(options: {\n message: string;\n helpLines?: string[];\n ghostHintLabel?: string;\n ghostText: string;\n completionKind?: \"none\" | \"rename-template\";\n stdin: NodeJS.ReadStream;\n stdout: NodeJS.WritableStream;\n validate: ValidationFn;\n}): Promise<string> {\n if (!supportsRawSessionIO(options.stdin, options.stdout)) {\n throw new Error(\"Inline text prompt requires TTY stdin/stdout with raw mode support\");\n }\n\n const stdout = options.stdout;\n let value = \"\";\n let ghostText = \"\";\n let closed = false;\n let renderScheduled = false;\n let templateCompletion: TemplateCompletionMatch | undefined;\n let templateCycleState:\n | {\n index: number;\n scopeKey: string;\n }\n | undefined;\n\n const refreshGhostText = (): void => {\n templateCompletion = undefined;\n if (options.completionKind === \"rename-template\") {\n templateCompletion = resolveTemplateCompletionMatch(value);\n if (!templateCompletion) {\n ghostText = \"\";\n templateCycleState = undefined;\n return;\n }\n\n if (templateCycleState?.scopeKey !== templateCompletion.scopeKey) {\n templateCycleState = undefined;\n }\n\n const candidateIndex = templateCycleState?.index ?? 0;\n const candidate = templateCompletion.candidates[candidateIndex];\n ghostText =\n typeof candidate === \"string\"\n ? deriveTemplateGhostSuffix(templateCompletion.fragment, candidate)\n : \"\";\n return;\n }\n\n ghostText = value.length === 0 ? options.ghostText : \"\";\n };\n\n const render = (): void => {\n if (closed) {\n return;\n }\n clearCurrentLine(stdout);\n const { line, cursorBackCount } = buildPromptLine({\n message: options.message,\n value,\n ghostText,\n });\n stdout.write(line);\n moveCursorLeft(stdout, cursorBackCount);\n };\n\n const scheduleRender = (): void => {\n if (closed || renderScheduled) {\n return;\n }\n renderScheduled = true;\n queueMicrotask(() => {\n renderScheduled = false;\n render();\n });\n };\n\n if (options.helpLines && options.helpLines.length > 0) {\n stdout.write(`${options.helpLines.join(\"\\n\")}\\n`);\n }\n if (options.ghostHintLabel && options.ghostText.length > 0) {\n stdout.write(`${dim(`${options.ghostHintLabel}: ${options.ghostText}`)}\\n`);\n }\n\n refreshGhostText();\n scheduleRender();\n\n return await new Promise<string>((resolve, reject) => {\n let settled = false;\n let session: RawSession | undefined;\n const keyParser = createKeypressParser({\n onEscapeAbort: () => {\n settleReject(createPromptAbortError());\n },\n });\n\n const cleanup = (): void => {\n session?.close();\n };\n\n const settleResolve = (result: string): void => {\n if (settled) {\n return;\n }\n settled = true;\n closed = true;\n cleanup();\n clearCurrentLine(stdout);\n stdout.write(`${options.message} ${result}\\n`);\n resolve(result);\n };\n\n const settleReject = (error: unknown): void => {\n if (settled) {\n return;\n }\n settled = true;\n closed = true;\n cleanup();\n clearCurrentLine(stdout);\n stdout.write(\"\\n\");\n reject(error);\n };\n\n const keypressHandler = (str: string, key: KeypressInfo = {}): void => {\n void (async () => {\n const parsed = keyParser.handle(str, key);\n\n if (parsed.kind === \"incomplete\") {\n return;\n }\n\n const acceptGhostText = (): boolean => {\n if (ghostText.length === 0) {\n return false;\n }\n value += ghostText;\n templateCycleState = undefined;\n refreshGhostText();\n scheduleRender();\n return true;\n };\n\n const cycleTemplateCandidates = (direction: \"up\" | \"down\"): boolean => {\n if (options.completionKind !== \"rename-template\") {\n return false;\n }\n const completion = resolveTemplateCompletionMatch(value);\n if (!completion || completion.candidates.length <= 1) {\n return false;\n }\n\n const currentIndex = templateCycleState?.scopeKey === completion.scopeKey\n ? templateCycleState.index\n : 0;\n const delta = direction === \"down\" ? 1 : -1;\n const nextIndex =\n (currentIndex + delta + completion.candidates.length) % completion.candidates.length;\n templateCycleState = {\n scopeKey: completion.scopeKey,\n index: nextIndex,\n };\n refreshGhostText();\n scheduleRender();\n return true;\n };\n\n if (parsed.kind === \"arrow\") {\n if (parsed.direction === \"right\" && acceptGhostText()) {\n return;\n }\n\n if ((parsed.direction === \"up\" || parsed.direction === \"down\") &&\n cycleTemplateCandidates(parsed.direction)) {\n return;\n }\n\n beep(stdout);\n scheduleRender();\n return;\n }\n\n const nextStr = parsed.str;\n const nextKey = parsed.key;\n\n if (nextKey.ctrl && nextKey.name === \"c\") {\n settleReject(createPromptAbortError());\n return;\n }\n\n if (nextKey.name === \"return\" || nextKey.name === \"enter\") {\n const validation = await options.validate(value);\n if (validation === true) {\n settleResolve(value);\n return;\n }\n beep(stdout);\n scheduleRender();\n return;\n }\n\n if (nextKey.ctrl && nextKey.name === \"u\") {\n value = \"\";\n templateCycleState = undefined;\n refreshGhostText();\n scheduleRender();\n return;\n }\n\n if (nextKey.name === \"tab\") {\n if (acceptGhostText()) {\n return;\n }\n beep(stdout);\n scheduleRender();\n return;\n }\n\n if (nextKey.name === \"backspace\") {\n if (value.length === 0) {\n beep(stdout);\n scheduleRender();\n return;\n }\n value = value.slice(0, -1);\n templateCycleState = undefined;\n refreshGhostText();\n scheduleRender();\n return;\n }\n\n if (isPrintableInput(nextStr, nextKey)) {\n value += nextStr;\n templateCycleState = undefined;\n refreshGhostText();\n scheduleRender();\n return;\n }\n\n scheduleRender();\n })().catch((error) => {\n settleReject(error);\n });\n };\n\n try {\n session = startRawSession({\n stdin: options.stdin,\n stdout,\n onTeardown: () => {\n keyParser.dispose();\n },\n });\n session.addKeypressListener(keypressHandler);\n } catch (error) {\n settleReject(error);\n }\n });\n}\n","export function validateIntegerInput(\n value: string,\n options: { min?: number; allowEmpty?: boolean },\n): true | string {\n const trimmed = value.trim();\n if (!trimmed) {\n return options.allowEmpty ? true : \"Required\";\n }\n if (!/^\\d+$/.test(trimmed)) {\n return \"Must be a non-negative integer\";\n }\n const parsed = Number(trimmed);\n const min = options.min ?? 0;\n if (parsed < min) {\n return `Must be >= ${min}`;\n }\n return true;\n}\n","import { rm } from \"node:fs/promises\";\n\nimport { checkbox, confirm, input, select } from \"@inquirer/prompts\";\n\nimport {\n actionRenameApply,\n actionRenameCleanup,\n collectRenameCleanupAnalyzerEvidence,\n RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS,\n type RenameCleanupAnalyzerEvidence,\n resolveRenameCleanupTarget,\n suggestRenameCleanupWithCodex,\n writeRenameCleanupAnalysisCsv,\n} from \"../actions\";\nimport { displayPath, printLine } from \"../actions/shared\";\nimport { promptRequiredPathWithConfig } from \"../prompts/path\";\nimport type { CliRuntime } from \"../types\";\nimport type {\n RenameCleanupConflictStrategy,\n RenameCleanupHint,\n RenameCleanupOptions,\n RenameCleanupStyle,\n RenameCleanupTimestampAction,\n} from \"../actions\";\nimport { createInteractiveAnalyzerStatus } from \"./analyzer-status\";\nimport { validateIntegerInput } from \"./input-validation\";\nimport type { InteractivePathPromptContext } from \"./shared\";\n\nconst INTERACTIVE_CLEANUP_HINT_CHOICES: Array<{\n name: string;\n value: RenameCleanupHint;\n description: string;\n}> = [\n {\n name: \"timestamp\",\n value: \"timestamp\",\n description: \"Date-plus-time fragments such as macOS screenshot timestamps\",\n },\n { name: \"date\", value: \"date\", description: \"Date-only fragments such as 2026-03-03\" },\n { name: \"serial\", value: \"serial\", description: \"Trailing counters such as (2), -01, or _003\" },\n { name: \"uid\", value: \"uid\", description: \"Existing uid-<token> fragments\" },\n];\nconst ANALYZER_FAMILY_VALUES = INTERACTIVE_CLEANUP_HINT_CHOICES.map(\n (choice) => choice.value,\n) as RenameCleanupHint[];\nconst CLEANUP_GROUPED_REVIEW_LIMITS = {\n // Keep grouped preview bounded in interactive terminals.\n maxGroupsToPrint: RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS.groupLimit,\n maxExamplesLineChars: 220,\n} as const;\n\nfunction parseInteractiveCsvList(value: string): string[] | undefined {\n const items = value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n return items.length > 0 ? items : undefined;\n}\n\nasync function promptInteractiveCleanupHints(): Promise<RenameCleanupHint[]> {\n const selected: RenameCleanupHint[] = [];\n\n while (true) {\n const remainingChoices = INTERACTIVE_CLEANUP_HINT_CHOICES.filter(\n (choice) => !selected.includes(choice.value),\n );\n const choice = await select<RenameCleanupHint | \"done\">({\n message: selected.length === 0 ? \"Add a cleanup hint\" : \"Add another cleanup hint or finish\",\n choices: [\n ...remainingChoices,\n ...(selected.length > 0\n ? [\n {\n name: \"done\",\n value: \"done\" as const,\n description: `Selected: ${selected.join(\", \")}`,\n },\n ]\n : []),\n ],\n });\n\n if (choice === \"done\") {\n return selected;\n }\n\n selected.push(choice);\n }\n}\n\nasync function promptCleanupAnalyzerFamilies(): Promise<RenameCleanupHint[]> {\n const selected = await checkbox<RenameCleanupHint>({\n message: \"Analyzer families to focus on (all selected by default)\",\n choices: INTERACTIVE_CLEANUP_HINT_CHOICES.map((choice) => ({\n ...choice,\n checked: true,\n })),\n required: false,\n });\n\n // Empty selection keeps the null/default full-scope behavior.\n return selected.length > 0 ? [...new Set(selected)] : [...ANALYZER_FAMILY_VALUES];\n}\n\nfunction isAnalyzerFamilyInPattern(pattern: string, family: RenameCleanupHint): boolean {\n if (family === \"timestamp\") {\n return pattern.includes(\"{timestamp}\");\n }\n if (family === \"date\") {\n return pattern.includes(\"{date}\");\n }\n if (family === \"serial\") {\n return pattern.includes(\"{serial}\");\n }\n return pattern.includes(\"{uid}\");\n}\n\nfunction narrowCleanupAnalyzerEvidence(\n evidence: RenameCleanupAnalyzerEvidence,\n selectedFamilies: RenameCleanupHint[],\n): RenameCleanupAnalyzerEvidence {\n if (selectedFamilies.length === ANALYZER_FAMILY_VALUES.length) {\n return evidence;\n }\n\n const narrowedGroups = evidence.groupedPatterns.filter((group) =>\n selectedFamilies.some((family) => isAnalyzerFamilyInPattern(group.pattern, family)),\n );\n const sampleNames: string[] = [];\n const sampleNameSet = new Set<string>();\n for (const group of narrowedGroups) {\n for (const example of group.examples) {\n if (sampleNameSet.has(example)) {\n continue;\n }\n sampleNameSet.add(example);\n sampleNames.push(example);\n }\n }\n\n return {\n ...evidence,\n sampledCount: sampleNames.length,\n sampleNames,\n groupedPatterns: narrowedGroups,\n };\n}\n\nfunction printCleanupAnalyzerGroupedReview(runtime: CliRuntime, evidence: RenameCleanupAnalyzerEvidence): void {\n const truncate = (value: string, maxChars: number): { value: string; truncated: boolean } => {\n if (value.length <= maxChars) {\n return { value, truncated: false };\n }\n if (maxChars <= 3) {\n return { value: value.slice(0, maxChars), truncated: true };\n }\n return { value: `${value.slice(0, maxChars - 3)}...`, truncated: true };\n };\n printLine(runtime.stdout, \"Grouped analyzer review:\");\n if (evidence.groupedPatterns.length === 0) {\n printLine(runtime.stdout, \"- no grouped pattern evidence\");\n printLine(runtime.stdout);\n return;\n }\n\n const groupedPatterns = evidence.groupedPatterns.slice(0, CLEANUP_GROUPED_REVIEW_LIMITS.maxGroupsToPrint);\n const hiddenGroupCount = Math.max(0, evidence.groupedPatterns.length - groupedPatterns.length);\n let truncatedExamplesGroupCount = 0;\n for (const group of groupedPatterns) {\n const truncatedExamples = truncate(\n group.examples.join(\" | \"),\n CLEANUP_GROUPED_REVIEW_LIMITS.maxExamplesLineChars,\n );\n if (truncatedExamples.truncated) {\n truncatedExamplesGroupCount += 1;\n }\n printLine(runtime.stdout, `- ${group.pattern} (${group.count})`);\n printLine(runtime.stdout, ` examples: ${truncatedExamples.value}`);\n }\n if (hiddenGroupCount > 0) {\n printLine(runtime.stdout, `- ... ${hiddenGroupCount} additional grouped pattern(s) not shown`);\n }\n if (truncatedExamplesGroupCount > 0) {\n printLine(\n runtime.stdout,\n `- ... examples truncated for ${truncatedExamplesGroupCount} grouped pattern(s)`,\n );\n }\n printLine(runtime.stdout);\n}\n\nasync function promptCleanupStyle(): Promise<RenameCleanupStyle> {\n return select<RenameCleanupStyle>({\n message: \"Cleanup output style\",\n choices: [\n {\n name: \"preserve\",\n value: \"preserve\",\n description: \"Keep readable spacing while normalizing matched fragments\",\n },\n {\n name: \"slug\",\n value: \"slug\",\n description: \"Convert the remaining text to kebab-case\",\n },\n ],\n default: \"preserve\",\n });\n}\n\nasync function promptCleanupTimestampAction(): Promise<RenameCleanupTimestampAction> {\n return select<RenameCleanupTimestampAction>({\n message: \"Timestamp fragment handling\",\n choices: [\n {\n name: \"keep\",\n value: \"keep\",\n description: \"Keep matched timestamps in normalized form\",\n },\n {\n name: \"remove\",\n value: \"remove\",\n description: \"Remove matched timestamps from the basename\",\n },\n ],\n default: \"keep\",\n });\n}\n\nasync function promptManualCleanupSettings(): Promise<{\n hints: RenameCleanupHint[];\n style: RenameCleanupStyle;\n timestampAction?: RenameCleanupTimestampAction;\n}> {\n const hints = await promptInteractiveCleanupHints();\n const style = await promptCleanupStyle();\n const timestampAction = hints.includes(\"timestamp\")\n ? await promptCleanupTimestampAction()\n : undefined;\n return { hints, style, timestampAction };\n}\n\nasync function promptCleanupScopeOptions(pathKind: \"file\" | \"directory\"): Promise<\n Pick<\n RenameCleanupOptions,\n \"recursive\" | \"maxDepth\" | \"matchRegex\" | \"skipRegex\" | \"ext\" | \"skipExt\"\n >\n> {\n const recursive =\n pathKind === \"directory\"\n ? await confirm({\n message: \"Traverse subdirectories recursively?\",\n default: false,\n })\n : false;\n const maxDepthInput =\n pathKind === \"directory\" && recursive\n ? await input({\n message: \"Max recursive depth (optional, root=0)\",\n default: \"\",\n validate: (value) => validateIntegerInput(value, { min: 0, allowEmpty: true }),\n })\n : \"\";\n const filterFiles =\n pathKind === \"directory\"\n ? await confirm({\n message: \"Filter files before cleanup?\",\n default: false,\n })\n : false;\n const matchRegex =\n pathKind === \"directory\" && filterFiles\n ? await input({ message: \"Match regex (optional)\", default: \"\" })\n : \"\";\n const skipRegex =\n pathKind === \"directory\" && filterFiles\n ? await input({ message: \"Skip regex (optional)\", default: \"\" })\n : \"\";\n const extInput =\n pathKind === \"directory\" && filterFiles\n ? await input({\n message: \"Only extensions (optional, comma-separated)\",\n default: \"\",\n })\n : \"\";\n const skipExtInput =\n pathKind === \"directory\" && filterFiles\n ? await input({\n message: \"Skip extensions (optional, comma-separated)\",\n default: \"\",\n })\n : \"\";\n\n return {\n recursive: pathKind === \"directory\" ? recursive : undefined,\n maxDepth: maxDepthInput.trim() ? Number(maxDepthInput.trim()) : undefined,\n matchRegex: matchRegex.trim() ? matchRegex.trim() : undefined,\n skipRegex: skipRegex.trim() ? skipRegex.trim() : undefined,\n ext: parseInteractiveCsvList(extInput),\n skipExt: parseInteractiveCsvList(skipExtInput),\n };\n}\n\nfunction printCleanupCodexSuggestion(\n runtime: CliRuntime,\n options: {\n hints: RenameCleanupHint[];\n style: RenameCleanupStyle;\n timestampAction?: RenameCleanupTimestampAction;\n confidence: number;\n reasoningSummary: string;\n },\n): void {\n printLine(runtime.stdout, \"Codex cleanup suggestion:\");\n printLine(runtime.stdout, `- hints: ${options.hints.join(\", \")}`);\n printLine(runtime.stdout, `- style: ${options.style}`);\n if (options.timestampAction) {\n printLine(runtime.stdout, `- timestamp action: ${options.timestampAction}`);\n }\n printLine(runtime.stdout, `- confidence: ${Math.round(options.confidence * 100)}%`);\n printLine(runtime.stdout, `- reasoning: ${options.reasoningSummary}`);\n printLine(runtime.stdout);\n}\n\nfunction printDeterministicCleanupSettings(\n runtime: CliRuntime,\n options: {\n hints: RenameCleanupHint[];\n style: RenameCleanupStyle;\n timestampAction?: RenameCleanupTimestampAction;\n },\n): void {\n printLine(runtime.stdout, \"Deterministic cleanup settings (global):\");\n printLine(runtime.stdout, `- hints: ${options.hints.join(\", \")}`);\n printLine(runtime.stdout, `- style: ${options.style}`);\n if (options.timestampAction) {\n printLine(runtime.stdout, `- timestamp action: ${options.timestampAction}`);\n }\n printLine(runtime.stdout);\n}\n\nasync function promptCleanupSettingsFromSuggestion(\n runtime: CliRuntime,\n options: {\n path: string;\n analyzerFamilies: RenameCleanupHint[];\n scope: Pick<\n RenameCleanupOptions,\n \"recursive\" | \"maxDepth\" | \"matchRegex\" | \"skipRegex\" | \"ext\" | \"skipExt\"\n >;\n },\n): Promise<{\n settings?:\n | {\n hints: RenameCleanupHint[];\n style: RenameCleanupStyle;\n timestampAction?: RenameCleanupTimestampAction;\n }\n | undefined;\n analysisReportPath?: string;\n}> {\n const status = createInteractiveAnalyzerStatus(runtime.stdout, runtime.colorEnabled);\n try {\n printLine(runtime.stdout, `Analyzer families selected: ${options.analyzerFamilies.join(\", \")}`);\n printLine(runtime.stdout);\n\n const analyzerSampleLimit = RENAME_CLEANUP_ANALYZER_EVIDENCE_LIMITS.sampleLimit;\n\n status.start(\"Sampling filenames for cleanup analysis...\");\n const collectedEvidence = await collectRenameCleanupAnalyzerEvidence(runtime, {\n path: options.path,\n ...options.scope,\n sampleLimit: analyzerSampleLimit,\n // Keep all sample-derived groups available for family narrowing, then let\n // grouped review/prompt rendering apply their own tighter presentation caps.\n groupLimit: analyzerSampleLimit,\n onProgress: (phase) => {\n if (phase === \"grouping\") {\n status.update(\"Grouping filename patterns for cleanup analysis...\");\n }\n },\n });\n const evidence = narrowCleanupAnalyzerEvidence(collectedEvidence, options.analyzerFamilies);\n status.stop();\n printCleanupAnalyzerGroupedReview(runtime, evidence);\n if (evidence.groupedPatterns.length === 0) {\n printLine(\n runtime.stdout,\n \"Codex cleanup suggestion unavailable: No grouped analyzer patterns matched selected families.\",\n );\n printLine(runtime.stdout, \"Falling back to manual cleanup settings.\");\n printLine(runtime.stdout);\n return {};\n }\n status.wait(\"Waiting for Codex cleanup suggestions...\");\n const result = await suggestRenameCleanupWithCodex({\n evidence,\n workingDirectory: runtime.cwd,\n });\n status.stop();\n\n if (!result.suggestion) {\n if (result.errorMessage) {\n printLine(runtime.stdout, `Codex cleanup suggestion unavailable: ${result.errorMessage}`);\n printLine(runtime.stdout, \"Falling back to manual cleanup settings.\");\n printLine(runtime.stdout);\n }\n return {};\n }\n\n printCleanupCodexSuggestion(runtime, {\n hints: result.suggestion.recommendedHints,\n style: result.suggestion.recommendedStyle,\n timestampAction: result.suggestion.recommendedTimestampAction,\n confidence: result.suggestion.confidence,\n reasoningSummary: result.suggestion.reasoningSummary,\n });\n printDeterministicCleanupSettings(runtime, {\n hints: result.suggestion.recommendedHints,\n style: result.suggestion.recommendedStyle,\n timestampAction: result.suggestion.recommendedTimestampAction,\n });\n\n const writeAnalysisReport = await confirm({\n message: \"Write grouped cleanup analysis report CSV?\",\n default: false,\n });\n let analysisReportPath: string | undefined;\n if (writeAnalysisReport) {\n analysisReportPath = await writeRenameCleanupAnalysisCsv(runtime, {\n evidence,\n suggestion: result.suggestion,\n });\n printLine(\n runtime.stdout,\n `Wrote cleanup analysis report: ${displayPath(runtime, analysisReportPath)}`,\n );\n printLine(runtime.stdout);\n }\n\n const useSuggestion = await confirm({\n message: \"Use these as deterministic cleanup settings?\",\n default: true,\n });\n if (!useSuggestion) {\n return { analysisReportPath };\n }\n\n return {\n settings: {\n hints: result.suggestion.recommendedHints,\n style: result.suggestion.recommendedStyle,\n timestampAction: result.suggestion.recommendedTimestampAction,\n },\n analysisReportPath,\n };\n } catch (error) {\n status.stop();\n const message = error instanceof Error ? error.message : String(error);\n printLine(runtime.stdout, `Codex cleanup suggestion unavailable: ${message}`);\n printLine(runtime.stdout, \"Falling back to manual cleanup settings.\");\n printLine(runtime.stdout);\n return {};\n }\n}\n\nasync function promptCleanupConflictStrategy(): Promise<RenameCleanupConflictStrategy> {\n return select<RenameCleanupConflictStrategy>({\n message: \"Cleanup conflict strategy\",\n choices: [\n {\n name: \"skip\",\n value: \"skip\",\n description: \"Keep the clean target when free and skip only the conflicted rows\",\n },\n {\n name: \"number\",\n value: \"number\",\n description: \"Append -1, -2, -3 only when the cleaned target conflicts\",\n },\n {\n name: \"uid-suffix\",\n value: \"uid-suffix\",\n description: \"Append -uid-<token> only when the cleaned target conflicts\",\n },\n ],\n default: \"skip\",\n });\n}\n\nexport async function runInteractiveRenameCleanup(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n): Promise<void> {\n const path = await promptRequiredPathWithConfig(\"Target path\", {\n kind: \"path\",\n ...pathPromptContext,\n });\n const target = await resolveRenameCleanupTarget(runtime, path);\n const scope = await promptCleanupScopeOptions(target.kind);\n\n const suggestWithCodex = await confirm({\n message: \"Suggest cleanup hints with Codex?\",\n default: false,\n });\n const analyzerFamilies = suggestWithCodex\n ? await promptCleanupAnalyzerFamilies()\n : undefined;\n const suggestionResult = suggestWithCodex\n ? await promptCleanupSettingsFromSuggestion(runtime, {\n path,\n analyzerFamilies: analyzerFamilies ?? ANALYZER_FAMILY_VALUES,\n scope,\n })\n : undefined;\n const cleanupSettings = suggestionResult?.settings ?? (await promptManualCleanupSettings());\n const cleanupActionSettings = {\n hints: cleanupSettings.hints,\n style: cleanupSettings.style,\n timestampAction: cleanupSettings.timestampAction,\n };\n const analysisReportPath = suggestionResult?.analysisReportPath;\n\n const conflictStrategy = await promptCleanupConflictStrategy();\n const dryRun = await confirm({ message: \"Dry run only?\", default: true });\n const previewSkips =\n target.kind === \"directory\" && dryRun\n ? await select<\"summary\" | \"detailed\">({\n message: \"Skipped-item preview mode\",\n choices: [\n {\n name: \"summary\",\n value: \"summary\",\n description: \"Compact skipped summary grouped by reason\",\n },\n {\n name: \"detailed\",\n value: \"detailed\",\n description: \"Show skipped summary plus bounded per-item skipped rows\",\n },\n ],\n default: \"summary\",\n })\n : undefined;\n\n const result = await actionRenameCleanup(runtime, {\n path,\n ...cleanupActionSettings,\n conflictStrategy,\n ...scope,\n dryRun,\n previewSkips,\n });\n\n const hasChanges = result.kind === \"file\" ? result.changed : result.changedCount > 0;\n if (!dryRun || !hasChanges || !result.planCsvPath) {\n return;\n }\n\n const applyNow = await confirm({ message: \"Apply these renames now?\", default: false });\n if (!applyNow) {\n const keepDryRunPlanCsv = await confirm({\n message: \"Keep dry-run plan CSV for later `rename apply`?\",\n default: true,\n });\n const keepAnalysisReportCsv = analysisReportPath\n ? await confirm({\n message: \"Keep cleanup analysis report CSV?\",\n default: true,\n })\n : true;\n\n if (!keepDryRunPlanCsv) {\n await rm(result.planCsvPath, { force: true });\n printLine(runtime.stdout, `Cleanup plan CSV removed: ${displayPath(runtime, result.planCsvPath)}`);\n }\n if (analysisReportPath && !keepAnalysisReportCsv) {\n await rm(analysisReportPath, { force: true });\n printLine(\n runtime.stdout,\n `Cleanup analysis report removed: ${displayPath(runtime, analysisReportPath)}`,\n );\n }\n return;\n }\n\n await actionRenameApply(runtime, { csv: result.planCsvPath, autoClean: false });\n const keepAppliedPlanCsv = await confirm({\n message: \"Keep applied plan CSV?\",\n default: false,\n });\n const keepAnalysisReportCsv = analysisReportPath\n ? await confirm({\n message: \"Keep cleanup analysis report CSV?\",\n default: true,\n })\n : true;\n\n if (!keepAppliedPlanCsv) {\n await rm(result.planCsvPath, { force: true });\n printLine(runtime.stdout, `Cleanup plan CSV removed: ${displayPath(runtime, result.planCsvPath)}`);\n }\n if (analysisReportPath && !keepAnalysisReportCsv) {\n await rm(analysisReportPath, { force: true });\n printLine(\n runtime.stdout,\n `Cleanup analysis report removed: ${displayPath(runtime, analysisReportPath)}`,\n );\n }\n}\n","import { confirm, input, select } from \"@inquirer/prompts\";\n\nimport {\n actionRenameApply,\n actionRenameBatch,\n actionRenameFile,\n} from \"../actions\";\nimport { promptRequiredPathWithConfig } from \"../prompts/path\";\nimport { promptTextWithGhost } from \"../prompts/text-inline\";\nimport {\n type RenameInteractiveCodexFlags as InteractiveCodexFlags,\n type RenameInteractiveCodexScope as InteractiveCodexScope,\n resolveAutoCodexFlagsForBatchProfile,\n resolveAutoCodexFlagsForFilePath,\n resolveCodexFlagsFromScope,\n} from \"../rename-interactive-router\";\nimport {\n type RenameSerialOrder,\n type RenameSerialScope,\n type RenameTemplatePreset,\n type TimestampTimezone,\n RENAME_SERIAL_ORDER_VALUES,\n normalizeSerialPlaceholderInTemplate,\n resolveRenamePatternTemplate,\n resolveTimestampPatternForInteractive,\n shouldPromptTimestampTimezone,\n templateContainsPrefixPlaceholder,\n templateContainsSerialPlaceholder,\n} from \"../rename-template\";\nimport type { CliRuntime } from \"../types\";\nimport { validateIntegerInput } from \"./input-validation\";\nimport type { RenameInteractiveActionKey } from \"./menu\";\nimport { runInteractiveRenameCleanup } from \"./rename-cleanup\";\nimport { assertNeverInteractiveAction, type InteractivePathPromptContext } from \"./shared\";\n\nasync function promptRenamePatternConfig(options: {\n includeSerialScope: boolean;\n pathPromptContext: InteractivePathPromptContext;\n}): Promise<{\n pattern: string;\n usesPrefix: boolean;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope: RenameSerialScope;\n}> {\n const preset = await select<RenameTemplatePreset>({\n message: \"Filename template preset\",\n choices: [\n {\n name: \"default\",\n value: \"default\",\n description: \"{prefix}-{timestamp}-{stem}\",\n },\n {\n name: \"timestamp-first\",\n value: \"timestamp-first\",\n description: \"{timestamp}-{prefix}-{stem}\",\n },\n {\n name: \"stem-first\",\n value: \"stem-first\",\n description: \"{stem}-{timestamp}-{prefix}\",\n },\n {\n name: \"custom\",\n value: \"custom\",\n description: \"Provide a custom template string\",\n },\n ],\n });\n\n const customTemplate =\n preset === \"custom\"\n ? await promptTextWithGhost({\n message: \"Template\",\n helpLines: [\n \"Custom filename template\",\n \"Main placeholders: {prefix}, {timestamp}, {date}, {stem}, {uid}, {serial}\",\n \"Advanced: explicit timestamp variants and {serial...} params are also supported.\",\n ],\n ghostHintLabel: \"Template suggestion (Right arrow to accept)\",\n ghostText: \"{timestamp}-{stem}\",\n completionKind: \"rename-template\",\n runtimeConfig: options.pathPromptContext.runtimeConfig,\n stdin: options.pathPromptContext.stdin,\n stdout: options.pathPromptContext.stdout,\n validate: (value) => (value.trim() ? true : \"Required\"),\n })\n : undefined;\n\n const basePattern = resolveRenamePatternTemplate({\n preset,\n customTemplate,\n });\n const usesPrefix = templateContainsPrefixPlaceholder(basePattern);\n const usesSerial = templateContainsSerialPlaceholder(basePattern);\n\n const serialOrder = usesSerial\n ? await select<RenameSerialOrder>({\n message: \"Serial order\",\n choices: RENAME_SERIAL_ORDER_VALUES.map((value) => ({\n name: value,\n value,\n description: value.startsWith(\"mtime_\")\n ? \"mtime uses file modified time\"\n : \"path uses deterministic path ordering\",\n })),\n default: \"path_asc\",\n })\n : undefined;\n\n const serialStartInput = usesSerial\n ? await input({\n message: \"Serial start number\",\n default: \"1\",\n validate: (value) => validateIntegerInput(value, { min: 0 }),\n })\n : \"\";\n\n const serialWidthInput = usesSerial\n ? await input({\n message: \"Serial min width in digits (optional, e.g. 2 => 01)\",\n default: \"\",\n validate: (value) => validateIntegerInput(value, { min: 1, allowEmpty: true }),\n })\n : \"\";\n\n const serialScope =\n options.includeSerialScope && usesSerial\n ? await select<RenameSerialScope>({\n message: \"Serial scope\",\n choices: [\n {\n name: \"global\",\n value: \"global\",\n description: \"Single serial sequence across recursive traversal\",\n },\n {\n name: \"directory\",\n value: \"directory\",\n description: \"Reset serial per directory when recursive\",\n },\n ],\n default: \"global\",\n })\n : \"global\";\n\n const serialStart = serialStartInput.trim() ? Number(serialStartInput.trim()) : undefined;\n const serialWidth = serialWidthInput.trim() ? Number(serialWidthInput.trim()) : undefined;\n const pattern =\n usesSerial && serialOrder !== undefined && serialStart !== undefined\n ? normalizeSerialPlaceholderInTemplate({\n template: basePattern,\n serial: {\n order: serialOrder,\n start: serialStart,\n width: serialWidth,\n },\n })\n : basePattern;\n\n const timestampTimezone: TimestampTimezone | undefined = shouldPromptTimestampTimezone(pattern)\n ? await select<TimestampTimezone>({\n message: \"Timestamp timezone basis\",\n choices: [\n {\n name: \"utc\",\n value: \"utc\",\n description: \"Stable cross-machine/audit naming (default)\",\n },\n {\n name: \"local\",\n value: \"local\",\n description: \"Local clock naming for personal use\",\n },\n ],\n default: \"utc\",\n })\n : undefined;\n\n const finalPattern = resolveTimestampPatternForInteractive(pattern, timestampTimezone);\n\n return {\n pattern: finalPattern,\n usesPrefix,\n serialOrder,\n serialStart,\n serialWidth,\n serialScope,\n };\n}\n\nexport async function handleRenameInteractiveAction(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n action: RenameInteractiveActionKey,\n): Promise<void> {\n if (action === \"rename:batch\") {\n const directory = await promptRequiredPathWithConfig(\"Target directory\", {\n kind: \"directory\",\n ...pathPromptContext,\n });\n const profile = await select<string>({\n message: \"File profile scope\",\n choices: [\n {\n name: \"All files (default)\",\n value: \"all\",\n description: \"No preset filter (still skips hidden/system junk by default)\",\n },\n {\n name: \"Images\",\n value: \"images\",\n description: \"Common image files: .png, .jpg, .webp, .gif, .svg, ...\",\n },\n {\n name: \"Media (images/audio/video)\",\n value: \"media\",\n description: \"Images + video/audio files: .mp4, .mov, .mp3, .wav, ...\",\n },\n {\n name: \"Docs\",\n value: \"docs\",\n description: \"Docs/data files: .md, .pdf, .docx, .csv, .json, .yaml, ...\",\n },\n ],\n });\n const recursive = await confirm({\n message: \"Traverse subdirectories recursively?\",\n default: false,\n });\n const patternConfig = await promptRenamePatternConfig({\n includeSerialScope: recursive,\n pathPromptContext,\n });\n const prefix = patternConfig.usesPrefix\n ? await input({\n message: \"Filename prefix (optional)\",\n default: \"\",\n })\n : undefined;\n const maxDepthInput = recursive\n ? await input({ message: \"Max recursive depth (optional, root=0)\", default: \"\" })\n : \"\";\n const dryRun = await confirm({ message: \"Dry run only?\", default: true });\n const previewSkips = dryRun\n ? await select<\"summary\" | \"detailed\">({\n message: \"Skipped-item preview mode\",\n choices: [\n {\n name: \"summary\",\n value: \"summary\",\n description: \"Compact skipped summary grouped by reason\",\n },\n {\n name: \"detailed\",\n value: \"detailed\",\n description: \"Show skipped summary plus bounded per-item skipped rows\",\n },\n ],\n default: \"summary\",\n })\n : \"summary\";\n const codexEnabled = await confirm({\n message: \"Enable Codex assistant when eligible?\",\n default: false,\n });\n let codexFlags: InteractiveCodexFlags = { codexImages: false, codexDocs: false };\n if (codexEnabled) {\n const scope = await select<InteractiveCodexScope>({\n message: \"Codex assistant scope\",\n choices: [\n {\n name: \"auto\",\n value: \"auto\",\n description: \"Route based on profile scope and supported extensions\",\n },\n {\n name: \"images\",\n value: \"images\",\n description: \"Enable only image analyzer\",\n },\n {\n name: \"docs\",\n value: \"docs\",\n description: \"Enable only document analyzer\",\n },\n ],\n default: \"auto\",\n });\n codexFlags = resolveCodexFlagsFromScope({\n scope,\n fallbackAuto: resolveAutoCodexFlagsForBatchProfile(profile),\n });\n }\n const result = await actionRenameBatch(runtime, {\n directory,\n prefix,\n pattern: patternConfig.pattern,\n serialOrder: patternConfig.serialOrder,\n serialStart: patternConfig.serialStart,\n serialWidth: patternConfig.serialWidth,\n serialScope: recursive ? patternConfig.serialScope : \"global\",\n profile: profile === \"all\" ? undefined : profile,\n recursive,\n maxDepth: maxDepthInput.trim() ? Number(maxDepthInput) : undefined,\n dryRun,\n previewSkips,\n codexImages: codexFlags.codexImages,\n codexDocs: codexFlags.codexDocs,\n });\n\n if (!dryRun && result.changedCount > 0) {\n return;\n }\n\n if (dryRun && result.changedCount > 0) {\n const applyNow = await confirm({ message: \"Apply these renames now?\", default: false });\n if (applyNow && result.planCsvPath) {\n const autoClean = await confirm({\n message: \"Auto-clean plan CSV after apply?\",\n default: true,\n });\n await actionRenameApply(runtime, { csv: result.planCsvPath, autoClean });\n }\n }\n return;\n }\n\n if (action === \"rename:cleanup\") {\n await runInteractiveRenameCleanup(runtime, pathPromptContext);\n return;\n }\n\n if (action === \"rename:file\") {\n const path = await promptRequiredPathWithConfig(\"Target file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const patternConfig = await promptRenamePatternConfig({\n includeSerialScope: false,\n pathPromptContext,\n });\n const prefix = patternConfig.usesPrefix\n ? await input({\n message: \"Filename prefix (optional)\",\n default: \"\",\n })\n : undefined;\n const dryRun = await confirm({ message: \"Dry run only?\", default: true });\n const codexEnabled = await confirm({\n message: \"Enable Codex assistant when eligible?\",\n default: false,\n });\n let codexFlags: InteractiveCodexFlags = { codexImages: false, codexDocs: false };\n if (codexEnabled) {\n const scope = await select<InteractiveCodexScope>({\n message: \"Codex assistant scope\",\n choices: [\n {\n name: \"auto\",\n value: \"auto\",\n description: \"Route based on selected file extension and supported analyzers\",\n },\n {\n name: \"images\",\n value: \"images\",\n description: \"Enable only image analyzer\",\n },\n {\n name: \"docs\",\n value: \"docs\",\n description: \"Enable only document analyzer\",\n },\n ],\n default: \"auto\",\n });\n codexFlags = resolveCodexFlagsFromScope({\n scope,\n fallbackAuto: resolveAutoCodexFlagsForFilePath(path),\n });\n }\n const result = await actionRenameFile(runtime, {\n path,\n prefix,\n pattern: patternConfig.pattern,\n serialOrder: patternConfig.serialOrder,\n serialStart: patternConfig.serialStart,\n serialWidth: patternConfig.serialWidth,\n serialScope: \"global\",\n dryRun,\n codexImages: codexFlags.codexImages,\n codexDocs: codexFlags.codexDocs,\n });\n\n if (!dryRun || !result.changed) {\n return;\n }\n\n const applyNow = await confirm({ message: \"Apply this rename now?\", default: false });\n if (applyNow && result.planCsvPath) {\n const autoClean = await confirm({\n message: \"Auto-clean plan CSV after apply?\",\n default: true,\n });\n await actionRenameApply(runtime, { csv: result.planCsvPath, autoClean });\n }\n return;\n }\n\n if (action !== \"rename:apply\") {\n assertNeverInteractiveAction(action);\n }\n\n const csvPath = await promptRequiredPathWithConfig(\"Rename plan CSV path\", {\n kind: \"csv\",\n ...pathPromptContext,\n });\n const autoClean = await confirm({\n message: \"Auto-clean plan CSV after apply?\",\n default: true,\n });\n await actionRenameApply(runtime, { csv: csvPath, autoClean });\n}\n","import { confirm, input } from \"@inquirer/prompts\";\n\nimport { actionVideoConvert, actionVideoGif, actionVideoResize } from \"../actions\";\nimport {\n formatDefaultOutputPathHint,\n promptOptionalOutputPathChoice,\n promptRequiredPathWithConfig,\n} from \"../prompts/path\";\nimport type { CliRuntime } from \"../types\";\nimport type { VideoInteractiveActionKey } from \"./menu\";\nimport { assertNeverInteractiveAction, type InteractivePathPromptContext } from \"./shared\";\n\nexport async function handleVideoInteractiveAction(\n runtime: CliRuntime,\n pathPromptContext: InteractivePathPromptContext,\n action: VideoInteractiveActionKey,\n): Promise<void> {\n if (action === \"video:convert\") {\n const inputPath = await promptRequiredPathWithConfig(\"Input video file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const outputPath = await promptRequiredPathWithConfig(\"Output video file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const overwrite = await confirm({ message: \"Overwrite if exists?\", default: false });\n await actionVideoConvert(runtime, { input: inputPath, output: outputPath, overwrite });\n return;\n }\n\n if (action === \"video:resize\") {\n const inputPath = await promptRequiredPathWithConfig(\"Input video file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const outputPath = await promptRequiredPathWithConfig(\"Output video file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const scale = Number(\n await input({\n message: \"Scale factor (for example 0.5 halves size, 2 doubles it)\",\n validate: (value) => {\n const trimmed = value.trim();\n if (!trimmed) {\n return \"Required\";\n }\n const parsed = Number(trimmed);\n return Number.isFinite(parsed) && parsed > 0 ? true : \"Enter a positive number.\";\n },\n }),\n );\n const overwrite = await confirm({ message: \"Overwrite if exists?\", default: false });\n await actionVideoResize(runtime, {\n input: inputPath,\n output: outputPath,\n scale,\n overwrite,\n });\n return;\n }\n\n if (action !== \"video:gif\") {\n assertNeverInteractiveAction(action);\n }\n\n const inputPath = await promptRequiredPathWithConfig(\"Input video file\", {\n kind: \"file\",\n ...pathPromptContext,\n });\n const outputHint = formatDefaultOutputPathHint(runtime, inputPath, \".gif\");\n const outputPath = await promptOptionalOutputPathChoice({\n message: \"Output GIF file\",\n defaultHint: outputHint,\n kind: \"file\",\n ...pathPromptContext,\n customMessage: \"Custom GIF output path\",\n });\n const widthInput = await input({ message: \"Width in px (optional)\", default: \"480\" });\n const fpsInput = await input({ message: \"FPS (optional)\", default: \"10\" });\n const overwrite = await confirm({ message: \"Overwrite if exists?\", default: false });\n await actionVideoGif(runtime, {\n input: inputPath,\n output: outputPath,\n width: widthInput.trim() ? Number(widthInput) : undefined,\n fps: fpsInput.trim() ? Number(fpsInput) : undefined,\n overwrite,\n });\n}\n","import { confirm } from \"@inquirer/prompts\";\n\nimport { actionDoctor } from \"../actions\";\nimport { resolvePathPromptRuntimeConfig } from \"../prompts/path-config\";\nimport type { CliRuntime } from \"../types\";\nimport { handleDataInteractiveAction } from \"./data\";\nimport { handleMarkdownInteractiveAction } from \"./markdown\";\nimport { selectInteractiveAction } from \"./menu\";\nimport { handleRenameInteractiveAction } from \"./rename\";\nimport { assertNeverInteractiveAction, type InteractivePathPromptContext } from \"./shared\";\nimport { handleVideoInteractiveAction } from \"./video\";\n\nexport async function runInteractiveMode(runtime: CliRuntime): Promise<void> {\n const pathPromptContext: InteractivePathPromptContext = {\n runtimeConfig: resolvePathPromptRuntimeConfig(),\n cwd: runtime.cwd,\n stdin: runtime.stdin,\n stdout: runtime.stdout,\n };\n const action = await selectInteractiveAction();\n\n if (action === \"cancel\") {\n runtime.stdout.write(\"Cancelled.\\n\");\n return;\n }\n\n if (action === \"doctor\") {\n const asJson = await confirm({ message: \"Output as JSON?\", default: false });\n await actionDoctor(runtime, { json: asJson });\n return;\n }\n\n switch (action) {\n case \"data:preview\":\n case \"data:query\":\n case \"data:parquet-preview\":\n case \"data:json-to-csv\":\n case \"data:csv-to-json\":\n await handleDataInteractiveAction(runtime, pathPromptContext, action);\n return;\n case \"md:to-docx\":\n case \"md:frontmatter-to-json\":\n await handleMarkdownInteractiveAction(runtime, pathPromptContext, action);\n return;\n case \"rename:file\":\n case \"rename:batch\":\n case \"rename:cleanup\":\n case \"rename:apply\":\n await handleRenameInteractiveAction(runtime, pathPromptContext, action);\n return;\n case \"video:convert\":\n case \"video:resize\":\n case \"video:gif\":\n await handleVideoInteractiveAction(runtime, pathPromptContext, action);\n return;\n }\n\n assertNeverInteractiveAction(action);\n}\n","// This file is generated by scripts/generate-embedded-version.mjs.\n// Do not edit manually.\nexport const EMBEDDED_PACKAGE_VERSION = \"0.0.7\";\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join, resolve as resolvePath } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { getProcessColors } from \"../colors\";\nimport { EMBEDDED_PACKAGE_VERSION } from \"./version-embedded\";\n\nfunction* candidateSearchRoots(): Generator<string> {\n yield dirname(fileURLToPath(import.meta.url));\n\n const argvPath = process.argv[1];\n if (typeof argvPath === \"string\" && argvPath.length > 0) {\n yield dirname(resolvePath(argvPath));\n }\n\n yield process.cwd();\n}\n\nfunction* walkUpDirectories(start: string, maxLevels: number): Generator<string> {\n let current = start;\n for (let depth = 0; depth < maxLevels; depth += 1) {\n yield current;\n const parent = dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n}\n\nfunction resolveVersionFromPath(start: string, maxLevels: number): string | null {\n for (const directory of walkUpDirectories(start, maxLevels)) {\n try {\n const raw = readFileSync(join(directory, \"package.json\"), \"utf8\");\n const data = JSON.parse(raw) as { version?: string };\n if (data.version) {\n return data.version;\n }\n } catch {\n // Try parent directories.\n }\n }\n return null;\n}\n\nfunction normalizeVersion(value: string | null | undefined): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n return null;\n }\n\n return trimmed;\n}\n\ntype ResolvePackageVersionOptions = {\n embeddedVersion?: string | null;\n candidateRoots?: string[];\n maxLevels?: number;\n resolveFromPath?: (start: string, maxLevels: number) => string | null;\n};\n\nexport function resolvePackageVersion(options: ResolvePackageVersionOptions = {}): string {\n const embeddedVersion = normalizeVersion(options.embeddedVersion ?? EMBEDDED_PACKAGE_VERSION);\n if (embeddedVersion) {\n return embeddedVersion;\n }\n\n const maxLevels = options.maxLevels ?? 8;\n const resolveFromPath = options.resolveFromPath ?? resolveVersionFromPath;\n const roots = options.candidateRoots ?? [...candidateSearchRoots()];\n const seen = new Set<string>();\n for (const root of roots) {\n if (seen.has(root)) {\n continue;\n }\n seen.add(root);\n const version = normalizeVersion(resolveFromPath(root, maxLevels));\n if (version) {\n return version;\n }\n }\n\n return \"0.0.0\";\n}\n\nexport function getFormattedVersionLabel(colorEnabled = true): string {\n const version = resolvePackageVersion();\n const pc = getProcessColors(colorEnabled);\n\n return pc.bgBlack(pc.bold(pc.italic(` cdx-chores ${pc.cyanBright(`ver.${version}`)} `)));\n}\n","import { Command, InvalidArgumentError } from \"commander\";\nimport {\n actionCsvToJson,\n actionDataDuckDbDoctor,\n actionDataDuckDbExtensionInstall,\n actionDataParquetPreview,\n actionDataPreview,\n actionDataQuery,\n actionDataQueryCodex,\n actionDoctor,\n actionJsonToCsv,\n actionMdFrontmatterToJson,\n actionMdToDocx,\n actionRenameApply,\n actionRenameBatch,\n actionRenameCleanup,\n actionRenameFile,\n actionVideoConvert,\n actionVideoGif,\n actionVideoResize,\n} from \"./cli/actions\";\nimport { toCliError } from \"./cli/errors\";\nimport { runInteractiveMode } from \"./cli/interactive\";\nimport { resolveCliColorEnabled } from \"./cli/colors\";\nimport {\n DEFAULT_RENAME_SERIAL_ORDER,\n DEFAULT_RENAME_SERIAL_START,\n RENAME_SERIAL_ORDER_VALUES,\n RENAME_SERIAL_SCOPE_VALUES,\n type RenameSerialOrder,\n type RenameSerialScope,\n type TimestampTimezone,\n TIMESTAMP_TIMEZONE_VALUES,\n} from \"./cli/rename-template\";\nimport {\n DATA_QUERY_INPUT_FORMAT_VALUES,\n type DataQueryInputFormat,\n} from \"./cli/duckdb/query\";\nimport {\n DUCKDB_MANAGED_EXTENSION_NAMES,\n type DuckDbManagedExtensionName,\n} from \"./cli/duckdb/extensions\";\nimport type {\n RenameCleanupConflictStrategy,\n RenameCleanupStyle,\n RenameCleanupTimestampAction,\n} from \"./cli/actions/rename\";\nimport { getFormattedVersionLabel } from \"./cli/program/version\";\nimport type { CliRuntime, RunCliOptions } from \"./cli/types\";\n\ninterface NormalizedCliArgv {\n argv: string[];\n colorEnabled: boolean;\n displayPathStyle: CliRuntime[\"displayPathStyle\"];\n}\n\nfunction createRuntime(options: RunCliOptions): CliRuntime {\n return {\n cwd: options.cwd ?? process.cwd(),\n colorEnabled: options.colorEnabled ?? true,\n now: options.now ?? (() => new Date()),\n platform: options.platform ?? process.platform,\n stdout: options.stdout ?? process.stdout,\n stderr: options.stderr ?? process.stderr,\n stdin: options.stdin ?? process.stdin,\n displayPathStyle: options.displayPathStyle ?? \"relative\",\n };\n}\n\nfunction applyCommonFileOptions(command: Command): void {\n command\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"--overwrite\", \"Overwrite output file if it already exists\", false);\n}\n\nfunction collectCsvListOption(value: string, previous: string[] = []): string[] {\n const next = value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n return [...previous, ...next];\n}\n\nfunction collectRepeatedOption(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\nfunction parseNonNegativeIntegerOption(value: string, label: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new InvalidArgumentError(`${label} must be a non-negative integer.`);\n }\n return parsed;\n}\n\nfunction parsePositiveIntegerOption(value: string, label: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(`${label} must be a positive integer.`);\n }\n return parsed;\n}\n\nfunction parsePositiveNumberOption(value: string, label: string): number {\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(`${label} must be a positive number.`);\n }\n return parsed;\n}\n\nfunction parseSerialOrderOption(value: string): RenameSerialOrder {\n if ((RENAME_SERIAL_ORDER_VALUES as readonly string[]).includes(value)) {\n return value as RenameSerialOrder;\n }\n throw new InvalidArgumentError(\n `--serial-order must be one of: ${RENAME_SERIAL_ORDER_VALUES.join(\", \")}.`,\n );\n}\n\nfunction parseSerialScopeOption(value: string): RenameSerialScope {\n if ((RENAME_SERIAL_SCOPE_VALUES as readonly string[]).includes(value)) {\n return value as RenameSerialScope;\n }\n throw new InvalidArgumentError(\n `--serial-scope must be one of: ${RENAME_SERIAL_SCOPE_VALUES.join(\", \")}.`,\n );\n}\n\nfunction parseTimestampTimezoneOption(value: string): TimestampTimezone {\n const normalized = value.trim().toLowerCase();\n if ((TIMESTAMP_TIMEZONE_VALUES as readonly string[]).includes(normalized)) {\n return normalized as TimestampTimezone;\n }\n throw new InvalidArgumentError(\n `--timestamp-timezone must be one of: ${TIMESTAMP_TIMEZONE_VALUES.join(\", \")}.`,\n );\n}\n\nfunction parseDataQueryInputFormatOption(value: string): DataQueryInputFormat {\n const normalized = value.trim().toLowerCase();\n if ((DATA_QUERY_INPUT_FORMAT_VALUES as readonly string[]).includes(normalized)) {\n return normalized as DataQueryInputFormat;\n }\n throw new InvalidArgumentError(\n `--input-format must be one of: ${DATA_QUERY_INPUT_FORMAT_VALUES.join(\", \")}.`,\n );\n}\n\nfunction parseDuckDbManagedExtensionOption(value: string): DuckDbManagedExtensionName {\n const normalized = value.trim().toLowerCase();\n if ((DUCKDB_MANAGED_EXTENSION_NAMES as readonly string[]).includes(normalized)) {\n return normalized as DuckDbManagedExtensionName;\n }\n throw new InvalidArgumentError(\n `Extension name must be one of: ${DUCKDB_MANAGED_EXTENSION_NAMES.join(\", \")}.`,\n );\n}\n\nfunction parseRenameCleanupStyleOption(value: string): RenameCleanupStyle {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"preserve\" || normalized === \"slug\") {\n return normalized;\n }\n throw new InvalidArgumentError(\"--style must be one of: preserve, slug.\");\n}\n\nfunction parseRenameCleanupTimestampActionOption(value: string): RenameCleanupTimestampAction {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"keep\" || normalized === \"remove\") {\n return normalized;\n }\n throw new InvalidArgumentError(\"--timestamp-action must be one of: keep, remove.\");\n}\n\nfunction parseRenameCleanupConflictStrategyOption(value: string): RenameCleanupConflictStrategy {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"skip\" || normalized === \"number\" || normalized === \"uid-suffix\") {\n return normalized;\n }\n throw new InvalidArgumentError(\"--conflict-strategy must be one of: skip, number, uid-suffix.\");\n}\n\nfunction applyRenameTemplateOptions(command: Command): void {\n command\n .option(\n \"--pattern <template>\",\n \"Custom filename template (supports {prefix}, {timestamp}, {timestamp_local}, {timestamp_utc}, {timestamp_local_iso}, {timestamp_utc_iso}, {timestamp_local_12h}, {timestamp_utc_12h}, {date}, {date_local}, {date_utc}, {stem}, {uid}, {serial...})\",\n )\n .option(\n \"--serial-order <value>\",\n `Serial ordering mode override (${RENAME_SERIAL_ORDER_VALUES.join(\", \")}). mtime = modified time. Default when unspecified: ${DEFAULT_RENAME_SERIAL_ORDER}.`,\n parseSerialOrderOption,\n )\n .option(\n \"--serial-start <value>\",\n `Serial start value override (non-negative integer). Default when unspecified: ${DEFAULT_RENAME_SERIAL_START}.`,\n (value) => parseNonNegativeIntegerOption(value, \"--serial-start\"),\n )\n .option(\"--serial-width <value>\", \"Minimum serial width in digits\", (value) =>\n parsePositiveIntegerOption(value, \"--serial-width\"),\n )\n .option(\n \"--serial-scope <value>\",\n `Serial scope mode override (${RENAME_SERIAL_SCOPE_VALUES.join(\", \")}). Default when unspecified: global.`,\n parseSerialScopeOption,\n )\n .option(\n \"--timestamp-timezone <value>\",\n `Timestamp timezone basis for legacy {timestamp} placeholder (${TIMESTAMP_TIMEZONE_VALUES.join(\", \")}). Default when unspecified: utc.`,\n parseTimestampTimezoneOption,\n );\n}\n\nfunction normalizeCliArgv(argv: string[]): NormalizedCliArgv {\n const normalized = argv.slice(0, 2);\n let displayPathStyle: CliRuntime[\"displayPathStyle\"] = \"relative\";\n let noColorFlag = false;\n\n for (const arg of argv.slice(2)) {\n if (arg === \"--absolute\" || arg === \"--abs\") {\n displayPathStyle = \"absolute\";\n continue;\n }\n\n if (arg === \"--no-color\") {\n noColorFlag = true;\n continue;\n }\n\n if (arg === \"-V\") {\n normalized.push(\"-v\");\n continue;\n }\n\n normalized.push(arg);\n }\n\n return {\n argv: normalized,\n colorEnabled: resolveCliColorEnabled({ noColorFlag }),\n displayPathStyle,\n };\n}\n\nexport async function runCli(\n argv: string[] = process.argv,\n runtime: RunCliOptions = {},\n): Promise<void> {\n const normalized = normalizeCliArgv(argv);\n const cliRuntime = createRuntime(runtime);\n cliRuntime.colorEnabled = normalized.colorEnabled && (runtime.colorEnabled ?? true);\n cliRuntime.displayPathStyle = runtime.displayPathStyle ?? normalized.displayPathStyle;\n const args = normalized.argv.slice(2);\n\n if (args.length === 0) {\n if (!cliRuntime.stdin.isTTY) {\n cliRuntime.stderr.write(\n \"No arguments provided and interactive mode requires a TTY. Use --help for commands.\\n\",\n );\n process.exitCode = 2;\n return;\n }\n\n try {\n await runInteractiveMode(cliRuntime);\n } catch (error) {\n const cliError = toCliError(error);\n cliRuntime.stderr.write(`${cliError.message}\\n`);\n process.exitCode = cliError.exitCode;\n }\n return;\n }\n\n const program = new Command();\n program\n .name(\"cdx-chores\")\n .description(\"CLI chores toolkit for file/media/document workflow helpers\")\n .showHelpAfterError()\n .option(\"--absolute, --abs\", \"Show absolute paths in CLI output\", false)\n .option(\"--no-color\", \"Disable ANSI colors\", false)\n .version(getFormattedVersionLabel(cliRuntime.colorEnabled), \"-v, --version\", \"Show version information\");\n\n program\n .command(\"interactive\")\n .description(\"Start interactive mode\")\n .action(async () => {\n await runInteractiveMode(cliRuntime);\n });\n\n program\n .command(\"doctor\")\n .description(\"Check tool availability and current feature capabilities\")\n .option(\"--json\", \"Output machine-readable JSON\", false)\n .action(async (options: { json?: boolean }) => {\n await actionDoctor(cliRuntime, { json: options.json });\n });\n\n const dataCommand = program.command(\"data\").description(\"Data preview, query, and conversion utilities\");\n\n applyCommonFileOptions(\n dataCommand\n .command(\"json-to-csv\")\n .description(\"Convert JSON file to CSV\")\n .requiredOption(\"-i, --input <path>\", \"Input JSON file\")\n .action(async (options: { input: string; output?: string; overwrite?: boolean }) => {\n await actionJsonToCsv(cliRuntime, options);\n }),\n );\n\n dataCommand\n .command(\"csv-to-json\")\n .description(\"Convert CSV file to JSON\")\n .requiredOption(\"-i, --input <path>\", \"Input CSV file\")\n .option(\"-o, --output <path>\", \"Output JSON file path\")\n .option(\"--overwrite\", \"Overwrite output file if it already exists\", false)\n .option(\"--pretty\", \"Pretty-print JSON output\", false)\n .action(\n async (options: {\n input: string;\n output?: string;\n overwrite?: boolean;\n pretty?: boolean;\n }) => {\n await actionCsvToJson(cliRuntime, options);\n },\n );\n\n dataCommand\n .command(\"preview\")\n .description(\"Preview CSV or JSON data as a bounded terminal table\")\n .argument(\"<input>\", \"Input CSV or JSON file\")\n .option(\"--rows <value>\", \"Number of rows to show\", (value: string) => parsePositiveIntegerOption(value, \"--rows\"))\n .option(\"--offset <value>\", \"Row offset to start from\", (value: string) =>\n parseNonNegativeIntegerOption(value, \"--offset\"),\n )\n .option(\"--columns <names>\", \"Columns to show (comma-separated)\", collectCsvListOption, [])\n .option(\n \"--contains <column:keyword>\",\n \"Filter rows by case-insensitive substring match on a named column (repeatable; escape ':' as \\\\: and '\\\\' as \\\\\\\\)\",\n collectRepeatedOption,\n [],\n )\n .action(\n async (\n input: string,\n options: {\n columns?: string[];\n contains?: string[];\n offset?: number;\n rows?: number;\n },\n ) => {\n await actionDataPreview(cliRuntime, {\n columns: options.columns,\n contains: options.contains,\n input,\n offset: options.offset,\n rows: options.rows,\n });\n },\n );\n\n const parquetCommand = dataCommand.command(\"parquet\").description(\"DuckDB-backed Parquet preview utilities\");\n\n const duckdbCommand = dataCommand.command(\"duckdb\").description(\"DuckDB extension inspection and setup utilities\");\n\n duckdbCommand\n .command(\"doctor\")\n .description(\"Inspect DuckDB-managed extension state for data query\")\n .option(\"--json\", \"Output machine-readable JSON\", false)\n .action(async (options: { json?: boolean }) => {\n await actionDataDuckDbDoctor(cliRuntime, { json: options.json });\n });\n\n const duckdbExtensionCommand = duckdbCommand\n .command(\"extension\")\n .description(\"Manage DuckDB extensions used by data query\");\n\n duckdbExtensionCommand\n .command(\"install\")\n .description(\"Install a managed DuckDB extension for the current runtime\")\n .argument(\"[name]\", `Extension name (${DUCKDB_MANAGED_EXTENSION_NAMES.join(\", \")})`, parseDuckDbManagedExtensionOption)\n .option(\"--all-supported\", \"Install all managed DuckDB extensions\", false)\n .action(\n async (\n extensionName: DuckDbManagedExtensionName | undefined,\n options: { allSupported?: boolean },\n ) => {\n await actionDataDuckDbExtensionInstall(cliRuntime, {\n allSupported: options.allSupported,\n extensionName,\n });\n },\n );\n\n parquetCommand\n .command(\"preview\")\n .description(\"Preview Parquet data as a bounded terminal table\")\n .argument(\"<input>\", \"Input Parquet file\")\n .option(\"--rows <value>\", \"Number of rows to show\", (value: string) => parsePositiveIntegerOption(value, \"--rows\"))\n .option(\"--offset <value>\", \"Row offset to start from\", (value: string) =>\n parseNonNegativeIntegerOption(value, \"--offset\"),\n )\n .option(\"--columns <names>\", \"Columns to show (comma-separated)\", collectCsvListOption, [])\n .action(\n async (\n input: string,\n options: {\n columns?: string[];\n offset?: number;\n rows?: number;\n },\n ) => {\n await actionDataParquetPreview(cliRuntime, {\n columns: options.columns,\n input,\n offset: options.offset,\n rows: options.rows,\n });\n },\n );\n\n const queryCommand = dataCommand\n .command(\"query\")\n .description(\"Run a DuckDB-backed SQL query against one input file\")\n .argument(\"<input>\", \"Input data file\")\n .option(\"--sql <query>\", \"SQL query to execute against logical table `file`\")\n .option(\n \"--input-format <format>\",\n `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(\", \")})`,\n parseDataQueryInputFormatOption,\n )\n .option(\"--source <name>\", \"Source object name for SQLite tables/views or Excel sheets\")\n .option(\n \"--install-missing-extension\",\n \"Attempt one DuckDB extension install-and-retry for sqlite/excel inputs\",\n false,\n )\n .option(\"--rows <value>\", \"Number of rows to show in bounded table output\", (value: string) =>\n parsePositiveIntegerOption(value, \"--rows\"),\n )\n .option(\"--json\", \"Write full query results as JSON to stdout\", false)\n .option(\"--pretty\", \"Pretty-print JSON stdout or .json file output\", false)\n .option(\"-o, --output <path>\", \"Write full query results to a .json or .csv file\")\n .option(\"--overwrite\", \"Overwrite output file if it already exists\", false)\n .action(\n async (\n input: string,\n options: {\n inputFormat?: DataQueryInputFormat;\n installMissingExtension?: boolean;\n json?: boolean;\n output?: string;\n overwrite?: boolean;\n pretty?: boolean;\n rows?: number;\n source?: string;\n sql: string;\n },\n ) => {\n await actionDataQuery(cliRuntime, {\n input,\n inputFormat: options.inputFormat,\n installMissingExtension: options.installMissingExtension,\n json: options.json,\n output: options.output,\n overwrite: options.overwrite,\n pretty: options.pretty,\n rows: options.rows,\n source: options.source,\n sql: options.sql,\n });\n },\n );\n\n queryCommand\n .command(\"codex\")\n .description(\"Draft SQL from natural-language intent using bounded introspection\")\n .argument(\"<input>\", \"Input data file\")\n .requiredOption(\"--intent <text>\", \"Natural-language query intent for Codex drafting\")\n .option(\n \"--input-format <format>\",\n `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(\", \")})`,\n parseDataQueryInputFormatOption,\n )\n .option(\"--source <name>\", \"Source object name for SQLite tables/views or Excel sheets\")\n .option(\"--print-sql\", \"Write drafted SQL only to stdout\", false)\n .action(\n async (\n input: string,\n options: {\n inputFormat?: DataQueryInputFormat;\n intent: string;\n printSql?: boolean;\n source?: string;\n },\n command: Command,\n ) => {\n const parentOptions = command.parent?.opts<{\n inputFormat?: DataQueryInputFormat;\n source?: string;\n }>();\n await actionDataQueryCodex(cliRuntime, {\n input,\n inputFormat: options.inputFormat ?? parentOptions?.inputFormat,\n intent: options.intent,\n printSql: options.printSql,\n source: options.source ?? parentOptions?.source,\n });\n },\n );\n\n const mdCommand = program.command(\"md\").description(\"Markdown utilities\");\n applyCommonFileOptions(\n mdCommand\n .command(\"to-docx\")\n .description(\"Convert Markdown to DOCX using pandoc\")\n .requiredOption(\"-i, --input <path>\", \"Input Markdown file\")\n .action(async (options: { input: string; output?: string; overwrite?: boolean }) => {\n await actionMdToDocx(cliRuntime, options);\n }),\n );\n mdCommand\n .command(\"frontmatter-to-json\")\n .description(\"Extract Markdown frontmatter to JSON\")\n .requiredOption(\"-i, --input <path>\", \"Input Markdown file\")\n .option(\"-o, --output <path>\", \"Write JSON to file path (default: stdout)\")\n .option(\"--overwrite\", \"Overwrite output file if it already exists\", false)\n .option(\"--pretty\", \"Pretty-print JSON output\", false)\n .option(\"--data-only\", \"Emit only the parsed frontmatter object\", false)\n .action(\n async (options: {\n input: string;\n output?: string;\n overwrite?: boolean;\n pretty?: boolean;\n dataOnly?: boolean;\n }) => {\n await actionMdFrontmatterToJson(cliRuntime, options);\n },\n );\n const renameCommand = program.command(\"rename\").description(\"Rename helpers\");\n const renameFileCommand = renameCommand\n .command(\"file\")\n .description(\"Rename a single file\")\n .argument(\"<path>\", \"Target file path\")\n .option(\"--prefix <value>\", \"Filename prefix (optional)\")\n .option(\"--dry-run\", \"Preview rename plan only\", false)\n .option(\"--codex\", \"Auto-route eligible files to Codex analyzers by file type\", false)\n .option(\n \"--codex-images\",\n \"Use only the Codex image analyzer for supported static image files\",\n false,\n )\n .option(\n \"--codex-images-timeout-ms <ms>\",\n \"Codex image-title generation timeout per request in milliseconds\",\n (value) => Number(value),\n )\n .option(\"--codex-images-retries <count>\", \"Retry failed Codex image-title requests\", (value) =>\n Number(value),\n )\n .option(\n \"--codex-images-batch-size <count>\",\n \"Number of images per Codex image-title request batch\",\n (value) => Number(value),\n )\n .option(\n \"--codex-docs\",\n \"Use only the Codex document analyzer for supported docs (.md, .txt, .json, .yaml, .toml, .xml, .html, .pdf, ...)\",\n false,\n )\n .option(\n \"--codex-docs-timeout-ms <ms>\",\n \"Codex document-title generation timeout per request in milliseconds\",\n (value) => Number(value),\n )\n .option(\"--codex-docs-retries <count>\", \"Retry failed Codex document-title requests\", (value) =>\n Number(value),\n )\n .option(\n \"--codex-docs-batch-size <count>\",\n \"Number of documents per Codex document-title request batch\",\n (value) => Number(value),\n );\n applyRenameTemplateOptions(renameFileCommand);\n renameFileCommand.action(\n async (\n path: string,\n options: {\n prefix?: string;\n pattern?: string;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope?: RenameSerialScope;\n timestampTimezone?: TimestampTimezone;\n dryRun?: boolean;\n codex?: boolean;\n codexImages?: boolean;\n codexImagesTimeoutMs?: number;\n codexImagesRetries?: number;\n codexImagesBatchSize?: number;\n codexDocs?: boolean;\n codexDocsTimeoutMs?: number;\n codexDocsRetries?: number;\n codexDocsBatchSize?: number;\n },\n ) => {\n await actionRenameFile(cliRuntime, {\n path,\n prefix: options.prefix,\n pattern: options.pattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n timestampTimezone: options.timestampTimezone,\n dryRun: options.dryRun,\n codex: options.codex,\n codexImages: options.codexImages,\n codexImagesTimeoutMs: options.codexImagesTimeoutMs,\n codexImagesRetries: options.codexImagesRetries,\n codexImagesBatchSize: options.codexImagesBatchSize,\n codexDocs: options.codexDocs,\n codexDocsTimeoutMs: options.codexDocsTimeoutMs,\n codexDocsRetries: options.codexDocsRetries,\n codexDocsBatchSize: options.codexDocsBatchSize,\n });\n },\n );\n\n const renameBatchCommand = renameCommand\n .command(\"batch\")\n .description(\"Batch rename files in a directory\")\n .argument(\"<directory>\", \"Target directory\")\n .option(\"--prefix <value>\", \"Filename prefix (optional)\")\n .option(\"--profile <name>\", \"Preset file profile: all, images, media, docs\")\n .option(\"--dry-run\", \"Preview rename plan only\", false)\n .option(\"--preview-skips <mode>\", \"Skipped-item preview mode: summary or detailed\")\n .option(\"--recursive\", \"Traverse subdirectories recursively\", false)\n .option(\"--max-depth <value>\", \"Maximum recursive depth (root=0)\", (value) => Number(value))\n .option(\"--match-regex <pattern>\", \"Only include files whose basename matches the regex\")\n .option(\"--skip-regex <pattern>\", \"Exclude files whose basename matches the regex\")\n .option(\n \"--ext <value>\",\n \"Only include file extensions (repeatable or comma-separated)\",\n collectCsvListOption,\n [],\n )\n .option(\n \"--skip-ext <value>\",\n \"Exclude file extensions (repeatable or comma-separated)\",\n collectCsvListOption,\n [],\n )\n .option(\"--codex\", \"Auto-route eligible files to Codex analyzers by file type\", false)\n .option(\n \"--codex-images\",\n \"Use only the Codex image analyzer for supported static image files\",\n false,\n )\n .option(\n \"--codex-images-timeout-ms <ms>\",\n \"Codex image-title generation timeout per request in milliseconds\",\n (value) => Number(value),\n )\n .option(\n \"--codex-images-retries <count>\",\n \"Retry failed Codex image-title requests (per batch)\",\n (value) => Number(value),\n )\n .option(\n \"--codex-images-batch-size <count>\",\n \"Number of images per Codex image-title request batch\",\n (value) => Number(value),\n )\n .option(\n \"--codex-docs\",\n \"Use only the Codex document analyzer for supported docs (.md, .txt, .json, .yaml, .toml, .xml, .html, .pdf, ...)\",\n false,\n )\n .option(\n \"--codex-docs-timeout-ms <ms>\",\n \"Codex document-title generation timeout per request in milliseconds\",\n (value) => Number(value),\n )\n .option(\n \"--codex-docs-retries <count>\",\n \"Retry failed Codex document-title requests (per batch)\",\n (value) => Number(value),\n )\n .option(\n \"--codex-docs-batch-size <count>\",\n \"Number of documents per Codex document-title request batch\",\n (value) => Number(value),\n );\n applyRenameTemplateOptions(renameBatchCommand);\n renameBatchCommand.action(\n async (\n directory: string,\n options: {\n prefix?: string;\n pattern?: string;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope?: RenameSerialScope;\n timestampTimezone?: TimestampTimezone;\n profile?: string;\n dryRun?: boolean;\n previewSkips?: \"summary\" | \"detailed\";\n recursive?: boolean;\n maxDepth?: number;\n matchRegex?: string;\n skipRegex?: string;\n ext?: string[];\n skipExt?: string[];\n codex?: boolean;\n codexImages?: boolean;\n codexImagesTimeoutMs?: number;\n codexImagesRetries?: number;\n codexImagesBatchSize?: number;\n codexDocs?: boolean;\n codexDocsTimeoutMs?: number;\n codexDocsRetries?: number;\n codexDocsBatchSize?: number;\n },\n ) => {\n await actionRenameBatch(cliRuntime, {\n directory,\n prefix: options.prefix,\n pattern: options.pattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n timestampTimezone: options.timestampTimezone,\n profile: options.profile,\n dryRun: options.dryRun,\n previewSkips: options.previewSkips,\n recursive: options.recursive,\n maxDepth: options.maxDepth,\n matchRegex: options.matchRegex,\n skipRegex: options.skipRegex,\n ext: options.ext,\n skipExt: options.skipExt,\n codex: options.codex,\n codexImages: options.codexImages,\n codexImagesTimeoutMs: options.codexImagesTimeoutMs,\n codexImagesRetries: options.codexImagesRetries,\n codexImagesBatchSize: options.codexImagesBatchSize,\n codexDocs: options.codexDocs,\n codexDocsTimeoutMs: options.codexDocsTimeoutMs,\n codexDocsRetries: options.codexDocsRetries,\n codexDocsBatchSize: options.codexDocsBatchSize,\n });\n },\n );\n\n renameCommand\n .command(\"cleanup\")\n .description(\"Normalize existing filenames by explicit hint families\")\n .argument(\"<path>\", \"Target file or directory path\")\n .option(\n \"--hint <value>\",\n \"Cleanup hint family (repeatable or comma-separated): date, timestamp, serial, uid\",\n collectCsvListOption,\n [],\n )\n .option(\n \"--hints <value>\",\n \"Alias for --hint (repeatable or comma-separated): date, timestamp, serial, uid\",\n collectCsvListOption,\n [],\n )\n .option(\n \"--style <value>\",\n \"Cleanup output style: preserve, slug\",\n parseRenameCleanupStyleOption,\n )\n .option(\n \"--timestamp-action <value>\",\n \"Timestamp fragment handling when --hint timestamp is active: keep or remove\",\n parseRenameCleanupTimestampActionOption,\n )\n .option(\n \"--conflict-strategy <value>\",\n \"Cleanup conflict strategy: skip, number, uid-suffix\",\n parseRenameCleanupConflictStrategyOption,\n )\n .option(\"--dry-run\", \"Preview cleanup plan only\", false)\n .option(\"--preview-skips <mode>\", \"Skipped-item preview mode: summary or detailed\")\n .option(\"--recursive\", \"Traverse subdirectories recursively\", false)\n .option(\"--max-depth <value>\", \"Maximum recursive depth (root=0)\", (value) => Number(value))\n .option(\"--match-regex <pattern>\", \"Only include files whose basename matches the regex\")\n .option(\"--skip-regex <pattern>\", \"Exclude files whose basename matches the regex\")\n .option(\n \"--ext <value>\",\n \"Only include file extensions (repeatable or comma-separated)\",\n collectCsvListOption,\n [],\n )\n .option(\n \"--skip-ext <value>\",\n \"Exclude file extensions (repeatable or comma-separated)\",\n collectCsvListOption,\n [],\n )\n .action(\n async (\n path: string,\n options: {\n hint?: string[];\n hints?: string[];\n style?: RenameCleanupStyle;\n timestampAction?: RenameCleanupTimestampAction;\n conflictStrategy?: RenameCleanupConflictStrategy;\n dryRun?: boolean;\n previewSkips?: \"summary\" | \"detailed\";\n recursive?: boolean;\n maxDepth?: number;\n matchRegex?: string;\n skipRegex?: string;\n ext?: string[];\n skipExt?: string[];\n },\n ) => {\n await actionRenameCleanup(cliRuntime, {\n path,\n hints: [...(options.hint ?? []), ...(options.hints ?? [])],\n style: options.style,\n timestampAction: options.timestampAction,\n conflictStrategy: options.conflictStrategy,\n dryRun: options.dryRun,\n previewSkips: options.previewSkips,\n recursive: options.recursive,\n maxDepth: options.maxDepth,\n matchRegex: options.matchRegex,\n skipRegex: options.skipRegex,\n ext: options.ext,\n skipExt: options.skipExt,\n });\n },\n );\n\n renameCommand\n .command(\"apply\")\n .description(\"Apply a previously generated rename plan CSV\")\n .argument(\"<csv>\", \"Rename plan CSV path\")\n .option(\"--auto-clean\", \"Delete the plan CSV after a successful apply\", false)\n .action(async (csv: string, options: { autoClean?: boolean }) => {\n await actionRenameApply(cliRuntime, { csv, autoClean: options.autoClean });\n });\n\n const batchRenameAliasCommand = program\n .command(\"batch-rename\")\n .description(\"Alias for `rename batch`\")\n .argument(\"<directory>\", \"Target directory\")\n .option(\"--prefix <value>\", \"Filename prefix (optional)\")\n .option(\"--profile <name>\", \"Preset file profile: all, images, media, docs\")\n .option(\"--dry-run\", \"Preview rename plan only\", false)\n .option(\"--preview-skips <mode>\", \"Skipped-item preview mode: summary or detailed\")\n .option(\"--recursive\", \"Traverse subdirectories recursively\", false)\n .option(\"--max-depth <value>\", \"Maximum recursive depth (root=0)\", (value) => Number(value))\n .option(\"--match-regex <pattern>\", \"Only include files whose basename matches the regex\")\n .option(\"--skip-regex <pattern>\", \"Exclude files whose basename matches the regex\")\n .option(\n \"--ext <value>\",\n \"Only include file extensions (repeatable or comma-separated)\",\n collectCsvListOption,\n [],\n )\n .option(\n \"--skip-ext <value>\",\n \"Exclude file extensions (repeatable or comma-separated)\",\n collectCsvListOption,\n [],\n )\n .option(\"--codex\", \"Auto-route eligible files to Codex analyzers by file type\", false)\n .option(\n \"--codex-images\",\n \"Use only the Codex image analyzer for supported static image files\",\n false,\n )\n .option(\n \"--codex-images-timeout-ms <ms>\",\n \"Codex image-title generation timeout per request in milliseconds\",\n (value) => Number(value),\n )\n .option(\n \"--codex-images-retries <count>\",\n \"Retry failed Codex image-title requests (per batch)\",\n (value) => Number(value),\n )\n .option(\n \"--codex-images-batch-size <count>\",\n \"Number of images per Codex image-title request batch\",\n (value) => Number(value),\n )\n .option(\n \"--codex-docs\",\n \"Use only the Codex document analyzer for supported docs (.md, .txt, .json, .yaml, .toml, .xml, .html, .pdf, ...)\",\n false,\n )\n .option(\n \"--codex-docs-timeout-ms <ms>\",\n \"Codex document-title generation timeout per request in milliseconds\",\n (value) => Number(value),\n )\n .option(\n \"--codex-docs-retries <count>\",\n \"Retry failed Codex document-title requests (per batch)\",\n (value) => Number(value),\n )\n .option(\n \"--codex-docs-batch-size <count>\",\n \"Number of documents per Codex document-title request batch\",\n (value) => Number(value),\n );\n applyRenameTemplateOptions(batchRenameAliasCommand);\n batchRenameAliasCommand.action(\n async (\n directory: string,\n options: {\n prefix?: string;\n pattern?: string;\n serialOrder?: RenameSerialOrder;\n serialStart?: number;\n serialWidth?: number;\n serialScope?: RenameSerialScope;\n timestampTimezone?: TimestampTimezone;\n profile?: string;\n dryRun?: boolean;\n previewSkips?: \"summary\" | \"detailed\";\n recursive?: boolean;\n maxDepth?: number;\n matchRegex?: string;\n skipRegex?: string;\n ext?: string[];\n skipExt?: string[];\n codex?: boolean;\n codexImages?: boolean;\n codexImagesTimeoutMs?: number;\n codexImagesRetries?: number;\n codexImagesBatchSize?: number;\n codexDocs?: boolean;\n codexDocsTimeoutMs?: number;\n codexDocsRetries?: number;\n codexDocsBatchSize?: number;\n },\n ) => {\n await actionRenameBatch(cliRuntime, {\n directory,\n prefix: options.prefix,\n pattern: options.pattern,\n serialOrder: options.serialOrder,\n serialStart: options.serialStart,\n serialWidth: options.serialWidth,\n serialScope: options.serialScope,\n timestampTimezone: options.timestampTimezone,\n profile: options.profile,\n dryRun: options.dryRun,\n previewSkips: options.previewSkips,\n recursive: options.recursive,\n maxDepth: options.maxDepth,\n matchRegex: options.matchRegex,\n skipRegex: options.skipRegex,\n ext: options.ext,\n skipExt: options.skipExt,\n codex: options.codex,\n codexImages: options.codexImages,\n codexImagesTimeoutMs: options.codexImagesTimeoutMs,\n codexImagesRetries: options.codexImagesRetries,\n codexImagesBatchSize: options.codexImagesBatchSize,\n codexDocs: options.codexDocs,\n codexDocsTimeoutMs: options.codexDocsTimeoutMs,\n codexDocsRetries: options.codexDocsRetries,\n codexDocsBatchSize: options.codexDocsBatchSize,\n });\n },\n );\n\n const videoCommand = program.command(\"video\").description(\"Video utilities (ffmpeg-backed)\");\n videoCommand\n .command(\"convert\")\n .description(\"Convert a video file to another format via ffmpeg\")\n .requiredOption(\"-i, --input <path>\", \"Input video file\")\n .requiredOption(\"-o, --output <path>\", \"Output video file\")\n .option(\"--overwrite\", \"Overwrite output file if it already exists\", false)\n .action(async (options: { input: string; output: string; overwrite?: boolean }) => {\n await actionVideoConvert(cliRuntime, options);\n });\n\n videoCommand\n .command(\"resize\")\n .description(\"Resize video via ffmpeg\")\n .requiredOption(\"-i, --input <path>\", \"Input video file\")\n .requiredOption(\"-o, --output <path>\", \"Output video file\")\n .option(\n \"-s, --scale <factor>\",\n \"Scale factor multiplier (for example 0.5 halves size, 2 doubles it)\",\n (value) => parsePositiveNumberOption(value, \"--scale\"),\n )\n .option(\"--width <px>\", \"Output width in pixels (requires --height)\", (value) =>\n parsePositiveIntegerOption(value, \"--width\"),\n )\n .option(\"--height <px>\", \"Output height in pixels (requires --width)\", (value) =>\n parsePositiveIntegerOption(value, \"--height\"),\n )\n .option(\"--overwrite\", \"Overwrite output file if it already exists\", false)\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Resize modes:\",\n \" Preferred: --scale 0.5\",\n \" Explicit override: --width 1280 --height 720\",\n ].join(\"\\n\"),\n )\n .action(\n async (options: {\n input: string;\n output: string;\n scale?: number;\n width?: number;\n height?: number;\n overwrite?: boolean;\n }) => {\n await actionVideoResize(cliRuntime, options);\n },\n );\n\n videoCommand\n .command(\"gif\")\n .description(\"Convert video to GIF via ffmpeg\")\n .requiredOption(\"-i, --input <path>\", \"Input video file\")\n .option(\"-o, --output <path>\", \"Output GIF file path\")\n .option(\"--width <px>\", \"GIF width\", (value) => Number(value))\n .option(\"--fps <value>\", \"GIF frames per second\", (value) => Number(value))\n .option(\"--overwrite\", \"Overwrite output file if it already exists\", false)\n .action(\n async (options: {\n input: string;\n output?: string;\n width?: number;\n fps?: number;\n overwrite?: boolean;\n }) => {\n await actionVideoGif(cliRuntime, options);\n },\n );\n\n try {\n await program.parseAsync(normalized.argv);\n } catch (error) {\n const cliError = toCliError(error);\n cliRuntime.stderr.write(`${cliError.message}\\n`);\n process.exitCode = cliError.exitCode;\n }\n}\n","import { runCli } from \"./command\";\n\nrunCli().catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(\"Failed to run CLI:\", message);\n process.exitCode = 1;\n});\n"],"x_google_ignoreList":[2],"mappings":"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"}
|