vde-layout 1.0.1 → 1.1.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["yaml","parseCommand","toCommandString","parseCommand","toCommandString","SINGLE_QUOTE","SHELL_SINGLE_QUOTE_ESCAPE","findNewPaneId","resolveSplitOrientationFromStep","resolveSplitPercentageFromStep","input","output","defaultCompilePreset","defaultCompilePresetFromValue","defaultCreateLayoutPlan","defaultEmitPlan"],"sources":["../src/utils/errors.ts","../src/models/schema.ts","../src/config/validator.ts","../src/config/loader.ts","../src/layout/preset.ts","../src/cli/package-version.ts","../src/core/errors.ts","../src/core/compile.ts","../src/core/planner.ts","../src/core/emitter.ts","../src/cli/error-handling.ts","../src/utils/logger.ts","../src/cli/runtime-and-list.ts","../src/executor/real-executor.ts","../src/executor/dry-run-executor.ts","../src/executor/mock-executor.ts","../src/backends/tmux/executor.ts","../src/utils/async.ts","../src/utils/pane-map.ts","../src/executor/split-step.ts","../src/utils/template-tokens.ts","../src/executor/terminal-command-preparation.ts","../src/executor/plan-runner-helpers.ts","../src/executor/plan-runner.ts","../src/executor/step-target.ts","../src/executor/unsupported-step-kind.ts","../src/backends/tmux/backend.ts","../src/backends/wezterm/list-parser.ts","../src/backends/wezterm/cli.ts","../src/backends/wezterm/dry-run.ts","../src/backends/wezterm/layout-resolution.ts","../src/backends/wezterm/pane-map.ts","../src/backends/wezterm/step-execution.ts","../src/backends/wezterm/backend.ts","../src/executor/backend-factory.ts","../src/executor/backend-resolver.ts","../src/cli/command-helpers.ts","../src/cli/user-prompt.ts","../src/cli/window-mode.ts","../src/cli/preset-execution.ts","../src/cli/index.ts","../src/index.ts"],"sourcesContent":["export type VDELayoutError = Error & {\n readonly code: string\n readonly details: Readonly<Record<string, unknown>>\n}\n\nexport const ErrorCodes = {\n CONFIG_NOT_FOUND: \"CONFIG_NOT_FOUND\",\n CONFIG_PARSE_ERROR: \"CONFIG_PARSE_ERROR\",\n CONFIG_PERMISSION_ERROR: \"CONFIG_PERMISSION_ERROR\",\n INVALID_PRESET: \"INVALID_PRESET\",\n PRESET_NOT_FOUND: \"PRESET_NOT_FOUND\",\n INVALID_LAYOUT: \"INVALID_LAYOUT\",\n INVALID_PANE: \"INVALID_PANE\",\n INVALID_PLAN: \"INVALID_PLAN\",\n MISSING_TARGET: \"MISSING_TARGET\",\n TMUX_NOT_RUNNING: \"TMUX_NOT_RUNNING\",\n TMUX_COMMAND_FAILED: \"TMUX_COMMAND_FAILED\",\n NOT_IN_TMUX_SESSION: \"NOT_IN_TMUX_SESSION\",\n TMUX_NOT_FOUND: \"TMUX_NOT_FOUND\",\n TMUX_NOT_INSTALLED: \"TMUX_NOT_INSTALLED\",\n UNSUPPORTED_TMUX_VERSION: \"UNSUPPORTED_TMUX_VERSION\",\n BACKEND_NOT_FOUND: \"BACKEND_NOT_FOUND\",\n TERMINAL_COMMAND_FAILED: \"TERMINAL_COMMAND_FAILED\",\n TEMPLATE_TOKEN_ERROR: \"TEMPLATE_TOKEN_ERROR\",\n WEZTERM_NOT_FOUND: \"WEZTERM_NOT_FOUND\",\n UNSUPPORTED_WEZTERM_VERSION: \"UNSUPPORTED_WEZTERM_VERSION\",\n USER_CANCELLED: \"USER_CANCELLED\",\n} as const\n\nconst createBaseError = (\n name: string,\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n const error = new Error(message) as VDELayoutError\n error.name = name\n ;(error as { code: string }).code = code\n ;(error as { details: Readonly<Record<string, unknown>> }).details = details\n return error\n}\n\nexport const createConfigError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"ConfigError\", message, code, details)\n}\n\nexport const createValidationError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"ValidationError\", message, code, details)\n}\n\nexport const createTmuxError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"TmuxError\", message, code, details)\n}\n\nexport const createEnvironmentError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"EnvironmentError\", message, code, details)\n}\n\nexport const isVDELayoutError = (error: unknown): error is VDELayoutError => {\n if (typeof error !== \"object\" || error === null) {\n return false\n }\n\n if (!(\"code\" in error)) {\n return false\n }\n\n const { code } = error as { code?: unknown }\n if (typeof code !== \"string\") {\n return false\n }\n\n if (!(\"details\" in error)) {\n return false\n }\n\n return true\n}\n\nconst formatters: Record<string, (error: VDELayoutError) => string> = {\n [ErrorCodes.CONFIG_NOT_FOUND]: (error) => {\n const searchPaths = error.details.searchPaths\n if (!Array.isArray(searchPaths)) {\n return \"\"\n }\n\n const lines = [\"\", \"Searched in the following locations:\"]\n searchPaths.forEach((location) => lines.push(` - ${location}`))\n lines.push(\"\", \"To create a configuration file, run:\")\n lines.push(\" mkdir -p ~/.config/vde\")\n lines.push(' echo \"presets: {}\" > ~/.config/vde/layout.yml')\n return lines.join(\"\\n\")\n },\n [ErrorCodes.NOT_IN_TMUX_SESSION]: () => {\n return \"\\nThis command must be run inside a tmux session.\\nStart tmux first with: tmux\\n\"\n },\n [ErrorCodes.TMUX_NOT_INSTALLED]: () => {\n return (\n \"\\ntmux is required but not installed.\\n\" +\n \"Install tmux using your package manager:\\n\" +\n \" - macOS: brew install tmux\\n\" +\n \" - Ubuntu/Debian: sudo apt-get install tmux\\n\" +\n \" - Fedora: sudo dnf install tmux\\n\"\n )\n },\n [ErrorCodes.UNSUPPORTED_TMUX_VERSION]: (error) => {\n const requiredVersion = error.details.requiredVersion\n if (typeof requiredVersion !== \"string\") {\n return \"\"\n }\n return `\\nRequired tmux version: ${requiredVersion} or higher\\n`\n },\n [ErrorCodes.BACKEND_NOT_FOUND]: (error) => {\n const backend = typeof error.details.backend === \"string\" ? error.details.backend : \"terminal backend\"\n const binary = typeof error.details.binary === \"string\" ? error.details.binary : backend\n const suggestion =\n backend === \"wezterm\"\n ? [\n \"\",\n `${backend} is required but not installed.`,\n \"Install wezterm using your package manager:\",\n \" - macOS: brew install --cask wezterm\",\n \" - Ubuntu/Debian: sudo apt-get install wezterm\",\n \" - Fedora: sudo dnf install wezterm\",\n ].join(\"\\n\")\n : \"\"\n return `\\nMissing binary: ${binary}${suggestion}`\n },\n [ErrorCodes.WEZTERM_NOT_FOUND]: () => {\n return (\n \"\\nwezterm command was not found.\\n\" +\n \"Install wezterm using your package manager:\\n\" +\n \" - macOS: brew install --cask wezterm\\n\" +\n \" - Ubuntu/Debian: sudo apt-get install wezterm\\n\" +\n \" - Fedora: sudo dnf install wezterm\\n\"\n )\n },\n [ErrorCodes.UNSUPPORTED_WEZTERM_VERSION]: (error) => {\n const requiredVersion = typeof error.details.requiredVersion === \"string\" ? error.details.requiredVersion : \"\"\n const detected = typeof error.details.detectedVersion === \"string\" ? error.details.detectedVersion : \"\"\n const lines = [\"\", \"Unsupported wezterm version detected.\"]\n if (detected) {\n lines.push(`Detected version: ${detected}`)\n }\n if (requiredVersion) {\n lines.push(`Required version: ${requiredVersion} or higher`)\n }\n return lines.join(\"\\n\")\n },\n}\n\nexport const formatError = (error: Error): string => {\n if (!isVDELayoutError(error)) {\n return `${error.name}: ${error.message}`\n }\n\n let message = `Error: ${error.message}`\n\n const formatter = formatters[error.code]\n if (formatter) {\n message += `\\n${formatter(error)}`\n }\n\n const commandDetail = error.details.command\n if (commandDetail !== undefined) {\n message += `\\nCommand: ${JSON.stringify(commandDetail)}`\n }\n\n const stderrDetail = error.details.stderr\n if (stderrDetail !== undefined) {\n message += `\\nstderr: ${String(stderrDetail)}`\n }\n\n const presetDetail = error.details.preset\n if (presetDetail !== undefined) {\n message += `\\npreset: ${String(presetDetail)}`\n }\n\n const nestedErrors = error.details.errors\n if (Array.isArray(nestedErrors) && nestedErrors.length > 0) {\n message += \"\\nValidation errors:\\n\"\n nestedErrors.forEach((item) => {\n message += ` - ${String(item)}\\n`\n })\n }\n\n return message\n}\n","import { z } from \"zod\"\n\nexport const WindowModeSchema = z.enum([\"new-window\", \"current-window\"])\nconst TerminalBackendSchema = z.enum([\"tmux\", \"wezterm\"])\n\n// Terminal pane schema\nconst TerminalPaneSchema = z\n .object({\n name: z.string().min(1),\n command: z.string().optional(),\n cwd: z.string().optional(),\n env: z.record(z.string()).optional(),\n delay: z.number().int().positive().optional(),\n title: z.string().optional(),\n focus: z.boolean().optional(),\n ephemeral: z.boolean().optional(),\n closeOnError: z.boolean().optional(),\n })\n .strict()\n\n// Split container schema (recursive)\nconst SplitPaneSchema: z.ZodType<unknown> = z.lazy(() =>\n z\n .object({\n type: z.enum([\"horizontal\", \"vertical\"]),\n ratio: z.array(z.number().positive()).min(1),\n panes: z.array(PaneSchema).min(1),\n })\n .strict()\n .refine((data) => data.ratio.length === data.panes.length, {\n message: \"Number of elements in ratio array does not match number of elements in panes array\",\n }),\n)\n\n// Recursive Pane schema definition\nexport const PaneSchema: z.ZodType<unknown> = z.lazy(() => z.union([SplitPaneSchema, TerminalPaneSchema]))\n\n// Layout schema definition\nexport const LayoutSchema = z\n .object({\n type: z.enum([\"horizontal\", \"vertical\"]),\n ratio: z.array(z.number().positive()).min(1),\n panes: z.array(PaneSchema).min(1),\n })\n .refine((data) => data.ratio.length === data.panes.length, {\n message: \"Number of elements in ratio array does not match number of elements in panes array\",\n })\n\n// Preset schema definition\nexport const PresetSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n layout: LayoutSchema.optional(),\n command: z.string().optional(),\n windowMode: WindowModeSchema.optional(),\n backend: TerminalBackendSchema.optional(),\n})\n\n// Config schema definition\nexport const ConfigSchema = z.object({\n defaults: z\n .object({\n windowMode: WindowModeSchema.optional(),\n })\n .optional(),\n presets: z.record(PresetSchema),\n})\n\n// Validation result type\ntype ValidationResult<T> = {\n success: boolean\n data?: T\n error?: string\n}\n\n// Helper function to format Zod errors consistently\nconst formatValidationError = (error: z.ZodError): string => {\n const messages = error.errors.map((e) => {\n const path = e.path.join(\".\")\n const message = e.message\n\n // Customize error message for panes array element count check\n if (path === \"layout.panes\" && message.includes(\"at least 2 element\")) {\n return `${path}: panes array must have at least 2 elements`\n }\n\n return `${path}: ${message}`\n })\n\n return messages.join(\"\\n\")\n}\n\n// Config validation\nexport const validateConfig = (data: unknown): ValidationResult<z.infer<typeof ConfigSchema>> => {\n try {\n const parsed = ConfigSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n\n// Preset validation\nexport const validatePreset = (data: unknown): ValidationResult<z.infer<typeof PresetSchema>> => {\n try {\n const parsed = PresetSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n\n// Pane validation\nexport const validatePane = (data: unknown): ValidationResult<z.infer<typeof PaneSchema>> => {\n try {\n const parsed = PaneSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n","import * as YAML from \"yaml\"\nimport { z } from \"zod\"\nimport { ConfigSchema } from \"../models/schema\"\nimport type { Config } from \"../models/types\"\nimport { createValidationError, ErrorCodes, isVDELayoutError } from \"../utils/errors\"\n\n/**\n * Parse YAML text into an object\n * @param yamlText - YAML text to parse\n * @returns Parsed object\n * @throws {ValidationError} When YAML parsing fails\n */\nconst parseYAML = (yamlText: string): unknown => {\n // Input validation\n if (!yamlText || typeof yamlText !== \"string\") {\n throw createValidationError(\"YAML text not provided\", ErrorCodes.CONFIG_PARSE_ERROR, {\n received: typeof yamlText,\n })\n }\n\n try {\n return YAML.parse(yamlText)\n } catch (error) {\n throw createValidationError(\"Failed to parse YAML\", ErrorCodes.CONFIG_PARSE_ERROR, {\n parseError: error instanceof Error ? error.message : String(error),\n yamlSnippet: yamlText.substring(0, 200),\n })\n }\n}\n\n/**\n * Validate basic configuration structure\n * @param parsed - Parsed YAML object\n * @throws {ValidationError} When structure is invalid\n */\nconst validateConfigStructure = (parsed: unknown): void => {\n // Check for empty YAML\n if (parsed === null || parsed === undefined || typeof parsed !== \"object\") {\n throw createValidationError(\"YAML is empty or invalid format\", ErrorCodes.CONFIG_PARSE_ERROR, {\n parsed: parsed,\n })\n }\n\n // Check for presets field existence\n const parsedObj = parsed as Record<string, unknown>\n if (!(\"presets\" in parsedObj) || parsedObj.presets === undefined || parsedObj.presets === null) {\n throw createValidationError(\"presets field is required\", ErrorCodes.INVALID_PRESET, {\n availableFields: Object.keys(parsedObj),\n })\n }\n\n // Check for empty presets\n const presetsObj = parsedObj.presets\n if (typeof presetsObj !== \"object\" || presetsObj === null || Object.keys(presetsObj).length === 0) {\n throw createValidationError(\"At least one preset is required\", ErrorCodes.INVALID_PRESET, {\n presets: presetsObj,\n })\n }\n}\n\n/**\n * Format Zod validation errors into user-friendly messages\n * @param error - Zod validation error\n * @returns Formatted error issues\n */\nconst formatZodErrors = (error: z.ZodError): Array<{ path: string; message: string; code: string }> => {\n return error.issues.map((issue) => {\n const path = issue.path.join(\".\")\n let message = issue.message\n\n // Custom error messages\n if (issue.code === \"invalid_type\") {\n if (issue.path.includes(\"command\") && issue.expected === \"string\") {\n message = \"command field must be a string\"\n } else if (issue.path.includes(\"workingDirectory\") && issue.expected === \"string\") {\n message = \"workingDirectory field must be a string\"\n } else if (issue.received === \"number\" && issue.expected === \"string\") {\n message = `${path} must be a string`\n } else if (issue.received === \"array\" && issue.expected === \"string\") {\n message = `${path} must be a string`\n }\n } else if (issue.code === \"invalid_union\") {\n // Detailed error messages for union types\n const unionIssue = issue as z.ZodIssue & { unionErrors?: z.ZodError[] }\n if (unionIssue.unionErrors !== undefined) {\n // When command is missing in terminal pane\n const terminalError = unionIssue.unionErrors.find(\n (e) => e.issues?.some((i) => i.path.includes(\"command\") && i.code === \"invalid_type\") === true,\n )\n if (terminalError !== undefined) {\n message = \"command field is required\"\n } else {\n // When panes is missing in split pane\n const splitError = unionIssue.unionErrors.find(\n (e) => e.issues?.some((i) => i.path.includes(\"panes\") && i.code === \"invalid_type\") === true,\n )\n if (splitError !== undefined) {\n message = \"panes field is required\"\n } else {\n message = 'Pane type must be \"terminal\" or \"split\"'\n }\n }\n } else {\n message = 'Pane type must be \"terminal\" or \"split\"'\n }\n } else if (issue.code === \"invalid_literal\") {\n if (issue.path.includes(\"direction\")) {\n message = 'direction must be \"horizontal\" or \"vertical\"'\n }\n } else if (issue.message.includes(\"required\")) {\n // Use the message as is\n message = issue.message\n } else if (issue.code === \"custom\" && issue.message.includes(\"ratio array\")) {\n message = issue.message\n } else if (issue.code === \"too_small\" && issue.message.includes(\"Array must contain at least\")) {\n // Minimum array elements error\n if (path.includes(\"panes\")) {\n message = \"panes array must contain at least 2 elements\"\n } else if (path.includes(\"ratio\")) {\n message = \"ratio array must contain at least 2 elements\"\n } else {\n message = issue.message\n }\n }\n\n return {\n path,\n message,\n code: issue.code,\n }\n })\n}\n\n/**\n * Validates YAML text and converts it to a type-safe Config object\n * @param yamlText - YAML text to validate\n * @returns Validated Config object\n * @throws {ValidationError} When YAML is invalid\n */\nexport const validateYAML = (yamlText: string): Config => {\n // Parse YAML\n const parsed = parseYAML(yamlText)\n\n // Validate basic structure\n validateConfigStructure(parsed)\n\n // Ratio sum validation removed - unnecessary due to automatic normalization\n\n // Validation with Zod schema\n try {\n const validated = ConfigSchema.parse(parsed)\n return validated\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = formatZodErrors(error)\n\n // Use the first error message as the primary message\n const primaryMessage = issues.length > 0 && issues[0] ? issues[0].message : \"Configuration validation failed\"\n\n throw createValidationError(primaryMessage, ErrorCodes.CONFIG_PARSE_ERROR, {\n issues,\n rawErrors: error.issues,\n })\n }\n\n if (isVDELayoutError(error) && error.name === \"ValidationError\") {\n throw error\n }\n\n // Other errors\n throw createValidationError(\"Unexpected validation error occurred\", ErrorCodes.CONFIG_PARSE_ERROR, {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n","import fs from \"fs-extra\"\nimport path from \"path\"\nimport os from \"os\"\nimport * as yaml from \"yaml\"\nimport type { Config } from \"../models/types\"\nimport { createConfigError, ErrorCodes } from \"../utils/errors\"\nimport { validateYAML } from \"./validator\"\n\nexport type ConfigLoaderOptions = {\n readonly configPaths?: string[]\n readonly onWarning?: (message: string) => void\n}\n\nexport type ConfigLoader = {\n readonly loadYAML: () => Promise<string>\n readonly loadConfig: () => Promise<Config>\n readonly findConfigFile: () => Promise<string | null>\n readonly getSearchPaths: () => string[]\n}\n\nexport const createConfigLoader = (options: ConfigLoaderOptions = {}): ConfigLoader => {\n const explicitConfigPaths = options.configPaths\n const emitWarning: (message: string) => void = options.onWarning ?? ((message: string): void => console.warn(message))\n\n const computeCachedSearchPaths = (): string[] => {\n if (explicitConfigPaths && explicitConfigPaths.length > 0) {\n return [...explicitConfigPaths]\n }\n\n const candidates: string[] = []\n const projectCandidate = findProjectConfigCandidate()\n if (projectCandidate !== null) {\n candidates.push(projectCandidate)\n }\n\n candidates.push(...buildDefaultSearchPaths())\n\n return [...new Set(candidates)]\n }\n\n const loadConfig = async (): Promise<Config> => {\n if (explicitConfigPaths && explicitConfigPaths.length > 0) {\n const filePath = await findFirstExisting(explicitConfigPaths)\n if (filePath === null) {\n throw createConfigError(\"Configuration file not found\", ErrorCodes.CONFIG_NOT_FOUND, {\n searchPaths: explicitConfigPaths,\n })\n }\n\n const content = await safeReadFile(filePath)\n return validateYAML(content)\n }\n\n const searchPaths = computeCachedSearchPaths()\n const existingPaths = await filterExistingPaths(searchPaths)\n\n if (existingPaths.length === 0) {\n throw createConfigError(\"Configuration file not found\", ErrorCodes.CONFIG_NOT_FOUND, {\n searchPaths,\n })\n }\n\n const projectPath = findProjectConfigCandidate()\n const globalPaths = existingPaths.filter((filePath) => filePath !== projectPath)\n\n let mergedConfig: Config = { presets: {} }\n\n for (const globalPath of globalPaths) {\n const content = await safeReadFile(globalPath)\n const config = validateYAML(content)\n mergedConfig = mergeConfigs(mergedConfig, config, emitWarning)\n }\n\n if (projectPath !== null && (await fs.pathExists(projectPath))) {\n const content = await safeReadFile(projectPath)\n const config = validateYAML(content)\n mergedConfig = mergeConfigs(mergedConfig, config, emitWarning)\n }\n\n return mergedConfig\n }\n\n return {\n loadYAML: async (): Promise<string> => {\n const config = await loadConfig()\n return yaml.stringify(config)\n },\n loadConfig,\n findConfigFile: async (): Promise<string | null> => {\n const searchPaths =\n explicitConfigPaths && explicitConfigPaths.length > 0 ? [...explicitConfigPaths] : computeCachedSearchPaths()\n\n for (const searchPath of searchPaths) {\n if (await fs.pathExists(searchPath)) {\n return searchPath\n }\n }\n return null\n },\n getSearchPaths: (): string[] => computeCachedSearchPaths(),\n }\n}\n\nconst buildDefaultSearchPaths = (): string[] => {\n const paths: string[] = []\n\n const vdeConfigPath = process.env.VDE_CONFIG_PATH\n if (vdeConfigPath !== undefined) {\n paths.push(path.join(vdeConfigPath, \"layout.yml\"))\n }\n\n const homeDir = process.env.HOME ?? os.homedir()\n const xdgConfigHome = process.env.XDG_CONFIG_HOME ?? path.join(homeDir, \".config\")\n paths.push(path.join(xdgConfigHome, \"vde\", \"layout.yml\"))\n\n return [...new Set(paths)]\n}\n\nconst findProjectConfigCandidate = (): string | null => {\n let currentDir = process.cwd()\n const { root } = path.parse(currentDir)\n\n while (true) {\n const candidate = path.join(currentDir, \".vde\", \"layout.yml\")\n if (fs.existsSync(candidate)) {\n return candidate\n }\n\n if (currentDir === root) {\n break\n }\n\n const parent = path.dirname(currentDir)\n if (parent === currentDir) {\n break\n }\n\n currentDir = parent\n }\n\n return null\n}\n\nconst findFirstExisting = async (paths: ReadonlyArray<string>): Promise<string | null> => {\n for (const candidate of paths) {\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return null\n}\n\nconst filterExistingPaths = async (paths: ReadonlyArray<string>): Promise<string[]> => {\n const existing: string[] = []\n for (const candidate of paths) {\n if (await fs.pathExists(candidate)) {\n existing.push(candidate)\n }\n }\n return existing\n}\n\nconst safeReadFile = async (filePath: string): Promise<string> => {\n try {\n return await fs.readFile(filePath, \"utf8\")\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw createConfigError(`Failed to read configuration file`, ErrorCodes.CONFIG_PERMISSION_ERROR, {\n filePath,\n error: errorMessage,\n })\n }\n}\n\nconst mergeConfigs = (base: Config, override: Config, emitWarning: (message: string) => void): Config => {\n const mergedPresets: Config[\"presets\"] = { ...base.presets }\n\n for (const [presetKey, overridePreset] of Object.entries(override.presets)) {\n const basePreset = base.presets[presetKey]\n if (\n basePreset !== undefined &&\n basePreset.windowMode !== undefined &&\n overridePreset.windowMode !== undefined &&\n basePreset.windowMode !== overridePreset.windowMode\n ) {\n emitWarning(\n `[vde-layout] Preset \"${presetKey}\" windowMode conflict: \"${basePreset.windowMode}\" overridden by \"${overridePreset.windowMode}\"`,\n )\n }\n mergedPresets[presetKey] = overridePreset\n }\n\n const baseDefaults = base.defaults\n const overrideDefaults = override.defaults\n\n if (\n baseDefaults?.windowMode !== undefined &&\n overrideDefaults?.windowMode !== undefined &&\n baseDefaults.windowMode !== overrideDefaults.windowMode\n ) {\n emitWarning(\n `[vde-layout] defaults.windowMode conflict: \"${baseDefaults.windowMode}\" overridden by \"${overrideDefaults.windowMode}\"`,\n )\n }\n\n const mergedDefaults =\n baseDefaults !== undefined || overrideDefaults !== undefined\n ? {\n ...(baseDefaults ?? {}),\n ...(overrideDefaults ?? {}),\n }\n : undefined\n\n return mergedDefaults === undefined\n ? {\n presets: mergedPresets,\n }\n : {\n defaults: mergedDefaults,\n presets: mergedPresets,\n }\n}\n","import { createConfigLoader, type ConfigLoaderOptions } from \"../config/loader\"\nimport { createConfigError, ErrorCodes } from \"../utils/errors\"\nimport type { Config, Preset, PresetInfo } from \"../models/types\"\nimport type { PresetManager } from \"../contracts\"\n\ntype PresetState = {\n setConfigPath: (filePath: string) => void\n loadConfig: () => Promise<void>\n getPreset: (name: string) => Preset\n listPresets: () => PresetInfo[]\n getDefaultPreset: () => Preset\n getDefaults: () => Config[\"defaults\"] | undefined\n}\n\nconst createState = (options: ConfigLoaderOptions = {}): PresetState => {\n let loaderOptions: ConfigLoaderOptions = options\n let cachedConfig: Config | null = null\n\n const setConfigPath = (filePath: string): void => {\n loaderOptions = { configPaths: [filePath] }\n cachedConfig = null\n }\n\n const loadConfig = async (): Promise<void> => {\n const loader = createConfigLoader(loaderOptions)\n cachedConfig = await loader.loadConfig()\n }\n\n const ensureConfig = (): Config => {\n if (cachedConfig === null) {\n throw createConfigError(\"Configuration not loaded\", ErrorCodes.CONFIG_NOT_FOUND)\n }\n return cachedConfig\n }\n\n const getPreset = (name: string): Preset => {\n const config = ensureConfig()\n const preset = config.presets[name]\n if (preset === undefined) {\n throw createConfigError(`Preset \"${name}\" not found`, ErrorCodes.PRESET_NOT_FOUND, {\n availablePresets: Object.keys(config.presets),\n })\n }\n return preset\n }\n\n const listPresets = (): PresetInfo[] => {\n if (cachedConfig === null) {\n return []\n }\n\n return Object.entries(cachedConfig.presets).map(([key, preset]) => ({\n key,\n name: preset.name,\n description: preset.description,\n }))\n }\n\n const getDefaultPreset = (): Preset => {\n const config = ensureConfig()\n\n if (config.presets.default !== undefined) {\n return config.presets.default\n }\n\n const firstKey = Object.keys(config.presets)[0]\n if (typeof firstKey !== \"string\" || firstKey.length === 0) {\n throw createConfigError(\"No presets defined\", ErrorCodes.PRESET_NOT_FOUND)\n }\n\n return config.presets[firstKey]!\n }\n\n const getDefaults = (): Config[\"defaults\"] | undefined => {\n const config = ensureConfig()\n return config.defaults\n }\n\n return {\n setConfigPath,\n loadConfig,\n getPreset,\n listPresets,\n getDefaultPreset,\n getDefaults,\n }\n}\n\nexport const createPresetManager = (options: ConfigLoaderOptions = {}): PresetManager => {\n const state = createState(options)\n return {\n setConfigPath: state.setConfigPath,\n loadConfig: state.loadConfig,\n getPreset: state.getPreset,\n listPresets: state.listPresets,\n getDefaultPreset: state.getDefaultPreset,\n getDefaults: state.getDefaults,\n }\n}\n","type PackageJsonModule = {\n readonly version: string\n}\n\ntype ModuleLoadError = Error & {\n readonly code?: string\n}\n\nconst CANDIDATE_PATHS = [\"../package.json\", \"../../package.json\"] as const\n\nconst isModuleNotFoundError = (error: unknown): error is ModuleLoadError => {\n return error instanceof Error && (error as ModuleLoadError).code === \"MODULE_NOT_FOUND\"\n}\n\nexport const loadPackageVersion = (requireFn: NodeJS.Require): string => {\n let lastNotFound: ModuleLoadError | undefined\n\n for (const path of CANDIDATE_PATHS) {\n try {\n return (requireFn(path) as PackageJsonModule).version\n } catch (error) {\n if (isModuleNotFoundError(error)) {\n lastNotFound = error\n continue\n }\n\n throw error\n }\n }\n\n throw lastNotFound ?? new Error(`Unable to resolve package version from candidates: ${CANDIDATE_PATHS.join(\", \")}`)\n}\n","type CoreErrorKind = \"compile\" | \"plan\" | \"emit\" | \"execution\"\n\nexport type CoreError = {\n readonly kind: CoreErrorKind\n readonly code: string\n readonly message: string\n readonly source?: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n}\n\nexport const createCoreError = (\n kind: CoreErrorKind,\n error: {\n readonly code: string\n readonly message: string\n readonly source?: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n },\n): CoreError => ({\n kind,\n code: error.code,\n message: error.message,\n source: error.source,\n path: error.path,\n details: error.details,\n})\n\nexport const isCoreError = (value: unknown): value is CoreError => {\n if (typeof value !== \"object\" || value === null) {\n return false\n }\n const candidate = value as Partial<CoreError>\n return (\n (candidate.kind === \"compile\" ||\n candidate.kind === \"plan\" ||\n candidate.kind === \"emit\" ||\n candidate.kind === \"execution\") &&\n typeof candidate.code === \"string\" &&\n typeof candidate.message === \"string\"\n )\n}\n","import { parse } from \"yaml\"\nimport { z } from \"zod\"\nimport { LayoutSchema } from \"../models/schema\"\nimport { createCoreError, type CoreError } from \"./errors\"\n\nexport type CompilePresetInput = {\n readonly document: string\n readonly source: string\n}\n\nexport type CompilePresetFromValueInput = {\n readonly value: unknown\n readonly source: string\n}\n\nexport type CompiledTerminalPane = {\n readonly kind: \"terminal\"\n readonly name: string\n readonly command?: string\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly delay?: number\n readonly title?: string\n readonly focus?: boolean\n readonly ephemeral?: boolean\n readonly closeOnError?: boolean\n readonly options?: Readonly<Record<string, unknown>>\n}\n\nexport type CompiledSplitPane = {\n readonly kind: \"split\"\n readonly orientation: \"horizontal\" | \"vertical\"\n readonly ratio: ReadonlyArray<number>\n readonly panes: ReadonlyArray<CompiledLayoutNode>\n}\n\nexport type CompiledLayoutNode = CompiledTerminalPane | CompiledSplitPane\n\ntype CompiledPresetMetadata = {\n readonly source: string\n}\n\nexport type CompiledPreset = {\n readonly name: string\n readonly version: string\n readonly command?: string\n readonly layout?: CompiledLayoutNode\n readonly metadata: CompiledPresetMetadata\n}\n\nexport type CompilePresetSuccess = {\n readonly preset: CompiledPreset\n}\n\nexport const compilePreset = ({ document, source }: CompilePresetInput): CompilePresetSuccess => {\n let parsed: unknown\n try {\n parsed = parse(document)\n } catch (error) {\n throw compileError(\"PRESET_PARSE_ERROR\", {\n source,\n message: `Failed to parse YAML: ${(error as Error).message}`,\n details: {\n reason: error instanceof Error ? error.message : String(error),\n },\n })\n }\n\n return compilePresetValue({ value: parsed, source })\n}\n\nexport const compilePresetFromValue = ({ value, source }: CompilePresetFromValueInput): CompilePresetSuccess => {\n return compilePresetValue({ value, source })\n}\n\nconst compilePresetValue = ({ value, source }: CompilePresetFromValueInput): CompilePresetSuccess => {\n const parsed = value\n\n if (!isRecord(parsed)) {\n throw compileError(\"PRESET_INVALID_DOCUMENT\", {\n source,\n message: \"Preset definition is not an object\",\n path: \"preset\",\n })\n }\n\n const name = typeof parsed.name === \"string\" && parsed.name.trim().length > 0 ? parsed.name : \"Unnamed preset\"\n const validatedLayout = validateLayoutDefinition(parsed.layout, {\n source,\n path: \"preset.layout\",\n })\n\n const layout = parseLayoutNode(validatedLayout, {\n source,\n path: \"preset.layout\",\n })\n\n return {\n preset: {\n name,\n version: \"legacy\",\n command: typeof parsed.command === \"string\" ? parsed.command : undefined,\n layout: layout ?? undefined,\n metadata: { source },\n },\n }\n}\n\nconst validateLayoutDefinition = (\n layout: unknown,\n context: { readonly source: string; readonly path: string },\n): unknown => {\n if (layout === undefined || layout === null) {\n return layout\n }\n\n if (!isRecord(layout) || !looksSplitLikeNode(layout)) {\n return layout\n }\n\n const normalizedLayout = sanitizeLayoutForSchemaValidation(layout)\n const validated = LayoutSchema.safeParse(normalizedLayout)\n if (validated.success) {\n return layout\n }\n\n const issue = validated.error.issues[0]\n if (!issue) {\n throw compileError(\"LAYOUT_INVALID_NODE\", {\n source: context.source,\n message: \"Layout node is invalid\",\n path: context.path,\n details: { layout },\n })\n }\n\n throw convertLayoutIssueToCompileError({\n issue,\n source: context.source,\n basePath: context.path,\n layout,\n })\n}\n\nconst parseLayoutNode = (\n node: unknown,\n context: { readonly source: string; readonly path: string },\n): CompiledLayoutNode | null => {\n if (node === undefined || node === null) {\n return null\n }\n\n if (!isRecord(node)) {\n throw compileError(\"LAYOUT_INVALID_NODE\", {\n source: context.source,\n message: \"Layout node is invalid\",\n path: context.path,\n details: { node },\n })\n }\n\n if (\"type\" in node || \"ratio\" in node || \"panes\" in node) {\n return parseSplitPane(node, context)\n }\n\n if (typeof node.name === \"string\") {\n return parseTerminalPane(node)\n }\n\n throw compileError(\"LAYOUT_INVALID_NODE\", {\n source: context.source,\n message: \"Layout node is invalid\",\n path: context.path,\n details: { node },\n })\n}\n\nconst parseSplitPane = (\n node: Record<string, unknown>,\n context: { readonly source: string; readonly path: string },\n): CompiledSplitPane => {\n const orientation = node.type\n const panesInput = node.panes\n const ratioInput = node.ratio\n if (\n (orientation !== \"horizontal\" && orientation !== \"vertical\") ||\n !Array.isArray(panesInput) ||\n !Array.isArray(ratioInput)\n ) {\n throw compileError(\"LAYOUT_INVALID_NODE\", {\n source: context.source,\n message: \"Layout node is invalid\",\n path: context.path,\n details: { node },\n })\n }\n\n const panes = panesInput.map((child, index) =>\n parseLayoutNode(child, {\n source: context.source,\n path: `${context.path}.panes[${index}]`,\n }),\n )\n const ratio = ratioInput.map((value): number => Number(value))\n\n return {\n kind: \"split\",\n orientation,\n ratio,\n panes: panes.filter((pane): pane is CompiledLayoutNode => pane !== null),\n }\n}\n\nconst parseTerminalPane = (node: Record<string, unknown>): CompiledTerminalPane => {\n const name = typeof node.name === \"string\" ? node.name : \"\"\n const command = typeof node.command === \"string\" ? node.command : undefined\n const cwd = typeof node.cwd === \"string\" ? node.cwd : undefined\n const delay = typeof node.delay === \"number\" && Number.isFinite(node.delay) && node.delay > 0 ? node.delay : undefined\n const title = typeof node.title === \"string\" && node.title.length > 0 ? node.title : undefined\n const focus = node.focus === true ? true : undefined\n const ephemeral = node.ephemeral === true ? true : undefined\n const closeOnError = node.closeOnError === true ? true : undefined\n const env = normalizeEnv(node.env)\n\n const knownKeys = new Set([\n \"name\",\n \"command\",\n \"cwd\",\n \"env\",\n \"focus\",\n \"ephemeral\",\n \"closeOnError\",\n \"options\",\n \"title\",\n \"delay\",\n ])\n const options = collectOptions(node, knownKeys)\n\n return {\n kind: \"terminal\",\n name,\n command,\n cwd,\n env,\n delay,\n title,\n focus,\n ephemeral,\n closeOnError,\n options,\n }\n}\n\nconst normalizeEnv = (env: unknown): Readonly<Record<string, string>> | undefined => {\n if (!isRecord(env)) {\n return undefined\n }\n\n const entries = Object.entries(env).reduce<Record<string, string>>((accumulator, [key, value]) => {\n if (typeof value === \"string\") {\n accumulator[key] = value\n }\n return accumulator\n }, {})\n\n return Object.keys(entries).length > 0 ? entries : undefined\n}\n\nconst collectOptions = (\n node: Record<string, unknown>,\n excludedKeys: ReadonlySet<string>,\n): Readonly<Record<string, unknown>> | undefined => {\n const optionsEntries = Object.entries(node).filter(([key]) => !excludedKeys.has(key))\n if (optionsEntries.length === 0) {\n return undefined\n }\n\n return optionsEntries.reduce<Record<string, unknown>>((accumulator, [key, value]) => {\n accumulator[key] = value\n return accumulator\n }, {})\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null\n}\n\nconst looksSplitLikeNode = (value: Record<string, unknown>): boolean => {\n return \"type\" in value || \"ratio\" in value || \"panes\" in value\n}\n\nconst sanitizeLayoutForSchemaValidation = (node: unknown): unknown => {\n if (!isRecord(node)) {\n return node\n }\n\n if (looksSplitLikeNode(node)) {\n const panes = Array.isArray(node.panes)\n ? node.panes.map((child) => sanitizeLayoutForSchemaValidation(child))\n : node.panes\n return {\n type: node.type,\n ratio: node.ratio,\n panes,\n }\n }\n\n return {\n name: node.name,\n command: node.command,\n cwd: node.cwd,\n env: normalizeEnv(node.env),\n delay: node.delay,\n title: node.title,\n focus: node.focus,\n ephemeral: node.ephemeral,\n closeOnError: node.closeOnError,\n }\n}\n\nconst convertLayoutIssueToCompileError = ({\n issue,\n source,\n basePath,\n layout,\n}: {\n readonly issue: z.ZodIssue\n readonly source: string\n readonly basePath: string\n readonly layout: unknown\n}): CoreError => {\n if (isMissingArrayIssue(issue, \"panes\")) {\n return compileError(\"LAYOUT_PANES_MISSING\", {\n source,\n message: \"panes array is missing or empty\",\n path: `${basePath}.panes`,\n })\n }\n\n if (isMissingArrayIssue(issue, \"ratio\")) {\n return compileError(\"LAYOUT_RATIO_MISSING\", {\n source,\n message: \"ratio array is missing or empty\",\n path: `${basePath}.ratio`,\n })\n }\n\n if (issue.path.includes(\"type\")) {\n return compileError(\"LAYOUT_INVALID_ORIENTATION\", {\n source,\n message: \"layout.type must be horizontal or vertical\",\n path: `${basePath}.type`,\n details: {\n type: getValueAtPath(layout, issue.path),\n },\n })\n }\n\n if (issue.message.includes(\"Number of elements in ratio array does not match number of elements in panes array\")) {\n return compileError(\"LAYOUT_RATIO_MISMATCH\", {\n source,\n message: \"ratio and panes arrays must have the same length\",\n path: basePath,\n details: getRatioLengthDetails(layout),\n })\n }\n\n if (issue.path.includes(\"ratio\")) {\n return compileError(\"RATIO_INVALID_VALUE\", {\n source,\n message: \"ratio value must be a positive number\",\n path: formatPath(basePath, issue.path),\n details: {\n value: getValueAtPath(layout, issue.path),\n },\n })\n }\n\n return compileError(\"LAYOUT_INVALID_NODE\", {\n source,\n message: \"Layout node is invalid\",\n path: formatPath(basePath, issue.path),\n details: {\n issue: issue.message,\n node: getValueAtPath(layout, issue.path),\n },\n })\n}\n\nconst isMissingArrayIssue = (issue: z.ZodIssue, field: \"panes\" | \"ratio\"): boolean => {\n if (issue.path.length !== 1 || issue.path[0] !== field) {\n return false\n }\n\n return issue.code === \"invalid_type\" || (issue.code === \"too_small\" && issue.type === \"array\")\n}\n\nconst getRatioLengthDetails = (layout: unknown): Readonly<Record<string, unknown>> | undefined => {\n if (!isRecord(layout)) {\n return undefined\n }\n\n const ratio = layout.ratio\n const panes = layout.panes\n if (!Array.isArray(ratio) || !Array.isArray(panes)) {\n return undefined\n }\n\n return {\n ratioLength: ratio.length,\n panesLength: panes.length,\n }\n}\n\nconst formatPath = (basePath: string, path: ReadonlyArray<string | number>): string => {\n if (path.length === 0) {\n return basePath\n }\n\n return path.reduce<string>((accumulator, segment) => {\n if (typeof segment === \"number\") {\n return `${accumulator}[${segment}]`\n }\n return `${accumulator}.${segment}`\n }, basePath)\n}\n\nconst getValueAtPath = (value: unknown, path: ReadonlyArray<string | number>): unknown => {\n let current: unknown = value\n\n for (const segment of path) {\n if (typeof segment === \"number\") {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current[segment]\n continue\n }\n\n if (!isRecord(current)) {\n return undefined\n }\n current = current[segment]\n }\n\n return current\n}\n\nconst compileError = (\n code: string,\n error: {\n readonly source?: string\n readonly message: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n },\n): CoreError => {\n return createCoreError(\"compile\", {\n code,\n message: error.message,\n source: error.source,\n path: error.path,\n details: error.details,\n })\n}\n","import type { CompiledLayoutNode, CompiledPreset, CompiledSplitPane, CompiledTerminalPane } from \"./compile\"\nimport { createCoreError, type CoreError } from \"./errors\"\n\ntype CreateLayoutPlanInput = {\n readonly preset: CompiledPreset\n}\n\ntype PlanTerminal = {\n readonly kind: \"terminal\"\n readonly id: string\n readonly name: string\n readonly command?: string\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly delay?: number\n readonly title?: string\n readonly focus: boolean\n readonly ephemeral?: boolean\n readonly closeOnError?: boolean\n readonly options?: Readonly<Record<string, unknown>>\n}\n\ntype PlanSplit = {\n readonly kind: \"split\"\n readonly id: string\n readonly orientation: \"horizontal\" | \"vertical\"\n readonly ratio: ReadonlyArray<number>\n readonly panes: ReadonlyArray<PlanNode>\n}\n\nexport type PlanNode = PlanTerminal | PlanSplit\n\nexport type LayoutPlan = {\n readonly root: PlanNode\n readonly focusPaneId: string\n}\n\nexport type CreateLayoutPlanSuccess = {\n readonly plan: LayoutPlan\n}\n\nexport const createLayoutPlan = ({ preset }: CreateLayoutPlanInput): CreateLayoutPlanSuccess => {\n if (!preset.layout) {\n const terminal = createTerminalNode({\n id: \"root\",\n terminal: {\n kind: \"terminal\",\n name: preset.name,\n command: preset.command,\n },\n focusOverride: true,\n })\n\n return {\n plan: {\n root: terminal,\n focusPaneId: terminal.id,\n },\n }\n }\n\n const { node, focusPaneIds, terminalPaneIds } = buildLayoutNode(preset.layout, {\n parentId: \"root\",\n path: \"preset.layout\",\n source: preset.metadata.source,\n })\n\n if (focusPaneIds.length > 1) {\n throw planError(\"FOCUS_CONFLICT\", {\n message: \"Multiple panes specify focus=true\",\n path: \"preset.layout\",\n source: preset.metadata.source,\n details: { focusPaneIds },\n })\n }\n\n if (terminalPaneIds.length === 0) {\n throw planError(\"NO_TERMINAL_PANES\", {\n message: \"No terminal panes are defined\",\n path: \"preset.layout\",\n source: preset.metadata.source,\n })\n }\n\n const focusPaneId = focusPaneIds[0] ?? terminalPaneIds[0]!\n const root = ensureFocus(node, focusPaneId)\n\n return {\n plan: {\n root,\n focusPaneId,\n },\n }\n}\n\ntype BuildResult = {\n readonly node: PlanNode\n readonly focusPaneIds: ReadonlyArray<string>\n readonly terminalPaneIds: ReadonlyArray<string>\n}\n\nconst buildLayoutNode = (\n node: CompiledLayoutNode,\n context: { readonly parentId: string; readonly path: string; readonly source: string },\n): BuildResult => {\n if (node.kind === \"split\") {\n return buildSplitNode(node, context)\n }\n\n return {\n node: createTerminalNode({ id: context.parentId, terminal: node }),\n focusPaneIds: node.focus === true ? [context.parentId] : [],\n terminalPaneIds: [context.parentId],\n }\n}\n\nconst buildSplitNode = (\n node: CompiledSplitPane,\n context: { readonly parentId: string; readonly path: string; readonly source: string },\n): BuildResult => {\n const ratio = normalizeRatio(node.ratio, context)\n\n const panes: PlanNode[] = []\n const focusPaneIds: string[] = []\n const terminalPaneIds: string[] = []\n\n for (let index = 0; index < node.panes.length; index += 1) {\n const childId = `${context.parentId}.${index}`\n const childContext = {\n parentId: childId,\n path: `${context.path}.panes[${index}]`,\n source: context.source,\n }\n\n const childResult = buildLayoutNode(node.panes[index]!, childContext)\n panes.push(childResult.node)\n focusPaneIds.push(...childResult.focusPaneIds)\n terminalPaneIds.push(...childResult.terminalPaneIds)\n }\n\n return {\n node: {\n kind: \"split\",\n id: context.parentId,\n orientation: node.orientation,\n ratio,\n panes,\n },\n focusPaneIds,\n terminalPaneIds,\n }\n}\n\nconst createTerminalNode = ({\n id,\n terminal,\n focusOverride,\n}: {\n readonly id: string\n readonly terminal: CompiledTerminalPane\n readonly focusOverride?: boolean\n}): PlanTerminal => {\n return {\n kind: \"terminal\",\n id,\n name: terminal.name,\n command: terminal.command,\n cwd: terminal.cwd,\n env: terminal.env,\n delay: terminal.delay,\n title: terminal.title,\n options: terminal.options,\n focus: focusOverride === true ? true : terminal.focus === true,\n ephemeral: terminal.ephemeral,\n closeOnError: terminal.closeOnError,\n }\n}\n\nconst ensureFocus = (node: PlanNode, focusPaneId: string): PlanNode => {\n if (node.kind === \"terminal\") {\n return {\n ...node,\n focus: node.id === focusPaneId,\n }\n }\n\n return {\n ...node,\n panes: node.panes.map((pane) => ensureFocus(pane, focusPaneId)),\n }\n}\n\nconst normalizeRatio = (\n ratio: ReadonlyArray<number>,\n context: { readonly path: string; readonly source: string },\n): number[] => {\n const total = ratio.reduce((sum, value, index) => {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n throw planError(\"RATIO_INVALID_VALUE\", {\n message: \"ratio value must be a non-negative number\",\n path: `${context.path}.ratio[${index}]`,\n source: context.source,\n details: { value },\n })\n }\n return sum + value\n }, 0)\n\n if (total === 0) {\n return ratio.map(() => 1 / ratio.length)\n }\n\n return ratio.map((value) => value / total)\n}\n\nconst planError = (\n code: string,\n error: {\n readonly message: string\n readonly source?: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n },\n): CoreError => {\n return createCoreError(\"plan\", {\n code,\n message: error.message,\n source: error.source,\n path: error.path,\n details: error.details,\n })\n}\n","import { createHash } from \"crypto\"\nimport type { LayoutPlan, PlanNode } from \"./planner\"\n\ntype EmitPlanInput = {\n readonly plan: LayoutPlan\n}\n\ntype CommandStepKind = \"split\" | \"focus\"\n\nexport type CommandStep = {\n readonly id: string\n readonly kind: CommandStepKind\n readonly command?: ReadonlyArray<string>\n readonly summary: string\n readonly targetPaneId?: string\n readonly createdPaneId?: string\n readonly orientation?: \"horizontal\" | \"vertical\"\n readonly percentage?: number\n}\n\nexport type EmittedTerminal = {\n readonly virtualPaneId: string\n readonly command?: string\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly delay?: number\n readonly title?: string\n readonly focus: boolean\n readonly name: string\n readonly ephemeral?: boolean\n readonly closeOnError?: boolean\n}\n\ntype PlanEmissionSummary = {\n readonly stepsCount: number\n readonly focusPaneId: string\n readonly initialPaneId: string\n}\n\nexport type PlanEmission = {\n readonly steps: ReadonlyArray<CommandStep>\n readonly summary: PlanEmissionSummary\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly hash: string\n}\n\ntype SplitNode = Extract<PlanNode, { kind: \"split\" }>\n\nexport const emitPlan = ({ plan }: EmitPlanInput): PlanEmission => {\n const steps: CommandStep[] = []\n collectSplitSteps(plan.root, steps)\n\n steps.push({\n id: `${plan.focusPaneId}:focus`,\n kind: \"focus\",\n summary: `select pane ${plan.focusPaneId}`,\n targetPaneId: plan.focusPaneId,\n })\n\n const hash = createPlanHash(plan, steps)\n const initialPaneId = determineInitialPaneId(plan.root)\n const terminals = collectTerminals(plan.root)\n\n return {\n steps,\n summary: {\n stepsCount: steps.length,\n focusPaneId: plan.focusPaneId,\n initialPaneId,\n },\n terminals,\n hash,\n }\n}\n\nconst collectSplitSteps = (node: PlanNode, steps: CommandStep[]): void => {\n if (node.kind === \"terminal\") {\n return\n }\n\n appendSplitSteps(node, steps)\n node.panes.forEach((pane) => collectSplitSteps(pane, steps))\n}\n\nconst appendSplitSteps = (node: SplitNode, steps: CommandStep[]): void => {\n const directionFlag = node.orientation === \"horizontal\" ? \"-h\" : \"-v\"\n\n for (let index = 1; index < node.panes.length; index += 1) {\n const remainingIncludingTarget = node.ratio.slice(index - 1).reduce((sum, value) => sum + value, 0)\n const remainingAfterTarget = node.ratio.slice(index).reduce((sum, value) => sum + value, 0)\n\n const desiredPercentage =\n remainingIncludingTarget === 0 ? 0 : (remainingAfterTarget / remainingIncludingTarget) * 100\n const percentage = clampPercent(desiredPercentage)\n const targetPaneId = node.panes[index - 1]?.id ?? node.id\n const createdPaneId = node.panes[index]?.id\n\n steps.push({\n id: `${node.id}:split:${index}`,\n kind: \"split\",\n summary: `split ${targetPaneId} (${directionFlag})`,\n targetPaneId,\n createdPaneId,\n orientation: node.orientation,\n percentage,\n })\n }\n}\n\nconst clampPercent = (value: number): number => {\n return Math.min(99, Math.max(1, Math.round(value)))\n}\n\nconst collectTerminals = (node: PlanNode): EmittedTerminal[] => {\n if (node.kind === \"terminal\") {\n return [\n {\n virtualPaneId: node.id,\n command: node.command,\n cwd: node.cwd,\n env: node.env,\n delay: node.delay,\n title: node.title,\n focus: node.focus,\n name: node.name,\n ephemeral: node.ephemeral,\n closeOnError: node.closeOnError,\n },\n ]\n }\n\n return node.panes.flatMap((pane) => collectTerminals(pane))\n}\n\nconst determineInitialPaneId = (node: PlanNode): string => {\n if (node.kind === \"terminal\") {\n return node.id\n }\n\n let current: PlanNode = node\n while (current.kind === \"split\") {\n current = current.panes[0]!\n }\n return current.id\n}\n\nconst createPlanHash = (plan: LayoutPlan, steps: ReadonlyArray<CommandStep>): string => {\n const digest = createHash(\"sha256\")\n const normalized = {\n focusPaneId: plan.focusPaneId,\n root: plan.root,\n steps,\n }\n digest.update(JSON.stringify(normalized))\n return digest.digest(\"hex\")\n}\n","import { isCoreError, type CoreError } from \"../core/index\"\nimport type { Logger } from \"../utils/logger\"\n\ntype CliErrorHandlers = {\n handleCoreError: (error: CoreError) => number\n handleError: (error: unknown) => number\n handlePipelineFailure: (error: unknown) => number\n}\n\nexport const createCliErrorHandlers = ({ getLogger }: { getLogger: () => Logger }): CliErrorHandlers => {\n const handleCoreError = (error: CoreError): number => {\n const header = [`[${error.kind}]`, `[${error.code}]`]\n if (typeof error.path === \"string\" && error.path.length > 0) {\n header.push(`[${error.path}]`)\n }\n\n const lines = [`${header.join(\" \")} ${error.message}`.trim()]\n\n if (typeof error.source === \"string\" && error.source.length > 0) {\n lines.push(`source: ${error.source}`)\n }\n\n const commandDetail = error.details?.command\n if (Array.isArray(commandDetail)) {\n const parts = commandDetail.filter((segment): segment is string => typeof segment === \"string\")\n if (parts.length > 0) {\n lines.push(`command: ${parts.join(\" \")}`)\n }\n } else if (typeof commandDetail === \"string\" && commandDetail.length > 0) {\n lines.push(`command: ${commandDetail}`)\n }\n\n const stderrDetail = error.details?.stderr\n if (typeof stderrDetail === \"string\" && stderrDetail.length > 0) {\n lines.push(`stderr: ${stderrDetail}`)\n } else if (stderrDetail !== undefined) {\n lines.push(`stderr: ${String(stderrDetail)}`)\n }\n\n getLogger().error(lines.join(\"\\n\"))\n return 1\n }\n\n const handleError = (error: unknown): number => {\n if (error instanceof Error) {\n getLogger().error(error.message, error)\n } else {\n getLogger().error(\"An unexpected error occurred\")\n }\n\n return 1\n }\n\n const handlePipelineFailure = (error: unknown): number => {\n if (isCoreError(error)) {\n return handleCoreError(error)\n }\n return handleError(error)\n }\n\n return {\n handleCoreError,\n handleError,\n handlePipelineFailure,\n }\n}\n","import chalk from \"chalk\"\n\nexport enum LogLevel {\n ERROR = 0,\n WARN = 1,\n INFO = 2,\n DEBUG = 3,\n}\n\ntype LoggerOptions = {\n readonly level?: LogLevel\n readonly prefix?: string\n}\n\nexport type Logger = {\n readonly level: LogLevel\n readonly prefix: string\n error: (message: string, error?: Error) => void\n warn: (message: string) => void\n info: (message: string) => void\n debug: (message: string) => void\n success: (message: string) => void\n createChild: (suffix: string) => Logger\n}\n\nconst resolveDefaultLogLevel = (): LogLevel => {\n if (process.env.VDE_DEBUG === \"true\") {\n return LogLevel.DEBUG\n }\n if (process.env.VDE_VERBOSE === \"true\") {\n return LogLevel.INFO\n }\n return LogLevel.WARN\n}\n\nconst formatMessage = (prefix: string, message: string): string => {\n return prefix ? `${prefix} ${message}` : message\n}\n\nexport const createLogger = (options: LoggerOptions = {}): Logger => {\n const level = options.level ?? resolveDefaultLogLevel()\n const prefix = options.prefix ?? \"\"\n\n const build = (nextPrefix: string, nextLevel: LogLevel): Logger => {\n const resolvedPrefix = nextPrefix\n\n return {\n level: nextLevel,\n prefix: resolvedPrefix,\n error(message: string, error?: Error): void {\n if (nextLevel >= LogLevel.ERROR) {\n console.error(chalk.red(formatMessage(resolvedPrefix, `Error: ${message}`)))\n if (error && process.env.VDE_DEBUG === \"true\") {\n console.error(chalk.gray(error.stack))\n }\n }\n },\n warn(message: string): void {\n if (nextLevel >= LogLevel.WARN) {\n console.warn(chalk.yellow(formatMessage(resolvedPrefix, message)))\n }\n },\n info(message: string): void {\n if (nextLevel >= LogLevel.INFO) {\n console.log(formatMessage(resolvedPrefix, message))\n }\n },\n debug(message: string): void {\n if (nextLevel >= LogLevel.DEBUG) {\n console.log(chalk.gray(formatMessage(resolvedPrefix, `[DEBUG] ${message}`)))\n }\n },\n success(message: string): void {\n console.log(chalk.green(formatMessage(resolvedPrefix, message)))\n },\n createChild(suffix: string): Logger {\n const childPrefix = resolvedPrefix ? `${resolvedPrefix} ${suffix}` : suffix\n return build(childPrefix, nextLevel)\n },\n }\n }\n\n return build(prefix, level)\n}\n","import chalk from \"chalk\"\n\nimport type { PresetInfo } from \"../models/types\"\nimport type { PresetManager } from \"../contracts\"\nimport { LogLevel, type Logger } from \"../utils/logger\"\n\ntype RuntimeOptions = {\n readonly verbose?: boolean\n readonly config?: string\n}\n\nexport const applyRuntimeOptions = ({\n runtimeOptions,\n createLogger,\n presetManager,\n}: {\n readonly runtimeOptions: RuntimeOptions\n readonly createLogger: (options?: { level?: LogLevel }) => Logger\n readonly presetManager: PresetManager\n}): Logger => {\n const logger =\n runtimeOptions.verbose === true\n ? createLogger({\n level: LogLevel.INFO,\n })\n : createLogger()\n\n if (\n typeof runtimeOptions.config === \"string\" &&\n runtimeOptions.config.length > 0 &&\n typeof presetManager.setConfigPath === \"function\"\n ) {\n presetManager.setConfigPath(runtimeOptions.config)\n }\n\n return logger\n}\n\nexport const listPresets = async ({\n presetManager,\n logger,\n onError,\n output = (line: string): void => console.log(line),\n}: {\n readonly presetManager: PresetManager\n readonly logger: Logger\n readonly onError: (error: unknown) => number\n readonly output?: (line: string) => void\n}): Promise<number> => {\n try {\n await presetManager.loadConfig()\n const presets = presetManager.listPresets()\n\n if (presets.length === 0) {\n logger.warn(\"No presets defined\")\n return 0\n }\n\n output(chalk.bold(\"Available presets:\\n\"))\n\n const maxKeyLength = Math.max(...presets.map((preset) => preset.key.length))\n presets.forEach((preset: PresetInfo) => {\n const paddedKey = preset.key.padEnd(maxKeyLength + 2)\n const description = preset.description ?? \"\"\n output(` ${chalk.cyan(paddedKey)} ${description}`)\n })\n\n return 0\n } catch (error) {\n return onError(error)\n }\n}\n","import { execa } from \"execa\"\nimport { createTmuxError, ErrorCodes } from \"../utils/errors\"\nimport type { CommandExecutor } from \"../contracts\"\nimport { createLogger, LogLevel } from \"../utils/logger\"\n\ntype RealExecutorOptions = {\n readonly verbose?: boolean\n}\n\nconst parseCommand = (commandOrArgs: string | string[]): string[] => {\n return typeof commandOrArgs === \"string\"\n ? commandOrArgs\n .split(\" \")\n .filter((segment) => segment.length > 0)\n .slice(1)\n : commandOrArgs\n}\n\nconst toCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n}\n\nexport const createRealExecutor = (options: RealExecutorOptions = {}): CommandExecutor => {\n const verbose = options.verbose ?? false\n const logger = createLogger({\n level: verbose ? LogLevel.INFO : LogLevel.WARN,\n prefix: \"[tmux]\",\n })\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n const args = parseCommand(commandOrArgs)\n const commandString = toCommandString(args)\n\n logger.info(`Executing: ${commandString}`)\n\n try {\n const result = await execa(\"tmux\", args)\n return result.stdout\n } catch (error) {\n const execaError = error as { exitCode?: number; stderr?: string; message: string }\n\n throw createTmuxError(\"Failed to execute tmux command\", ErrorCodes.TMUX_COMMAND_FAILED, {\n command: commandString,\n exitCode: execaError.exitCode,\n stderr: execaError.stderr,\n })\n }\n }\n\n return {\n execute,\n async executeMany(commandsList: string[][]): Promise<void> {\n for (const args of commandsList) {\n await execute(args)\n }\n },\n isDryRun(): boolean {\n return false\n },\n logCommand(command: string): void {\n logger.info(`Executing: ${command}`)\n },\n }\n}\n","import type { CommandExecutor } from \"../contracts\"\nimport { createLogger, LogLevel } from \"../utils/logger\"\n\ntype DryRunExecutorOptions = {\n readonly verbose?: boolean\n}\n\nconst parseCommand = (commandOrArgs: string | string[]): string[] => {\n return typeof commandOrArgs === \"string\"\n ? commandOrArgs\n .split(\" \")\n .filter((segment) => segment.length > 0)\n .slice(1)\n : commandOrArgs\n}\n\nconst toCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n}\n\nexport const createDryRunExecutor = (options: DryRunExecutorOptions = {}): CommandExecutor => {\n const verbose = options.verbose ?? false\n const logger = createLogger({\n level: verbose ? LogLevel.INFO : LogLevel.WARN,\n prefix: \"[tmux] [DRY RUN]\",\n })\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n const args = parseCommand(commandOrArgs)\n const commandString = toCommandString(args)\n logger.info(`Would execute: ${commandString}`)\n return \"\"\n }\n\n return {\n execute,\n async executeMany(commandsList: string[][]): Promise<void> {\n for (const args of commandsList) {\n await execute(args)\n }\n },\n isDryRun(): boolean {\n return true\n },\n logCommand(command: string): void {\n logger.info(`Would execute: ${command}`)\n },\n }\n}\n","import type { CommandExecutor } from \"../contracts\"\nimport type { TmuxExecutorContract } from \"../contracts\"\nimport { createEnvironmentError, ErrorCodes } from \"../utils/errors\"\n\nexport type MockExecutor = CommandExecutor &\n TmuxExecutorContract & {\n readonly getExecutedCommands: () => string[][]\n readonly clearExecutedCommands: () => void\n readonly setMockPaneIds: (paneIds: string[]) => void\n readonly getPaneIds: () => string[]\n }\n\nconst parseCommand = (commandOrArgs: string | string[]): string[] => {\n return typeof commandOrArgs === \"string\"\n ? commandOrArgs\n .split(\" \")\n .filter((segment) => segment.length > 0)\n .slice(1)\n : commandOrArgs\n}\n\nconst isInTmuxSession = (): boolean => {\n return Boolean(process.env.TMUX)\n}\n\nconst toCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n}\n\nexport const createMockExecutor = (): MockExecutor => {\n let mockPaneCounter = 0\n let mockPaneIds: string[] = [\"%0\"]\n let executedCommands: string[][] = []\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n const args = parseCommand(commandOrArgs)\n executedCommands.push(args)\n\n if (args[0] === \"new-window\") {\n mockPaneCounter = 0\n mockPaneIds = [\"%0\"]\n return \"%0\"\n }\n\n if (args.includes(\"display-message\") && args.includes(\"#{pane_id}\")) {\n return mockPaneIds[0] ?? \"%0\"\n }\n\n if (args.includes(\"list-panes\") && args.includes(\"#{pane_id}\")) {\n return mockPaneIds.join(\"\\n\")\n }\n\n if (args[0] === \"kill-pane\" && args.includes(\"-a\")) {\n const targetIndex = args.indexOf(\"-t\")\n const targetPane =\n (targetIndex >= 0 && targetIndex + 1 < args.length ? args[targetIndex + 1] : mockPaneIds[0]) ?? \"%0\"\n mockPaneIds = [targetPane]\n const parsedCounter = Number(targetPane.replace(\"%\", \"\"))\n if (!Number.isNaN(parsedCounter)) {\n mockPaneCounter = parsedCounter\n }\n return \"\"\n }\n\n if (args.includes(\"split-window\")) {\n mockPaneCounter += 1\n const newPaneId = `%${mockPaneCounter}`\n mockPaneIds = [...mockPaneIds, newPaneId]\n }\n\n return \"\"\n }\n\n return {\n execute,\n async executeMany(commandsList: string[][]): Promise<void> {\n for (const args of commandsList) {\n await execute(args)\n }\n },\n isDryRun(): boolean {\n return true\n },\n logCommand(): void {\n // noop\n },\n getExecutedCommands(): string[][] {\n return executedCommands\n },\n clearExecutedCommands(): void {\n executedCommands = []\n },\n setMockPaneIds(paneIds: string[]): void {\n mockPaneIds = [...paneIds]\n },\n getPaneIds(): string[] {\n return mockPaneIds\n },\n isInTmuxSession,\n async verifyTmuxEnvironment(): Promise<void> {\n if (!isInTmuxSession()) {\n throw createEnvironmentError(\"Must be run inside a tmux session\", ErrorCodes.NOT_IN_TMUX_SESSION, {\n hint: \"Please start a tmux session and try again\",\n })\n }\n },\n getCommandString: toCommandString,\n async getCurrentSessionName(): Promise<string> {\n return \"mock-session\"\n },\n }\n}\n","import { execa } from \"execa\"\nimport { createEnvironmentError, ErrorCodes } from \"../../utils/errors\"\nimport type { TmuxExecutorContract } from \"../../contracts\"\nimport type { CommandExecutor } from \"../../contracts\"\nimport { createRealExecutor, createDryRunExecutor, createMockExecutor } from \"../../executor/index\"\n\ntype TmuxExecutorOptions = {\n readonly verbose?: boolean\n readonly dryRun?: boolean\n readonly executor?: CommandExecutor\n}\n\nexport type TmuxExecutor = TmuxExecutorContract & {\n readonly getExecutor: () => CommandExecutor\n}\n\nexport const createTmuxExecutor = (options: TmuxExecutorOptions = {}): TmuxExecutor => {\n const executor = resolveExecutor(options)\n\n const isInTmuxSession = (): boolean => {\n return Boolean(process.env.TMUX)\n }\n\n const verifyTmuxEnvironment = async (): Promise<void> => {\n if (!isInTmuxSession()) {\n throw createEnvironmentError(\"Must be run inside a tmux session\", ErrorCodes.NOT_IN_TMUX_SESSION, {\n hint: \"Please start a tmux session and try again\",\n })\n }\n\n if (executor.isDryRun()) {\n return\n }\n\n try {\n await execa(\"tmux\", [\"-V\"])\n } catch (_error) {\n throw createEnvironmentError(\"tmux is not installed\", ErrorCodes.TMUX_NOT_FOUND, {\n hint: \"Please install tmux\",\n })\n }\n }\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n return executor.execute(commandOrArgs)\n }\n\n const executeMany = async (commandsList: string[][]): Promise<void> => {\n for (const command of commandsList) {\n await execute(command)\n }\n }\n\n const getCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n }\n\n const getCurrentSessionName = async (): Promise<string> => {\n return execute([\"display-message\", \"-p\", \"#{session_name}\"])\n }\n\n return {\n verifyTmuxEnvironment,\n execute,\n executeMany,\n isInTmuxSession,\n getCurrentSessionName,\n getCommandString,\n getExecutor: () => executor,\n }\n}\n\nconst resolveExecutor = (options: TmuxExecutorOptions): CommandExecutor => {\n if (options.executor) {\n return options.executor\n }\n\n if (options.dryRun === true) {\n return createDryRunExecutor({ verbose: options.verbose })\n }\n\n if (isTestEnvironment()) {\n return createMockExecutor()\n }\n\n return createRealExecutor({ verbose: options.verbose })\n}\n\nconst isTestEnvironment = (): boolean => {\n return process.env.VDE_TEST_MODE === \"true\" || process.env.NODE_ENV === \"test\" || process.env.VITEST === \"true\"\n}\n","export const waitForDelay = (ms: number): Promise<void> => {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms)\n })\n}\n","export const resolvePaneMapping = (paneMap: Map<string, string>, virtualId: string): string | undefined => {\n const direct = paneMap.get(virtualId)\n if (typeof direct === \"string\" && direct.length > 0) {\n return direct\n }\n\n let ancestor = virtualId\n while (ancestor.includes(\".\")) {\n ancestor = ancestor.slice(0, ancestor.lastIndexOf(\".\"))\n const candidate = paneMap.get(ancestor)\n if (typeof candidate === \"string\" && candidate.length > 0) {\n paneMap.set(virtualId, candidate)\n return candidate\n }\n }\n\n for (const [key, value] of paneMap.entries()) {\n if (key.startsWith(`${virtualId}.`)) {\n if (typeof value === \"string\" && value.length > 0) {\n paneMap.set(virtualId, value)\n return value\n }\n }\n }\n\n return undefined\n}\n","import type { CommandStep } from \"../core/emitter\"\nimport { createCoreError } from \"../core/errors\"\nimport { ErrorCodes } from \"../utils/errors\"\n\ntype SplitOrientation = \"horizontal\" | \"vertical\"\ntype SplitCommandStep = CommandStep & { readonly kind: \"split\" }\n\nconst asSplitStep = (step: CommandStep, field: \"orientation\" | \"percentage\"): SplitCommandStep => {\n if (step.kind !== \"split\") {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: `Non-split step cannot resolve split ${field}`,\n path: step.id,\n details: { kind: step.kind },\n })\n }\n return step as SplitCommandStep\n}\n\nexport const resolveSplitOrientation = (step: CommandStep): SplitOrientation => {\n const splitStep = asSplitStep(step, \"orientation\")\n\n if (splitStep.orientation === \"horizontal\" || splitStep.orientation === \"vertical\") {\n return splitStep.orientation\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: \"Split step missing orientation metadata\",\n path: splitStep.id,\n details: { orientation: splitStep.orientation },\n })\n}\n\nexport const resolveSplitPercentage = (step: CommandStep): string => {\n const splitStep = asSplitStep(step, \"percentage\")\n\n if (typeof splitStep.percentage === \"number\" && Number.isFinite(splitStep.percentage)) {\n return String(clampSplitPercentage(splitStep.percentage))\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: \"Split step missing percentage metadata\",\n path: splitStep.id,\n details: { percentage: splitStep.percentage },\n })\n}\n\nconst clampSplitPercentage = (value: number): number => {\n return Math.min(99, Math.max(1, Math.round(value)))\n}\n","import type { EmittedTerminal } from \"../core/emitter\"\n\n/**\n * Template token types supported in pane commands:\n * - {{pane_id:<name>}} - resolves to a specific pane's ID by name\n * - {{this_pane}} - references the current pane receiving the command\n * - {{focus_pane}} - references the intended focus pane\n */\n\ntype ReplaceTemplateTokensInput = {\n readonly command: string\n readonly currentPaneRealId: string\n readonly focusPaneRealId: string\n readonly nameToRealIdMap: ReadonlyMap<string, string>\n}\n\nexport type TemplateTokenError = Error & {\n readonly tokenType: string\n readonly availablePanes?: ReadonlyArray<string>\n}\n\ntype TemplateTokenErrorConstructor = {\n new (message: string, tokenType: string, availablePanes?: ReadonlyArray<string>): TemplateTokenError\n (message: string, tokenType: string, availablePanes?: ReadonlyArray<string>): TemplateTokenError\n readonly prototype: TemplateTokenError\n}\n\nconst TemplateTokenErrorImpl = function TemplateTokenError(\n message: string,\n tokenType: string,\n availablePanes?: ReadonlyArray<string>,\n): TemplateTokenError {\n type MutableTemplateTokenError = Error & { tokenType: string; availablePanes?: ReadonlyArray<string> }\n const error = new Error(message) as MutableTemplateTokenError\n Object.setPrototypeOf(error, TemplateTokenErrorImpl.prototype)\n error.name = \"TemplateTokenError\"\n error.tokenType = tokenType\n error.availablePanes = availablePanes\n return error as TemplateTokenError\n}\n\nTemplateTokenErrorImpl.prototype = Object.create(Error.prototype)\nTemplateTokenErrorImpl.prototype.constructor = TemplateTokenErrorImpl\n\nexport const TemplateTokenError = TemplateTokenErrorImpl as TemplateTokenErrorConstructor\n\n/**\n * Replaces template tokens in a command string with actual pane IDs.\n *\n * Uses a single-pass regex replacement to avoid nested token issues.\n * All tokens are replaced in a single pass, preventing already-replaced\n * values from being re-processed.\n *\n * @param input - Object containing the command and pane ID mappings\n * @returns The command string with all template tokens replaced\n * @throws TemplateTokenError if a referenced pane name is not found in the mapping\n */\nexport const replaceTemplateTokens = ({\n command,\n currentPaneRealId,\n focusPaneRealId,\n nameToRealIdMap,\n}: ReplaceTemplateTokensInput): string => {\n // Single-pass regex that matches all token types\n // This prevents nested token issues by replacing everything in one pass\n const tokenPattern = /\\{\\{(this_pane|focus_pane|pane_id:([^}]+))\\}\\}/g\n\n return command.replace(tokenPattern, (match, tokenContent: string, paneName?: string) => {\n if (tokenContent === \"this_pane\") {\n return currentPaneRealId\n }\n\n if (tokenContent === \"focus_pane\") {\n return focusPaneRealId\n }\n\n // Must be pane_id:<name> token\n if (tokenContent.startsWith(\"pane_id:\") && paneName !== undefined) {\n const trimmedName = paneName.trim()\n const paneId = nameToRealIdMap.get(trimmedName)\n\n if (paneId === undefined) {\n throw new TemplateTokenError(\n `Pane name \"${trimmedName}\" not found. Available panes: ${Array.from(nameToRealIdMap.keys()).join(\", \")}`,\n \"pane_id\",\n Array.from(nameToRealIdMap.keys()),\n )\n }\n\n return paneId\n }\n\n // Fallback: return original match if token is malformed\n return match\n })\n}\n\n/**\n * Builds a mapping from pane names to real pane IDs.\n *\n * **Duplicate Name Handling:**\n * If multiple panes share the same name, the last one in the terminals\n * array wins. This follows the iteration order of the layout tree.\n * It's recommended to use unique names for panes to avoid ambiguity\n * in template token references.\n *\n * **Virtual to Real ID Resolution:**\n * Only panes with successfully resolved real IDs (present in paneMap)\n * are included in the resulting map. This ensures that template tokens\n * only reference panes that have been properly created.\n *\n * @param terminals - Array of emitted terminals from the layout plan\n * @param paneMap - Map from virtual pane IDs to real pane IDs (backend-specific)\n * @returns A map from pane names to real pane IDs\n */\nexport const buildNameToRealIdMap = (\n terminals: ReadonlyArray<EmittedTerminal>,\n paneMap: ReadonlyMap<string, string>,\n): Map<string, string> => {\n const nameToRealIdMap = new Map<string, string>()\n\n for (const terminal of terminals) {\n const realId = paneMap.get(terminal.virtualPaneId)\n if (realId !== undefined) {\n nameToRealIdMap.set(terminal.name, realId)\n }\n }\n\n return nameToRealIdMap\n}\n","import type { EmittedTerminal } from \"../core/emitter\"\nimport { buildNameToRealIdMap, replaceTemplateTokens, TemplateTokenError } from \"../utils/template-tokens\"\n\ntype TemplateTokenErrorContext = {\n readonly terminal: EmittedTerminal\n readonly error: TemplateTokenError\n}\n\ntype PrepareTerminalCommandsInput = {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly focusPaneVirtualId: string\n readonly resolveRealPaneId: (virtualPaneId: string) => string\n readonly onTemplateTokenError: (context: TemplateTokenErrorContext) => never\n}\n\ntype PreparedTerminalCommand = {\n readonly terminal: EmittedTerminal\n readonly realPaneId: string\n readonly cwdCommand?: string\n readonly envCommands: ReadonlyArray<{\n readonly key: string\n readonly command: string\n }>\n readonly title?: string\n readonly command?: {\n readonly text: string\n readonly delayMs: number\n }\n}\n\ntype PreparedTerminalCommands = {\n readonly focusPaneRealId: string\n readonly commands: ReadonlyArray<PreparedTerminalCommand>\n}\n\nconst SINGLE_QUOTE = \"'\"\nconst SHELL_SINGLE_QUOTE_ESCAPE = `'\"'\"'`\nconst ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/\n\nconst shellQuoteLiteral = (value: string): string => {\n return `'${value.split(SINGLE_QUOTE).join(SHELL_SINGLE_QUOTE_ESCAPE)}'`\n}\n\nconst assertValidEnvKey = (key: string): void => {\n if (!ENV_KEY_PATTERN.test(key)) {\n throw new Error(`Invalid environment variable name: ${key}`)\n }\n}\n\nconst normalizeDelay = (delay: unknown): number => {\n return typeof delay === \"number\" && Number.isFinite(delay) && delay > 0 ? delay : 0\n}\n\nconst applyEphemeralSuffix = (command: string, terminal: EmittedTerminal): string => {\n if (terminal.ephemeral !== true) {\n return command\n }\n\n return terminal.closeOnError === true ? `${command}; exit` : `${command}; [ $? -eq 0 ] && exit`\n}\n\nexport const prepareTerminalCommands = ({\n terminals,\n focusPaneVirtualId,\n resolveRealPaneId,\n onTemplateTokenError,\n}: PrepareTerminalCommandsInput): PreparedTerminalCommands => {\n const paneMap = new Map<string, string>()\n for (const terminal of terminals) {\n paneMap.set(terminal.virtualPaneId, resolveRealPaneId(terminal.virtualPaneId))\n }\n\n const focusPaneRealId = paneMap.get(focusPaneVirtualId) ?? resolveRealPaneId(focusPaneVirtualId)\n const nameToRealIdMap = buildNameToRealIdMap(terminals, paneMap)\n\n const commands: PreparedTerminalCommand[] = terminals.map((terminal) => {\n const realPaneId = paneMap.get(terminal.virtualPaneId)\n if (realPaneId === undefined) {\n throw new Error(`Unknown pane: ${terminal.virtualPaneId}`)\n }\n\n const cwdCommand =\n typeof terminal.cwd === \"string\" && terminal.cwd.length > 0\n ? `cd -- ${shellQuoteLiteral(terminal.cwd)}`\n : undefined\n\n const envCommands =\n terminal.env === undefined\n ? []\n : Object.entries(terminal.env).map(([key, value]) => {\n assertValidEnvKey(key)\n return {\n key,\n command: `export ${key}=${shellQuoteLiteral(String(value))}`,\n }\n })\n\n const title = typeof terminal.title === \"string\" && terminal.title.length > 0 ? terminal.title : undefined\n\n let command:\n | {\n readonly text: string\n readonly delayMs: number\n }\n | undefined\n\n if (typeof terminal.command === \"string\" && terminal.command.length > 0) {\n try {\n const commandUsesFocusToken = terminal.command.includes(\"{{focus_pane}}\")\n const replaced = replaceTemplateTokens({\n command: terminal.command,\n currentPaneRealId: realPaneId,\n focusPaneRealId: commandUsesFocusToken ? focusPaneRealId : \"\",\n nameToRealIdMap,\n })\n\n command = {\n text: applyEphemeralSuffix(replaced, terminal),\n delayMs: normalizeDelay(terminal.delay),\n }\n } catch (error) {\n if (error instanceof TemplateTokenError) {\n return onTemplateTokenError({ terminal, error })\n }\n throw error\n }\n }\n\n return {\n terminal,\n realPaneId,\n cwdCommand,\n envCommands,\n title,\n command,\n }\n })\n\n return {\n focusPaneRealId,\n commands,\n }\n}\n","import type { CommandStep, EmittedTerminal } from \"../core/emitter\"\nimport { createCoreError } from \"../core/errors\"\nimport type { CommandExecutor } from \"../contracts\"\nimport { waitForDelay } from \"../utils/async\"\nimport { ErrorCodes } from \"../utils/errors\"\nimport { resolvePaneMapping } from \"../utils/pane-map\"\nimport { resolveSplitOrientation, resolveSplitPercentage } from \"./split-step\"\nimport { prepareTerminalCommands } from \"./terminal-command-preparation\"\n\nexport const executeSplitStep = async ({\n step,\n executor,\n paneMap,\n}: {\n readonly step: CommandStep\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n}): Promise<void> => {\n const targetVirtualId = ensureNonEmpty(step.targetPaneId, () =>\n raiseExecutionError(ErrorCodes.MISSING_TARGET, {\n message: \"Split step missing target pane metadata\",\n path: step.id,\n }),\n )\n\n const targetRealId = ensureNonEmpty(resolvePaneId(paneMap, targetVirtualId), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown target pane: ${targetVirtualId}`,\n path: step.id,\n }),\n )\n\n const panesBefore = await listPaneIds(executor, step)\n const splitCommand = buildSplitCommand(step, targetRealId)\n await executeCommand(executor, splitCommand, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to execute split step ${step.id}`,\n path: step.id,\n details: { command: splitCommand },\n })\n\n const panesAfter = await listPaneIds(executor, step)\n const newPaneId = ensureNonEmpty(findNewPaneId(panesBefore, panesAfter), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: \"Unable to determine newly created pane\",\n path: step.id,\n }),\n )\n\n const createdVirtualId = step.createdPaneId\n if (typeof createdVirtualId === \"string\" && createdVirtualId.length > 0) {\n registerPane(paneMap, createdVirtualId, newPaneId)\n }\n}\n\nexport const executeFocusStep = async ({\n step,\n executor,\n paneMap,\n}: {\n readonly step: CommandStep\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n}): Promise<void> => {\n const targetVirtualId = ensureNonEmpty(step.targetPaneId, () =>\n raiseExecutionError(ErrorCodes.MISSING_TARGET, {\n message: \"Focus step missing target pane metadata\",\n path: step.id,\n }),\n )\n\n const targetRealId = ensureNonEmpty(resolvePaneId(paneMap, targetVirtualId), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown focus pane: ${targetVirtualId}`,\n path: step.id,\n }),\n )\n\n const command = buildFocusCommand(targetRealId)\n await executeCommand(executor, command, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to execute focus step ${step.id}`,\n path: step.id,\n details: { command },\n })\n}\n\nexport const executeTerminalCommands = async ({\n terminals,\n executor,\n paneMap,\n focusPaneVirtualId,\n}: {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n readonly focusPaneVirtualId: string\n}): Promise<void> => {\n if (!paneMap.has(focusPaneVirtualId)) {\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown focus pane: ${focusPaneVirtualId}`,\n path: focusPaneVirtualId,\n })\n }\n ensureNonEmpty(resolvePaneId(paneMap, focusPaneVirtualId), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown focus pane: ${focusPaneVirtualId}`,\n path: focusPaneVirtualId,\n }),\n )\n\n const resolveRealPaneId = (virtualPaneId: string): string => {\n return ensureNonEmpty(resolvePaneId(paneMap, virtualPaneId), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown terminal pane: ${virtualPaneId}`,\n path: virtualPaneId,\n }),\n )\n }\n\n const prepared = prepareTerminalCommands({\n terminals,\n focusPaneVirtualId,\n resolveRealPaneId,\n onTemplateTokenError: ({ terminal, error }): never => {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TEMPLATE_TOKEN_ERROR,\n message: `Template token resolution failed for pane ${terminal.virtualPaneId}: ${error.message}`,\n path: terminal.virtualPaneId,\n details: {\n command: terminal.command,\n tokenType: error.tokenType,\n availablePanes: error.availablePanes,\n },\n })\n },\n })\n\n for (const commandSet of prepared.commands) {\n const { terminal, realPaneId } = commandSet\n\n if (typeof commandSet.cwdCommand === \"string\") {\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, commandSet.cwdCommand, \"Enter\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to change directory for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { cwd: terminal.cwd },\n })\n }\n\n for (const envEntry of commandSet.envCommands) {\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, envEntry.command, \"Enter\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to set environment variable ${envEntry.key}`,\n path: terminal.virtualPaneId,\n })\n }\n\n if (typeof commandSet.title === \"string\") {\n await executeCommand(executor, [\"select-pane\", \"-t\", realPaneId, \"-T\", commandSet.title], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to set pane title for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { title: commandSet.title },\n })\n }\n\n if (commandSet.command !== undefined) {\n if (commandSet.command.delayMs > 0) {\n await waitForDelay(commandSet.command.delayMs)\n }\n\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, commandSet.command.text, \"Enter\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to execute command for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { command: terminal.command },\n })\n }\n }\n}\n\nexport const executeCommand = async (\n executor: CommandExecutor,\n command: string[],\n context: {\n readonly code: string\n readonly message: string\n readonly path: string\n readonly details?: Record<string, unknown>\n },\n): Promise<string> => {\n try {\n return await executor.execute([...command])\n } catch (error) {\n if (error instanceof Error && \"code\" in error && \"message\" in error) {\n const candidate = error as { code?: string; message?: string; details?: Record<string, unknown> }\n throw createCoreError(\"execution\", {\n code: typeof candidate.code === \"string\" ? candidate.code : context.code,\n message: candidate.message ?? context.message,\n path: context.path,\n details: candidate.details ?? context.details,\n })\n }\n\n throw createCoreError(\"execution\", {\n code: context.code,\n message: context.message,\n path: context.path,\n details: context.details,\n })\n }\n}\n\nexport const resolveCurrentPaneId = async ({\n executor,\n contextPath,\n isDryRun,\n}: {\n executor: CommandExecutor\n contextPath: string\n isDryRun: boolean\n}): Promise<string> => {\n const envPaneId = process.env.TMUX_PANE\n if (typeof envPaneId === \"string\" && envPaneId.trim().length > 0) {\n return normalizePaneId(envPaneId)\n }\n\n if (isDryRun) {\n return \"%0\"\n }\n\n const output = await executeCommand(executor, [\"display-message\", \"-p\", \"#{pane_id}\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to resolve current tmux pane\",\n path: contextPath,\n })\n\n const paneId = output.trim()\n if (paneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.NOT_IN_TMUX_SESSION,\n message: \"Unable to determine current tmux pane\",\n path: contextPath,\n })\n }\n\n return normalizePaneId(paneId)\n}\n\nexport const listWindowPaneIds = async (executor: CommandExecutor, contextPath: string): Promise<string[]> => {\n const output = await executeCommand(executor, [\"list-panes\", \"-F\", \"#{pane_id}\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to list tmux panes\",\n path: contextPath,\n })\n\n return output\n .split(\"\\n\")\n .map((pane) => pane.trim())\n .filter((pane) => pane.length > 0)\n}\n\nconst listPaneIds = async (executor: CommandExecutor, step: CommandStep): Promise<string[]> => {\n return listWindowPaneIds(executor, step.id)\n}\n\nconst findNewPaneId = (before: string[], after: string[]): string | undefined => {\n const beforeSet = new Set(before)\n return after.find((id) => !beforeSet.has(id))\n}\n\nconst buildSplitCommand = (step: CommandStep, targetRealId: string): string[] => {\n const directionFlag = resolveSplitOrientation(step) === \"horizontal\" ? \"-h\" : \"-v\"\n const percentage = resolveSplitPercentage(step)\n return [\"split-window\", directionFlag, \"-t\", targetRealId, \"-p\", percentage]\n}\n\nconst buildFocusCommand = (targetRealId: string): string[] => {\n return [\"select-pane\", \"-t\", targetRealId]\n}\n\nexport const normalizePaneId = (raw: string): string => {\n const trimmed = raw.trim()\n return trimmed.length === 0 ? \"%0\" : trimmed\n}\n\nexport const registerPane = (paneMap: Map<string, string>, virtualId: string, realId: string): void => {\n paneMap.set(virtualId, realId)\n}\n\nexport const resolvePaneId = (paneMap: Map<string, string>, virtualId: string): string | undefined => {\n return resolvePaneMapping(paneMap, virtualId)\n}\n\nconst ensureNonEmpty = <T extends string>(value: T | undefined, buildError: () => never): T => {\n if (value === undefined || value.length === 0) {\n return buildError()\n }\n return value\n}\n\nexport const raiseExecutionError = (\n code: string,\n error: {\n readonly message: string\n readonly path: string\n readonly details?: Record<string, unknown>\n },\n): never => {\n throw createCoreError(\"execution\", {\n code,\n message: error.message,\n path: error.path,\n details: error.details,\n })\n}\n","import type { PlanEmission } from \"../core/emitter\"\nimport type { ConfirmPaneClosure } from \"../contracts\"\nimport type { CommandExecutor } from \"../contracts\"\nimport { ErrorCodes } from \"../utils/errors\"\nimport type { WindowMode } from \"../models/types\"\nimport {\n executeCommand,\n executeFocusStep,\n executeSplitStep,\n executeTerminalCommands,\n listWindowPaneIds,\n normalizePaneId,\n raiseExecutionError,\n registerPane,\n resolveCurrentPaneId,\n resolvePaneId,\n} from \"./plan-runner-helpers\"\n\ntype ExecutePlanInput = {\n readonly emission: PlanEmission\n readonly executor: CommandExecutor\n readonly windowName?: string\n readonly windowMode: WindowMode\n readonly onConfirmKill?: ConfirmPaneClosure\n}\n\ntype ExecutePlanSuccess = {\n readonly executedSteps: number\n}\n\nexport const executePlan = async ({\n emission,\n executor,\n windowName,\n windowMode,\n onConfirmKill,\n}: ExecutePlanInput): Promise<ExecutePlanSuccess> => {\n const initialVirtualPaneId = emission.summary.initialPaneId\n if (typeof initialVirtualPaneId !== \"string\" || initialVirtualPaneId.length === 0) {\n raiseExecutionError(ErrorCodes.INVALID_PLAN, {\n message: \"Plan emission is missing initial pane metadata\",\n path: \"plan.initialPaneId\",\n })\n }\n\n const paneMap = new Map<string, string>()\n\n const isDryRun = executor.isDryRun()\n\n let initialPaneId: string\n\n if (windowMode === \"current-window\") {\n const currentPaneId = await resolveCurrentPaneId({\n executor,\n contextPath: initialVirtualPaneId,\n isDryRun,\n })\n\n const panesInWindow = await listWindowPaneIds(executor, initialVirtualPaneId)\n const panesToClose = panesInWindow.filter((paneId) => paneId !== currentPaneId)\n\n if (panesToClose.length > 0) {\n let confirmed = true\n if (onConfirmKill !== undefined) {\n confirmed = await onConfirmKill({ panesToClose, dryRun: isDryRun })\n }\n\n if (confirmed !== true) {\n raiseExecutionError(ErrorCodes.USER_CANCELLED, {\n message: \"Aborted layout application for current window\",\n path: initialVirtualPaneId,\n details: { panes: panesToClose },\n })\n }\n\n await executeCommand(executor, [\"kill-pane\", \"-a\", \"-t\", currentPaneId], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to close existing panes\",\n path: initialVirtualPaneId,\n details: { command: [\"kill-pane\", \"-a\", \"-t\", currentPaneId] },\n })\n }\n\n initialPaneId = normalizePaneId(currentPaneId)\n } else {\n const newWindowCommand: string[] = [\"new-window\", \"-P\", \"-F\", \"#{pane_id}\"]\n if (typeof windowName === \"string\" && windowName.trim().length > 0) {\n newWindowCommand.push(\"-n\", windowName.trim())\n }\n\n const createdPane = await executeCommand(executor, newWindowCommand, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to create tmux window\",\n path: initialVirtualPaneId,\n })\n initialPaneId = normalizePaneId(createdPane)\n }\n\n registerPane(paneMap, initialVirtualPaneId, initialPaneId)\n\n let executedSteps = 0\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n await executeSplitStep({ step, executor, paneMap })\n executedSteps += 1\n } else if (step.kind === \"focus\") {\n await executeFocusStep({ step, executor, paneMap })\n executedSteps += 1\n } else {\n raiseExecutionError(ErrorCodes.INVALID_PLAN, {\n message: `Unsupported step kind in emission: ${String((step as { kind?: unknown }).kind)}`,\n path: step.id,\n })\n }\n }\n\n await executeTerminalCommands({\n terminals: emission.terminals,\n executor,\n paneMap,\n focusPaneVirtualId: emission.summary.focusPaneId,\n })\n\n const finalRealFocus = resolvePaneId(paneMap, emission.summary.focusPaneId)\n if (typeof finalRealFocus === \"string\" && finalRealFocus.length > 0) {\n await executeCommand(executor, [\"select-pane\", \"-t\", finalRealFocus], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to restore focus\",\n path: emission.summary.focusPaneId,\n })\n }\n\n return { executedSteps }\n}\n","import type { CommandStep } from \"../core/emitter\"\nimport { createCoreError } from \"../core/errors\"\nimport { ErrorCodes } from \"../utils/errors\"\n\nconst getStepLabel = (step: CommandStep): string => {\n if (step.kind === \"split\") {\n return \"Split\"\n }\n if (step.kind === \"focus\") {\n return \"Focus\"\n }\n return \"Step\"\n}\n\nexport const resolveRequiredStepTargetPaneId = (step: CommandStep): string => {\n if (typeof step.targetPaneId === \"string\" && step.targetPaneId.length > 0) {\n return step.targetPaneId\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.MISSING_TARGET,\n message: `${getStepLabel(step)} step missing target pane metadata`,\n path: step.id,\n })\n}\n","import { createCoreError } from \"../core/errors\"\nimport type { CoreError } from \"../core/errors\"\nimport { ErrorCodes } from \"../utils/errors\"\n\ntype UnsupportedStep = {\n readonly id: string\n readonly kind?: unknown\n}\n\nexport const createUnsupportedStepKindError = (step: UnsupportedStep): CoreError => {\n return createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: `Unsupported step kind in emission: ${String(step.kind)}`,\n path: step.id,\n })\n}\n","import { createTmuxExecutor } from \"./executor\"\nimport type { CommandStep, PlanEmission } from \"../../core/emitter\"\nimport { executePlan } from \"../../executor/plan-runner\"\nimport {\n resolveSplitOrientation as resolveSplitOrientationFromStep,\n resolveSplitPercentage as resolveSplitPercentageFromStep,\n} from \"../../executor/split-step\"\nimport { resolveRequiredStepTargetPaneId } from \"../../executor/step-target\"\nimport { createUnsupportedStepKindError } from \"../../executor/unsupported-step-kind\"\nimport type {\n ApplyPlanParameters,\n ApplyPlanResult,\n DryRunStep,\n TerminalBackend,\n TmuxTerminalBackendContext,\n} from \"../../executor/terminal-backend\"\n\nexport const createTmuxBackend = (context: TmuxTerminalBackendContext): TerminalBackend => {\n const tmuxExecutor = createTmuxExecutor({\n executor: context.executor,\n verbose: context.verbose,\n dryRun: context.dryRun,\n })\n\n const buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n return emission.steps.map((step) => ({\n backend: \"tmux\" as const,\n summary: step.summary,\n command: tmuxExecutor.getCommandString(buildTmuxCommand(step)),\n }))\n }\n\n const verifyEnvironment = async (): Promise<void> => {\n if (context.dryRun) {\n return\n }\n await tmuxExecutor.verifyTmuxEnvironment()\n }\n\n const applyPlan = async ({ emission, windowMode, windowName }: ApplyPlanParameters): Promise<ApplyPlanResult> => {\n const executionResult = await executePlan({\n emission,\n executor: tmuxExecutor.getExecutor(),\n windowMode,\n windowName,\n onConfirmKill: context.prompt,\n })\n\n return {\n executedSteps: executionResult.executedSteps,\n focusPaneId: emission.summary.focusPaneId,\n }\n }\n\n return {\n verifyEnvironment,\n applyPlan,\n getDryRunSteps: buildDryRunSteps,\n }\n}\n\nconst buildTmuxCommand = (step: CommandStep): string[] => {\n if (step.kind === \"split\") {\n const target = resolveRequiredStepTargetPaneId(step)\n const direction = resolveSplitOrientationFromStep(step) === \"horizontal\" ? \"-h\" : \"-v\"\n const percent = resolveSplitPercentageFromStep(step)\n return [\"split-window\", direction, \"-t\", target, \"-p\", percent]\n }\n\n if (step.kind === \"focus\") {\n const target = resolveRequiredStepTargetPaneId(step)\n return [\"select-pane\", \"-t\", target]\n }\n\n throw createUnsupportedStepKindError(step)\n}\n","type WeztermListPane = {\n readonly paneId: string\n readonly isActive: boolean\n}\n\ntype WeztermListTab = {\n readonly tabId: string\n readonly isActive: boolean\n readonly panes: ReadonlyArray<WeztermListPane>\n}\n\nexport type WeztermListWindow = {\n readonly windowId: string\n readonly isActive: boolean\n readonly workspace?: string\n readonly tabs: ReadonlyArray<WeztermListTab>\n}\n\nexport type WeztermListResult = {\n readonly windows: ReadonlyArray<WeztermListWindow>\n}\n\ntype RawListPane = {\n readonly pane_id?: number | string\n readonly is_active?: unknown\n}\n\ntype RawListTab = {\n readonly tab_id?: number | string\n readonly is_active?: unknown\n readonly panes?: RawListPane[]\n}\n\ntype RawListWindow = {\n readonly window_id?: number | string\n readonly is_active?: unknown\n readonly workspace?: unknown\n readonly tabs?: RawListTab[]\n}\n\ntype RawListEntry = {\n readonly window_id?: number | string\n readonly tab_id?: number | string\n readonly pane_id?: number | string\n readonly workspace?: unknown\n readonly is_active?: unknown\n}\n\ntype RawListResult = {\n readonly windows?: RawListWindow[]\n}\n\nconst toIdString = (value: unknown): string | undefined => {\n if (typeof value === \"string\") {\n return value\n }\n if (typeof value === \"number\") {\n return value.toString()\n }\n return undefined\n}\n\nconst isNonEmptyString = (value: string | undefined): value is string => {\n return typeof value === \"string\" && value.length > 0\n}\n\nconst toWorkspaceString = (value: unknown): string | undefined => {\n if (typeof value === \"string\" && value.length > 0) {\n return value\n }\n return undefined\n}\n\ntype MutableTabRecord = {\n tabId: string\n isActive: boolean\n panes: WeztermListPane[]\n}\n\ntype MutableWindowRecord = {\n windowId: string\n isActive: boolean\n workspace?: string\n tabs: Map<string, MutableTabRecord>\n}\n\ntype NormalizedArrayEntry = {\n windowId: string\n tabId: string\n paneId: string\n workspace?: string\n isActive: boolean\n}\n\nconst toImmutablePanes = (panes: ReadonlyArray<WeztermListPane>): WeztermListPane[] => {\n return panes.map(\n (pane): WeztermListPane => ({\n paneId: pane.paneId,\n isActive: pane.isActive,\n }),\n )\n}\n\nconst toImmutableTabs = (tabs: ReadonlyMap<string, MutableTabRecord>): WeztermListTab[] => {\n return Array.from(tabs.values()).map(\n (tabRecord): WeztermListTab => ({\n tabId: tabRecord.tabId,\n isActive: tabRecord.isActive,\n panes: toImmutablePanes(tabRecord.panes),\n }),\n )\n}\n\nconst toImmutableWindows = (windows: ReadonlyMap<string, MutableWindowRecord>): WeztermListWindow[] => {\n return Array.from(windows.values()).map(\n (windowRecord): WeztermListWindow => ({\n windowId: windowRecord.windowId,\n isActive: windowRecord.isActive,\n workspace: windowRecord.workspace,\n tabs: toImmutableTabs(windowRecord.tabs),\n }),\n )\n}\n\nconst normalizeArrayEntry = (entry: unknown): NormalizedArrayEntry | undefined => {\n if (typeof entry !== \"object\" || entry === null) {\n return undefined\n }\n const listEntry = entry as RawListEntry\n const windowIdRaw = toIdString(listEntry.window_id)\n const paneIdRaw = toIdString(listEntry.pane_id)\n const tabIdRaw = toIdString(listEntry.tab_id) ?? windowIdRaw\n if (!isNonEmptyString(windowIdRaw) || !isNonEmptyString(tabIdRaw) || !isNonEmptyString(paneIdRaw)) {\n return undefined\n }\n return {\n windowId: windowIdRaw,\n tabId: tabIdRaw,\n paneId: paneIdRaw,\n workspace: toWorkspaceString(listEntry.workspace),\n isActive: listEntry.is_active === true,\n }\n}\n\nconst getOrCreateWindowRecord = (\n windows: Map<string, MutableWindowRecord>,\n entry: NormalizedArrayEntry,\n): MutableWindowRecord => {\n const existingWindow = windows.get(entry.windowId)\n if (existingWindow) {\n if (entry.workspace !== undefined && existingWindow.workspace === undefined) {\n existingWindow.workspace = entry.workspace\n }\n return existingWindow\n }\n const createdWindow: MutableWindowRecord = {\n windowId: entry.windowId,\n isActive: false,\n workspace: entry.workspace,\n tabs: new Map(),\n }\n windows.set(entry.windowId, createdWindow)\n return createdWindow\n}\n\nconst getOrCreateTabRecord = (windowRecord: MutableWindowRecord, tabId: string): MutableTabRecord => {\n const existingTab = windowRecord.tabs.get(tabId)\n if (existingTab) {\n return existingTab\n }\n const createdTab: MutableTabRecord = {\n tabId,\n isActive: false,\n panes: [],\n }\n windowRecord.tabs.set(tabId, createdTab)\n return createdTab\n}\n\nconst parseArrayResponse = (parsed: unknown): WeztermListResult | undefined => {\n if (!Array.isArray(parsed)) {\n return undefined\n }\n\n const windowMap = new Map<string, MutableWindowRecord>()\n for (const entry of parsed) {\n const normalizedEntry = normalizeArrayEntry(entry)\n if (!normalizedEntry) {\n continue\n }\n\n const windowRecord = getOrCreateWindowRecord(windowMap, normalizedEntry)\n const tabRecord = getOrCreateTabRecord(windowRecord, normalizedEntry.tabId)\n\n windowRecord.isActive ||= normalizedEntry.isActive\n tabRecord.isActive ||= normalizedEntry.isActive\n tabRecord.panes.push({\n paneId: normalizedEntry.paneId,\n isActive: normalizedEntry.isActive,\n })\n }\n\n return { windows: toImmutableWindows(windowMap) }\n}\n\nconst parseObjectPane = (pane: unknown): WeztermListPane | undefined => {\n if (typeof pane !== \"object\" || pane === null) {\n return undefined\n }\n const rawPane = pane as RawListPane\n const paneIdRaw = toIdString(rawPane.pane_id)\n if (!isNonEmptyString(paneIdRaw)) {\n return undefined\n }\n return {\n paneId: paneIdRaw,\n isActive: rawPane.is_active === true,\n }\n}\n\nconst parseObjectTab = (tab: unknown): WeztermListTab | undefined => {\n if (typeof tab !== \"object\" || tab === null) {\n return undefined\n }\n const rawTab = tab as RawListTab\n const tabIdRaw = toIdString(rawTab.tab_id)\n if (!isNonEmptyString(tabIdRaw)) {\n return undefined\n }\n\n const paneRecords = Array.isArray(rawTab.panes) ? rawTab.panes : []\n const panes: WeztermListPane[] = []\n for (const pane of paneRecords) {\n const mappedPane = parseObjectPane(pane)\n if (mappedPane) {\n panes.push(mappedPane)\n }\n }\n\n return {\n tabId: tabIdRaw,\n isActive: rawTab.is_active === true,\n panes,\n }\n}\n\nconst parseObjectWindow = (window: unknown): WeztermListWindow | undefined => {\n if (typeof window !== \"object\" || window === null) {\n return undefined\n }\n const rawWindow = window as RawListWindow\n const windowIdRaw = toIdString(rawWindow.window_id)\n if (!isNonEmptyString(windowIdRaw)) {\n return undefined\n }\n\n const tabs: WeztermListTab[] = []\n const rawTabs = Array.isArray(rawWindow.tabs) ? rawWindow.tabs : []\n for (const tab of rawTabs) {\n const mappedTab = parseObjectTab(tab)\n if (mappedTab) {\n tabs.push(mappedTab)\n }\n }\n\n return {\n windowId: windowIdRaw,\n isActive: rawWindow.is_active === true,\n workspace: toWorkspaceString(rawWindow.workspace),\n tabs,\n }\n}\n\nconst parseObjectResponse = (parsed: unknown): WeztermListResult | undefined => {\n if (typeof parsed !== \"object\" || parsed === null) {\n return undefined\n }\n\n const candidate = parsed as Partial<RawListResult>\n const rawWindows = Array.isArray(candidate.windows) ? candidate.windows : []\n const windows: WeztermListWindow[] = []\n for (const window of rawWindows) {\n const mappedWindow = parseObjectWindow(window)\n if (mappedWindow) {\n windows.push(mappedWindow)\n }\n }\n return { windows }\n}\n\nexport const parseWeztermListResult = (stdout: string): WeztermListResult | undefined => {\n try {\n const parsed: unknown = JSON.parse(stdout)\n return parseArrayResponse(parsed) ?? parseObjectResponse(parsed)\n } catch {\n return undefined\n }\n}\n","import { execa } from \"execa\"\nimport { createEnvironmentError, ErrorCodes } from \"../../utils/errors\"\nimport { createCoreError } from \"../../core/errors\"\nimport { parseWeztermListResult, type WeztermListResult } from \"./list-parser\"\n\nexport type { WeztermListResult } from \"./list-parser\"\n\nconst WEZTERM_BINARY = \"wezterm\"\nconst MINIMUM_VERSION = \"20220624-141144-bd1b7c5d\"\nconst VERSION_REGEX = /(\\d{8})-(\\d{6})-([0-9a-fA-F]+)/i\n\ntype ExecaLikeError = Error & {\n readonly exitCode?: number\n readonly code?: string\n readonly stderr?: string\n readonly stdout?: string\n}\n\nexport const verifyWeztermAvailability = async (): Promise<{ version: string }> => {\n let stdout: string\n try {\n const result = await execa(WEZTERM_BINARY, [\"--version\"])\n stdout = result.stdout\n } catch (error) {\n const execaError = error as ExecaLikeError\n if (execaError.code === \"ENOENT\") {\n throw createEnvironmentError(\"wezterm is not installed\", ErrorCodes.BACKEND_NOT_FOUND, {\n backend: \"wezterm\",\n binary: WEZTERM_BINARY,\n })\n }\n throw createEnvironmentError(\"Failed to execute wezterm --version\", ErrorCodes.WEZTERM_NOT_FOUND, {\n backend: \"wezterm\",\n binary: WEZTERM_BINARY,\n stderr: execaError.stderr,\n })\n }\n\n const detectedVersion = extractVersion(stdout)\n if (detectedVersion === undefined) {\n throw createEnvironmentError(\"Unable to determine wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n requiredVersion: MINIMUM_VERSION,\n detectedVersion: stdout.trim(),\n })\n }\n\n if (!isVersionSupported(detectedVersion, MINIMUM_VERSION)) {\n throw createEnvironmentError(\"Unsupported wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n requiredVersion: MINIMUM_VERSION,\n detectedVersion,\n })\n }\n\n return { version: detectedVersion }\n}\n\nexport type RunWeztermErrorContext = {\n readonly message: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n}\n\nexport const runWeztermCli = async (args: string[], errorContext: RunWeztermErrorContext): Promise<string> => {\n try {\n const result = await execa(WEZTERM_BINARY, [\"cli\", ...args])\n return result.stdout\n } catch (error) {\n const execaError = error as ExecaLikeError\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: errorContext.message,\n path: errorContext.path,\n details: {\n command: [WEZTERM_BINARY, \"cli\", ...args],\n stderr: execaError.stderr,\n exitCode: execaError.exitCode,\n backend: \"wezterm\",\n ...(errorContext.details ?? {}),\n },\n })\n }\n}\n\nexport const listWeztermWindows = async (): Promise<WeztermListResult> => {\n const stdout = await runWeztermCli([\"list\", \"--format\", \"json\"], { message: \"Failed to list wezterm panes\" })\n const result = parseWeztermListResult(stdout)\n if (result === undefined) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"Invalid wezterm list output\",\n details: { stdout },\n })\n }\n return result\n}\n\nexport const killWeztermPane = async (paneId: string): Promise<void> => {\n await runWeztermCli([\"kill-pane\", \"--pane-id\", paneId], {\n message: `Failed to kill wezterm pane ${paneId}`,\n path: paneId,\n })\n}\n\nconst extractVersion = (raw: string): string | undefined => {\n const match = raw.match(VERSION_REGEX)\n if (!match) {\n return undefined\n }\n const date = match[1]\n const time = match[2]\n const commit = match[3]\n if (date === undefined || time === undefined || commit === undefined) {\n return undefined\n }\n return `${date}-${time}-${commit.toLowerCase()}`\n}\n\nconst isVersionSupported = (detected: string, minimum: string): boolean => {\n const parse = (version: string): { build: number; commit: string } | undefined => {\n const match = version.match(VERSION_REGEX)\n if (!match) {\n return undefined\n }\n const date = match[1]\n const time = match[2]\n const commit = match[3]\n if (date === undefined || time === undefined || commit === undefined) {\n return undefined\n }\n const build = Number(`${date}${time}`)\n if (Number.isNaN(build)) {\n return undefined\n }\n return { build, commit: commit.toLowerCase() }\n }\n\n const detectedInfo = parse(detected)\n const minimumInfo = parse(minimum)\n if (detectedInfo === undefined || minimumInfo === undefined) {\n return false\n }\n\n if (detectedInfo.build > minimumInfo.build) {\n return true\n }\n if (detectedInfo.build < minimumInfo.build) {\n return false\n }\n\n return detectedInfo.commit >= minimumInfo.commit\n}\n","import type { PlanEmission } from \"../../core/emitter\"\nimport { createCoreError } from \"../../core/errors\"\nimport { resolveSplitOrientation, resolveSplitPercentage } from \"../../executor/split-step\"\nimport { resolveRequiredStepTargetPaneId } from \"../../executor/step-target\"\nimport { prepareTerminalCommands } from \"../../executor/terminal-command-preparation\"\nimport type { DryRunStep } from \"../../executor/terminal-backend\"\nimport { ErrorCodes } from \"../../utils/errors\"\n\nconst SINGLE_QUOTE = \"'\"\nconst SHELL_SINGLE_QUOTE_ESCAPE = `'\"'\"'`\n\nexport const buildSplitArguments = (params: {\n readonly targetPaneId: string\n readonly percent: string\n readonly horizontal: boolean\n}): string[] => {\n const directionFlag = params.horizontal ? \"--right\" : \"--bottom\"\n return [\"split-pane\", directionFlag, \"--percent\", params.percent, \"--pane-id\", params.targetPaneId]\n}\n\nexport const buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n const steps: DryRunStep[] = []\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n const target = resolveRequiredStepTargetPaneId(step)\n const args = buildSplitArguments({\n targetPaneId: target,\n percent: resolveSplitPercentage(step),\n horizontal: resolveSplitOrientation(step) === \"horizontal\",\n })\n steps.push({\n backend: \"wezterm\",\n summary: step.summary,\n command: `wezterm cli ${args.join(\" \")}`,\n })\n continue\n }\n\n if (step.kind === \"focus\") {\n const target = resolveRequiredStepTargetPaneId(step)\n steps.push({\n backend: \"wezterm\",\n summary: step.summary,\n command: `wezterm cli activate-pane --pane-id ${target}`,\n })\n continue\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: `Unsupported step kind in emission: ${String((step as { kind?: unknown }).kind)}`,\n path: step.id,\n })\n }\n\n const prepared = prepareTerminalCommands({\n terminals: emission.terminals,\n focusPaneVirtualId: emission.summary.focusPaneId,\n resolveRealPaneId: (virtualPaneId: string): string => virtualPaneId,\n onTemplateTokenError: ({ terminal, error }): never => {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TEMPLATE_TOKEN_ERROR,\n message: `Template token resolution failed for pane ${terminal.virtualPaneId}: ${error.message}`,\n path: terminal.virtualPaneId,\n details: {\n command: terminal.command,\n tokenType: error.tokenType,\n availablePanes: error.availablePanes,\n },\n })\n },\n })\n\n const quoteForShellDisplay = (value: string): string => {\n return `${SINGLE_QUOTE}${value.split(SINGLE_QUOTE).join(SHELL_SINGLE_QUOTE_ESCAPE)}${SINGLE_QUOTE}`\n }\n\n for (const commandSet of prepared.commands) {\n const paneId = commandSet.terminal.virtualPaneId\n if (typeof commandSet.cwdCommand === \"string\") {\n steps.push({\n backend: \"wezterm\",\n summary: `set cwd for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- ${quoteForShellDisplay(commandSet.cwdCommand)}`,\n })\n }\n\n for (const envEntry of commandSet.envCommands) {\n steps.push({\n backend: \"wezterm\",\n summary: `set env ${envEntry.key} for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- ${quoteForShellDisplay(envEntry.command)}`,\n })\n }\n\n if (commandSet.command !== undefined) {\n steps.push({\n backend: \"wezterm\",\n summary: `run command for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- ${quoteForShellDisplay(commandSet.command.text)}`,\n })\n }\n }\n\n return steps\n}\n","import { createCoreError } from \"../../core/errors\"\nimport type { WindowMode } from \"../../models/types\"\nimport type { ConfirmPaneClosure } from \"../../contracts\"\nimport { waitForDelay } from \"../../utils/async\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport { killWeztermPane, type WeztermListResult } from \"./cli\"\nimport type { ExecuteWeztermCommand, ListWeztermWindows } from \"./shared\"\n\nconst PANE_REGISTRATION_RETRIES = 5\nconst PANE_REGISTRATION_DELAY_MS = 100\n\ntype InitialPaneResolution = {\n readonly paneId: string\n readonly windowId: string\n}\n\ntype CurrentWindowResolution = InitialPaneResolution & {\n readonly panesToClose: ReadonlyArray<string>\n}\n\nconst resolveCurrentWindow = async (context: {\n readonly list: WeztermListResult\n readonly prompt?: ConfirmPaneClosure\n readonly dryRun: boolean\n readonly logCommand: (args: ReadonlyArray<string>) => void\n readonly preferredPaneId?: string\n}): Promise<CurrentWindowResolution> => {\n const hasPreferredPane = typeof context.preferredPaneId === \"string\" && context.preferredPaneId.length > 0\n const preferredPaneId = hasPreferredPane ? (context.preferredPaneId as string) : undefined\n const preferredWindowId =\n preferredPaneId !== undefined ? findWindowContainingPane(context.list, preferredPaneId) : undefined\n\n const activeWindow =\n (preferredWindowId !== undefined\n ? context.list.windows.find((window) => window.windowId === preferredWindowId)\n : undefined) ??\n context.list.windows.find((window) => window.isActive) ??\n context.list.windows[0]\n\n if (!activeWindow) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"No active wezterm window detected\",\n details: { hint: \"Launch wezterm and ensure a window is focused, or run with --new-window.\" },\n })\n }\n\n const activeTab =\n (preferredPaneId !== undefined\n ? activeWindow.tabs.find((tab) => tab.panes.some((pane) => pane.paneId === preferredPaneId))\n : undefined) ??\n activeWindow.tabs.find((tab) => tab.isActive) ??\n activeWindow.tabs[0]\n\n if (!activeTab) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"No active wezterm tab detected\",\n path: activeWindow.windowId,\n details: { hint: \"Ensure a wezterm tab is focused before using --current-window.\" },\n })\n }\n\n const activePane =\n (preferredPaneId !== undefined ? activeTab.panes.find((pane) => pane.paneId === preferredPaneId) : undefined) ??\n activeTab.panes.find((pane) => pane.isActive) ??\n activeTab.panes[0]\n\n if (!activePane) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"No active wezterm pane detected\",\n path: activeTab.tabId,\n details: { hint: \"Ensure a wezterm pane is active before using --current-window.\" },\n })\n }\n\n const panesToClose = activeTab.panes.filter((pane) => pane.paneId !== activePane.paneId).map((pane) => pane.paneId)\n\n if (panesToClose.length > 0) {\n let confirmed = true\n if (context.prompt) {\n confirmed = await context.prompt({ panesToClose, dryRun: context.dryRun })\n }\n\n if (confirmed !== true) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.USER_CANCELLED,\n message: \"Aborted layout application for current wezterm window\",\n path: activePane.paneId,\n details: { panes: panesToClose },\n })\n }\n\n for (const paneId of panesToClose) {\n context.logCommand([\"kill-pane\", \"--pane-id\", paneId])\n await killWeztermPane(paneId)\n }\n }\n\n return {\n paneId: activePane.paneId,\n windowId: activeWindow.windowId,\n panesToClose,\n }\n}\n\nconst findActiveWindow = (\n list: WeztermListResult,\n): { windowId: string; tabs: (typeof list.windows)[number][\"tabs\"] } | undefined => {\n return list.windows.find((window) => window.isActive) ?? list.windows[0]\n}\n\nconst findWindowContainingPane = (list: WeztermListResult, paneId: string): string | undefined => {\n for (const window of list.windows) {\n for (const tab of window.tabs) {\n for (const pane of tab.panes) {\n if (pane.paneId === paneId) {\n return window.windowId\n }\n }\n }\n }\n return undefined\n}\n\nexport const findWorkspaceForPane = (list: WeztermListResult, paneId: string): string | undefined => {\n for (const window of list.windows) {\n for (const tab of window.tabs) {\n for (const pane of tab.panes) {\n if (pane.paneId === paneId) {\n return window.workspace\n }\n }\n }\n }\n return undefined\n}\n\nconst filterWindowsByWorkspace = (list: WeztermListResult, workspace?: string): WeztermListResult => {\n if (workspace === undefined || workspace.length === 0) {\n return list\n }\n const scoped = list.windows.filter((window) => window.workspace === workspace)\n if (scoped.length === 0) {\n return list\n }\n return { windows: scoped }\n}\n\nexport const collectPaneIdsForWindow = (list: WeztermListResult, windowId: string): Set<string> => {\n const targetWindow = list.windows.find((window) => window.windowId === windowId)\n if (!targetWindow) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: `Wezterm window ${windowId} not found`,\n details: { windowId },\n })\n }\n\n const paneIds = targetWindow.tabs.flatMap((tab) => tab.panes.map((pane) => pane.paneId))\n return new Set(paneIds)\n}\n\nconst waitForPaneRegistration = async ({\n paneId,\n listWindows,\n windowHint,\n}: {\n readonly paneId: string\n readonly listWindows: ListWeztermWindows\n readonly windowHint?: string\n}): Promise<string> => {\n for (let attempt = 0; attempt < PANE_REGISTRATION_RETRIES; attempt += 1) {\n const snapshot = await listWindows()\n\n if (typeof windowHint === \"string\") {\n try {\n const panes = collectPaneIdsForWindow(snapshot, windowHint)\n if (panes.has(paneId)) {\n return windowHint\n }\n } catch {\n // window may not be ready yet; fall through to global search.\n }\n }\n\n const located = findWindowContainingPane(snapshot, paneId)\n if (typeof located === \"string\" && located.length > 0) {\n return located\n }\n\n if (attempt < PANE_REGISTRATION_RETRIES - 1) {\n await waitForDelay(PANE_REGISTRATION_DELAY_MS)\n }\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"Unable to locate spawned wezterm window\",\n details: { paneId, hint: \"Verify that wezterm is running and the CLI client can connect.\" },\n })\n}\n\nconst extractSpawnPaneId = (output: string): string => {\n const trimmed = output.trim()\n if (trimmed.length === 0) {\n return \"\"\n }\n\n const lastLine = trimmed.split(\"\\n\").pop() ?? \"\"\n const tokens = lastLine.split(/\\s+/).filter((segment) => segment.length > 0)\n if (tokens.length === 0) {\n return \"\"\n }\n // wezterm cli spawn outputs pane-id first, followed by optional window or tab metadata\n const [paneId] = tokens\n if (typeof paneId !== \"string\") {\n return \"\"\n }\n return paneId.trim()\n}\n\nexport const resolveInitialPane = async ({\n windowMode,\n prompt,\n dryRun,\n listWindows,\n runCommand,\n logCommand,\n initialCwd,\n workspaceHint,\n initialList,\n preferredPaneId,\n}: {\n readonly windowMode: WindowMode\n readonly prompt?: ConfirmPaneClosure\n readonly dryRun: boolean\n readonly listWindows: ListWeztermWindows\n readonly runCommand: ExecuteWeztermCommand\n readonly logCommand: (args: ReadonlyArray<string>) => void\n readonly initialCwd?: string\n readonly workspaceHint?: string\n readonly initialList?: WeztermListResult\n readonly preferredPaneId?: string\n}): Promise<InitialPaneResolution> => {\n const hasPreferredPane = typeof preferredPaneId === \"string\" && preferredPaneId.length > 0\n const preferredPaneIdValue = hasPreferredPane ? (preferredPaneId as string) : undefined\n\n if (windowMode === \"current-window\") {\n const snapshot = initialList ?? (await listWindows())\n const scoped = filterWindowsByWorkspace(snapshot, workspaceHint)\n return resolveCurrentWindow({ list: scoped, prompt, dryRun, logCommand, preferredPaneId: preferredPaneIdValue })\n }\n\n const existingSnapshot = initialList ?? (await listWindows())\n const scopedExisting = filterWindowsByWorkspace(existingSnapshot, workspaceHint)\n const scopedPreferredWindowId =\n preferredPaneIdValue !== undefined ? findWindowContainingPane(scopedExisting, preferredPaneIdValue) : undefined\n const activeWindow =\n (scopedPreferredWindowId !== undefined\n ? scopedExisting.windows.find((window) => window.windowId === scopedPreferredWindowId)\n : undefined) ?? findActiveWindow(scopedExisting)\n\n if (activeWindow) {\n const args = [\"spawn\", \"--window-id\", activeWindow.windowId] as string[]\n if (typeof initialCwd === \"string\" && initialCwd.length > 0) {\n args.push(\"--cwd\", initialCwd)\n }\n const spawnOutput = await runCommand(args, {\n message: \"Failed to spawn wezterm tab\",\n })\n const paneId = extractSpawnPaneId(spawnOutput)\n if (paneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"wezterm spawn did not return a pane id\",\n details: { stdout: spawnOutput },\n })\n }\n const windowId = await waitForPaneRegistration({\n paneId,\n listWindows,\n windowHint: activeWindow.windowId,\n })\n return { paneId, windowId }\n }\n\n const args = [\"spawn\", \"--new-window\"] as string[]\n if (typeof initialCwd === \"string\" && initialCwd.length > 0) {\n args.push(\"--cwd\", initialCwd)\n }\n if (typeof workspaceHint === \"string\" && workspaceHint.length > 0) {\n args.push(\"--workspace\", workspaceHint)\n }\n const spawnOutput = await runCommand(args, {\n message: \"Failed to spawn wezterm window\",\n })\n const paneId = extractSpawnPaneId(spawnOutput)\n if (paneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"wezterm spawn did not return a pane id\",\n details: { stdout: spawnOutput },\n })\n }\n\n const newWindowId = await waitForPaneRegistration({\n paneId,\n listWindows,\n })\n return { paneId, windowId: newWindowId }\n}\n","import { createCoreError } from \"../../core/errors\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport { resolvePaneMapping } from \"../../utils/pane-map\"\nimport type { PaneMap } from \"./shared\"\n\nexport const registerPaneWithAncestors = (map: PaneMap, virtualId: string, realId: string): void => {\n map.set(virtualId, realId)\n\n let ancestor = virtualId\n while (ancestor.includes(\".\")) {\n ancestor = ancestor.slice(0, ancestor.lastIndexOf(\".\"))\n if (!map.has(ancestor)) {\n map.set(ancestor, realId)\n } else {\n break\n }\n }\n}\n\nexport const resolveRealPaneId = (\n paneMap: PaneMap,\n virtualId: string,\n context: { readonly stepId: string },\n): string => {\n const resolved = resolvePaneMapping(paneMap, virtualId)\n if (typeof resolved === \"string\" && resolved.length > 0) {\n return resolved\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: `Unknown wezterm pane mapping for ${virtualId}`,\n path: context.stepId,\n })\n}\n","import type { CommandStep, EmittedTerminal } from \"../../core/emitter\"\nimport { createCoreError } from \"../../core/errors\"\nimport { resolveSplitOrientation, resolveSplitPercentage } from \"../../executor/split-step\"\nimport { prepareTerminalCommands } from \"../../executor/terminal-command-preparation\"\nimport { waitForDelay } from \"../../utils/async\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport { buildSplitArguments } from \"./dry-run\"\nimport { collectPaneIdsForWindow } from \"./layout-resolution\"\nimport { registerPaneWithAncestors, resolveRealPaneId } from \"./pane-map\"\nimport type { ExecuteWeztermCommand, ListWeztermWindows, LogPaneMapping, PaneMap } from \"./shared\"\n\nconst findNewPaneId = (before: Set<string>, after: Set<string>): string | undefined => {\n for (const paneId of after) {\n if (!before.has(paneId)) {\n return paneId\n }\n }\n return undefined\n}\n\nconst appendCarriageReturn = (value: string): string => {\n return value.endsWith(\"\\r\") ? value : `${value}\\r`\n}\n\nconst sendTextToPane = async ({\n paneId,\n text,\n runCommand,\n context,\n}: {\n readonly paneId: string\n readonly text: string\n readonly runCommand: ExecuteWeztermCommand\n readonly context: { readonly message: string; readonly path: string; readonly details?: Record<string, unknown> }\n}): Promise<void> => {\n await runCommand([\"send-text\", \"--pane-id\", paneId, \"--no-paste\", \"--\", appendCarriageReturn(text)], context)\n}\n\nexport const applyFocusStep = async ({\n step,\n paneMap,\n runCommand,\n}: {\n readonly step: CommandStep\n readonly paneMap: PaneMap\n readonly runCommand: ExecuteWeztermCommand\n}): Promise<void> => {\n const targetVirtualId = step.targetPaneId\n if (typeof targetVirtualId !== \"string\" || targetVirtualId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: \"Focus step missing target pane metadata\",\n path: step.id,\n })\n }\n\n const targetRealId = resolveRealPaneId(paneMap, targetVirtualId, { stepId: step.id })\n\n await runCommand([\"activate-pane\", \"--pane-id\", targetRealId], {\n message: `Failed to execute focus step ${step.id}`,\n path: step.id,\n })\n}\n\nexport const applySplitStep = async ({\n step,\n paneMap,\n windowId,\n runCommand,\n listWindows,\n logPaneMapping,\n}: {\n readonly step: CommandStep\n readonly paneMap: PaneMap\n readonly windowId: string\n readonly runCommand: ExecuteWeztermCommand\n readonly listWindows: ListWeztermWindows\n readonly logPaneMapping: LogPaneMapping\n}): Promise<void> => {\n const targetVirtualId = step.targetPaneId\n if (typeof targetVirtualId !== \"string\" || targetVirtualId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: \"Split step missing target pane metadata\",\n path: step.id,\n })\n }\n\n const targetRealId = resolveRealPaneId(paneMap, targetVirtualId, { stepId: step.id })\n\n const beforeList = await listWindows()\n const beforePaneIds = collectPaneIdsForWindow(beforeList, windowId)\n\n const args = buildSplitArguments({\n targetPaneId: targetRealId,\n percent: resolveSplitPercentage(step),\n horizontal: resolveSplitOrientation(step) === \"horizontal\",\n })\n\n await runCommand(args, {\n message: `Failed to execute split step ${step.id}`,\n path: step.id,\n })\n\n const afterList = await listWindows()\n const afterPaneIds = collectPaneIdsForWindow(afterList, windowId)\n\n const newPaneId = findNewPaneId(beforePaneIds, afterPaneIds)\n if (typeof newPaneId !== \"string\" || newPaneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"Unable to determine newly created wezterm pane\",\n path: step.id,\n })\n }\n\n if (typeof step.createdPaneId === \"string\" && step.createdPaneId.length > 0) {\n registerPaneWithAncestors(paneMap, step.createdPaneId, newPaneId)\n logPaneMapping(step.createdPaneId, newPaneId)\n }\n}\n\nexport const applyTerminalCommands = async ({\n terminals,\n paneMap,\n runCommand,\n focusPaneVirtualId,\n}: {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly paneMap: PaneMap\n readonly runCommand: ExecuteWeztermCommand\n readonly focusPaneVirtualId: string\n}): Promise<void> => {\n if (!paneMap.has(focusPaneVirtualId)) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: `Unknown focus pane: ${focusPaneVirtualId}`,\n path: focusPaneVirtualId,\n })\n }\n\n const prepared = prepareTerminalCommands({\n terminals,\n focusPaneVirtualId,\n resolveRealPaneId: (virtualPaneId: string): string =>\n resolveRealPaneId(paneMap, virtualPaneId, {\n stepId: virtualPaneId,\n }),\n onTemplateTokenError: ({ terminal, error }): never => {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TEMPLATE_TOKEN_ERROR,\n message: `Template token resolution failed for pane ${terminal.virtualPaneId}: ${error.message}`,\n path: terminal.virtualPaneId,\n details: {\n command: terminal.command,\n tokenType: error.tokenType,\n availablePanes: error.availablePanes,\n },\n })\n },\n })\n\n for (const commandSet of prepared.commands) {\n const { terminal, realPaneId } = commandSet\n\n if (typeof commandSet.cwdCommand === \"string\") {\n await sendTextToPane({\n paneId: realPaneId,\n text: commandSet.cwdCommand,\n runCommand,\n context: {\n message: `Failed to change directory for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { cwd: terminal.cwd },\n },\n })\n }\n\n for (const envEntry of commandSet.envCommands) {\n await sendTextToPane({\n paneId: realPaneId,\n text: envEntry.command,\n runCommand,\n context: {\n message: `Failed to set environment variable ${envEntry.key}`,\n path: terminal.virtualPaneId,\n },\n })\n }\n\n if (commandSet.command !== undefined) {\n if (commandSet.command.delayMs > 0) {\n await waitForDelay(commandSet.command.delayMs)\n }\n\n await sendTextToPane({\n paneId: realPaneId,\n text: commandSet.command.text,\n runCommand,\n context: {\n message: `Failed to execute command for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { command: terminal.command },\n },\n })\n }\n }\n}\n","import type { PlanEmission } from \"../../core/emitter\"\nimport { createCoreError } from \"../../core/errors\"\nimport type {\n ApplyPlanParameters,\n ApplyPlanResult,\n TerminalBackend,\n WeztermTerminalBackendContext,\n} from \"../../executor/terminal-backend\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport { listWeztermWindows, runWeztermCli, verifyWeztermAvailability, type WeztermListResult } from \"./cli\"\nimport { buildDryRunSteps } from \"./dry-run\"\nimport { findWorkspaceForPane, resolveInitialPane } from \"./layout-resolution\"\nimport { registerPaneWithAncestors } from \"./pane-map\"\nimport { applyFocusStep, applySplitStep, applyTerminalCommands } from \"./step-execution\"\nimport type { ExecuteWeztermCommand, PaneMap } from \"./shared\"\n\nconst ensureVirtualPaneId = (emission: PlanEmission): string => {\n const { initialPaneId } = emission.summary\n if (typeof initialPaneId !== \"string\" || initialPaneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: \"Plan emission is missing initial pane metadata\",\n path: \"plan.initialPaneId\",\n })\n }\n return initialPaneId\n}\n\nexport const createWeztermBackend = (context: WeztermTerminalBackendContext): TerminalBackend => {\n const formatCommand = (args: ReadonlyArray<string>): string => {\n return `wezterm cli ${args.join(\" \")}`\n }\n\n const logCommand = (args: ReadonlyArray<string>): void => {\n const message = `[wezterm] ${formatCommand(args)}`\n if (context.verbose) {\n context.logger.info(message)\n } else {\n context.logger.debug(message)\n }\n }\n\n const logPaneMapping = (virtualId: string, realId: string): void => {\n const message = `[wezterm] pane ${virtualId} -> ${realId}`\n if (context.verbose) {\n context.logger.info(message)\n } else {\n context.logger.debug(message)\n }\n }\n\n const runCommand: ExecuteWeztermCommand = async (args, errorContext) => {\n const commandArgs = [...args]\n logCommand(commandArgs)\n return runWeztermCli(commandArgs, errorContext)\n }\n\n const listWindows = async (): Promise<WeztermListResult> => {\n logCommand([\"list\", \"--format\", \"json\"])\n return listWeztermWindows()\n }\n\n const verifyEnvironment = async (): Promise<void> => {\n if (context.dryRun) {\n return\n }\n await verifyWeztermAvailability()\n }\n\n const applyPlan = async ({ emission, windowMode }: ApplyPlanParameters): Promise<ApplyPlanResult> => {\n const initialVirtualPaneId = ensureVirtualPaneId(emission)\n const paneMap: PaneMap = new Map()\n const initialTerminal = emission.terminals.find((terminal) => terminal.virtualPaneId === initialVirtualPaneId)\n const initialCwd =\n typeof initialTerminal?.cwd === \"string\" && initialTerminal.cwd.length > 0 ? initialTerminal.cwd : context.cwd\n\n let cachedInitialList: WeztermListResult | undefined\n let workspaceHint: string | undefined\n if (typeof context.paneId === \"string\" && context.paneId.length > 0) {\n try {\n cachedInitialList = await listWindows()\n workspaceHint = findWorkspaceForPane(cachedInitialList, context.paneId)\n } catch {\n cachedInitialList = undefined\n workspaceHint = undefined\n }\n }\n\n const { paneId: initialPaneId, windowId } = await resolveInitialPane({\n windowMode,\n prompt: context.prompt,\n dryRun: context.dryRun,\n listWindows,\n runCommand,\n logCommand,\n initialCwd,\n workspaceHint,\n initialList: cachedInitialList,\n preferredPaneId: context.paneId,\n })\n registerPaneWithAncestors(paneMap, initialVirtualPaneId, initialPaneId)\n logPaneMapping(initialVirtualPaneId, initialPaneId)\n\n let executedSteps = 0\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n await applySplitStep({\n step,\n paneMap,\n windowId,\n runCommand,\n listWindows,\n logPaneMapping,\n })\n executedSteps += 1\n } else if (step.kind === \"focus\") {\n await applyFocusStep({\n step,\n paneMap,\n runCommand,\n })\n executedSteps += 1\n } else {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: `Unsupported step kind in emission: ${String((step as { kind?: unknown }).kind)}`,\n path: step.id,\n })\n }\n }\n\n await applyTerminalCommands({\n terminals: emission.terminals,\n paneMap,\n runCommand,\n focusPaneVirtualId: emission.summary.focusPaneId,\n })\n\n const focusVirtual = emission.summary.focusPaneId\n const focusPaneId = typeof focusVirtual === \"string\" ? paneMap.get(focusVirtual) : undefined\n\n return {\n executedSteps,\n focusPaneId,\n }\n }\n\n return {\n verifyEnvironment,\n applyPlan,\n getDryRunSteps: buildDryRunSteps,\n }\n}\n","import type {\n TerminalBackend,\n TerminalBackendContext,\n TerminalBackendKind,\n TmuxTerminalBackendContext,\n WeztermTerminalBackendContext,\n} from \"./terminal-backend\"\nimport { createTmuxBackend } from \"../backends/tmux/backend\"\nimport { createWeztermBackend } from \"../backends/wezterm/backend\"\n\nexport function createTerminalBackend(kind: \"tmux\", context: TmuxTerminalBackendContext): TerminalBackend\nexport function createTerminalBackend(kind: \"wezterm\", context: WeztermTerminalBackendContext): TerminalBackend\nexport function createTerminalBackend(kind: TerminalBackendKind, context: TerminalBackendContext): TerminalBackend {\n if (kind === \"tmux\") {\n if (!(\"executor\" in context)) {\n throw new Error(\"tmux backend requires executor context\")\n }\n return createTmuxBackend(context)\n }\n\n if (kind === \"wezterm\") {\n return createWeztermBackend(context)\n }\n\n throw new Error(`Unsupported backend \"${kind}\"`)\n}\n","import type { TerminalBackendKind } from \"./terminal-backend\"\n\ntype ResolveBackendOptions = {\n readonly cliFlag?: TerminalBackendKind\n readonly presetBackend?: TerminalBackendKind\n readonly env: NodeJS.ProcessEnv\n}\n\nconst KNOWN_BACKENDS: TerminalBackendKind[] = [\"tmux\", \"wezterm\"]\n\nexport const resolveTerminalBackendKind = ({\n cliFlag,\n presetBackend,\n env,\n}: ResolveBackendOptions): TerminalBackendKind => {\n const selectedBackend = cliFlag ?? presetBackend\n if (selectedBackend !== undefined) {\n if (!KNOWN_BACKENDS.includes(selectedBackend)) {\n throw new Error(`Unknown backend \"${selectedBackend}\"`)\n }\n return selectedBackend\n }\n\n if (typeof env.TMUX === \"string\" && env.TMUX.trim().length > 0) {\n return \"tmux\"\n }\n\n return \"tmux\"\n}\n","import chalk from \"chalk\"\n\nimport type { WindowMode } from \"../models/types\"\nimport type { DryRunStep } from \"../executor/terminal-backend\"\n\nexport const renderDryRun = (\n steps: ReadonlyArray<DryRunStep>,\n output: (message: string) => void = (message): void => console.log(message),\n): void => {\n output(chalk.bold(\"\\nPlanned terminal steps (dry-run)\"))\n steps.forEach((step, index) => {\n output(` ${index + 1}. [${step.backend}] ${step.summary}: ${step.command}`)\n })\n}\n\nexport const buildPresetSource = (presetName?: string): string => {\n return typeof presetName === \"string\" && presetName.length > 0 ? `preset://${presetName}` : \"preset://default\"\n}\n\nexport const determineCliWindowMode = (options: {\n currentWindow?: boolean\n newWindow?: boolean\n}): WindowMode | undefined => {\n if (options.currentWindow === true && options.newWindow === true) {\n throw new Error(\"Cannot use --current-window and --new-window at the same time\")\n }\n\n if (options.currentWindow === true) {\n return \"current-window\"\n }\n\n if (options.newWindow === true) {\n return \"new-window\"\n }\n\n return undefined\n}\n","import { createInterface } from \"node:readline/promises\"\nimport { stdin as input, stdout as output } from \"node:process\"\nimport type { ConfirmPaneClosure, ConfirmPaneClosureContext } from \"../contracts\"\nimport type { Logger } from \"../utils/logger\"\n\nexport const createPaneKillPrompter = (logger: Logger): ConfirmPaneClosure => {\n return async ({ panesToClose, dryRun }: ConfirmPaneClosureContext): Promise<boolean> => {\n if (panesToClose.length === 0) {\n return true\n }\n\n const paneList = panesToClose.join(\", \")\n\n if (dryRun) {\n logger.warn(`[DRY RUN] Would close panes: ${paneList}`)\n return true\n }\n\n logger.warn(`This operation will close the following panes: ${paneList}`)\n\n if (input.isTTY !== true || output.isTTY !== true) {\n logger.error(\"Cannot prompt for confirmation because the terminal is not interactive\")\n return false\n }\n\n const rl = createInterface({ input, output })\n try {\n const answer = await rl.question(\"Continue? [y/N]: \")\n const normalized = answer.trim().toLowerCase()\n return normalized === \"y\" || normalized === \"yes\"\n } finally {\n rl.close()\n }\n }\n}\n","import type { WindowMode } from \"../models/types\"\n\ntype WindowModeSource = {\n readonly cli?: WindowMode\n readonly preset?: WindowMode\n readonly defaults?: WindowMode\n}\n\ntype WindowModeResolutionSource = \"cli\" | \"preset\" | \"defaults\" | \"fallback\"\n\ntype WindowModeResolution = {\n readonly mode: WindowMode\n readonly source: WindowModeResolutionSource\n}\n\nexport const resolveWindowMode = ({ cli, preset, defaults }: WindowModeSource): WindowModeResolution => {\n if (cli !== undefined) {\n return { mode: cli, source: \"cli\" }\n }\n\n if (preset !== undefined) {\n return { mode: preset, source: \"preset\" }\n }\n\n if (defaults !== undefined) {\n return { mode: defaults, source: \"defaults\" }\n }\n\n return { mode: \"new-window\", source: \"fallback\" }\n}\n","import { createTerminalBackend } from \"../executor/backend-factory\"\nimport { resolveTerminalBackendKind } from \"../executor/backend-resolver\"\nimport type { TerminalBackendKind } from \"../executor/terminal-backend\"\nimport type { WindowMode } from \"../models/types\"\nimport type { CommandExecutor } from \"../contracts\"\nimport type { PresetManager } from \"../contracts\"\nimport type { Logger } from \"../utils/logger\"\nimport { buildPresetSource, determineCliWindowMode, renderDryRun } from \"./command-helpers\"\nimport type { CoreBridge } from \"./core-bridge\"\nimport { createPaneKillPrompter } from \"./user-prompt\"\nimport { resolveWindowMode } from \"./window-mode\"\n\ntype ExecutePresetCliOptions = {\n readonly verbose: boolean\n readonly dryRun: boolean\n readonly currentWindow: boolean\n readonly newWindow: boolean\n readonly backend?: string\n}\n\ntype ExecutePresetInput = {\n readonly presetName: string | undefined\n readonly options: ExecutePresetCliOptions\n readonly presetManager: PresetManager\n readonly createCommandExecutor: (options: { verbose: boolean; dryRun: boolean }) => CommandExecutor\n readonly core: CoreBridge\n readonly logger: Logger\n readonly handleError: (error: unknown) => number\n readonly handlePipelineFailure: (error: unknown) => number\n readonly output?: (line: string) => void\n readonly cwd?: string\n readonly env?: NodeJS.ProcessEnv\n}\n\nexport const executePreset = async ({\n presetName,\n options,\n presetManager,\n createCommandExecutor,\n core,\n logger,\n handleError,\n handlePipelineFailure,\n output = (line: string): void => console.log(line),\n cwd = process.cwd(),\n env = process.env,\n}: ExecutePresetInput): Promise<number> => {\n try {\n await presetManager.loadConfig()\n\n const preset =\n typeof presetName === \"string\" && presetName.length > 0\n ? presetManager.getPreset(presetName)\n : presetManager.getDefaultPreset()\n\n const windowModeResolution = resolveWindowModeForPreset({\n presetManager,\n options,\n presetWindowMode: preset.windowMode,\n })\n const windowMode = windowModeResolution.mode\n logger.info(`Window mode: ${windowMode} (source: ${windowModeResolution.source})`)\n const confirmPaneClosure = createPaneKillPrompter(logger)\n\n const executor = createCommandExecutor({\n verbose: options.verbose,\n dryRun: options.dryRun,\n })\n\n const backendKind = resolveTerminalBackendKind({\n cliFlag: options.backend as TerminalBackendKind | undefined,\n presetBackend: preset.backend,\n env,\n })\n logger.info(`Terminal backend: ${backendKind}`)\n const backendContextBase = {\n logger,\n dryRun: options.dryRun,\n verbose: options.verbose,\n prompt: confirmPaneClosure,\n cwd,\n paneId: env.WEZTERM_PANE,\n } as const\n\n const backend =\n backendKind === \"tmux\"\n ? createTerminalBackend(\"tmux\", {\n ...backendContextBase,\n executor,\n })\n : createTerminalBackend(\"wezterm\", backendContextBase)\n\n await backend.verifyEnvironment()\n\n if (options.dryRun === true) {\n output(\"[DRY RUN] No actual commands will be executed\")\n }\n\n let emission\n try {\n emission = buildPlanEmission({\n core,\n preset,\n presetName,\n })\n } catch (error) {\n return handlePipelineFailure(error)\n }\n\n if (options.dryRun === true) {\n const dryRunSteps = backend.getDryRunSteps(emission)\n renderDryRun(dryRunSteps, output)\n } else {\n try {\n const executionResult = await backend.applyPlan({\n emission,\n windowMode,\n windowName: resolveWindowName({\n presetName,\n presetDisplayName: preset.name,\n }),\n })\n logger.info(`Executed ${executionResult.executedSteps} ${backendKind} steps`)\n } catch (error) {\n return handlePipelineFailure(error)\n }\n }\n\n logger.success(`Applied preset \"${preset.name}\"`)\n return 0\n } catch (error) {\n return handleError(error)\n }\n}\n\nconst buildPlanEmission = ({\n core,\n preset,\n presetName,\n}: {\n readonly core: CoreBridge\n readonly preset: ReturnType<PresetManager[\"getDefaultPreset\"]>\n readonly presetName?: string\n}): ReturnType<CoreBridge[\"emitPlan\"]> => {\n const compileResult = core.compilePresetFromValue({\n value: preset,\n source: buildPresetSource(presetName),\n })\n const planResult = core.createLayoutPlan({ preset: compileResult.preset })\n return core.emitPlan({ plan: planResult.plan })\n}\n\nconst resolveWindowName = ({\n presetName,\n presetDisplayName,\n}: {\n readonly presetName: string | undefined\n readonly presetDisplayName?: string\n}): string => {\n return presetDisplayName ?? presetName ?? \"vde-layout\"\n}\n\nconst resolveWindowModeForPreset = ({\n presetManager,\n options,\n presetWindowMode,\n}: {\n readonly presetManager: PresetManager\n readonly options: ExecutePresetCliOptions\n readonly presetWindowMode: WindowMode | undefined\n}): ReturnType<typeof resolveWindowMode> => {\n const cliWindowMode = determineCliWindowMode({\n currentWindow: options.currentWindow,\n newWindow: options.newWindow,\n })\n const defaults = presetManager.getDefaults()\n return resolveWindowMode({\n cli: cliWindowMode,\n preset: presetWindowMode,\n defaults: defaults?.windowMode,\n })\n}\n","import { Command, CommanderError } from \"commander\"\nimport { createRequire } from \"module\"\nimport { createPresetManager } from \"../layout/preset\"\nimport { loadPackageVersion } from \"./package-version\"\nimport { createCliErrorHandlers } from \"./error-handling\"\nimport { applyRuntimeOptions, listPresets } from \"./runtime-and-list\"\nimport { executePreset } from \"./preset-execution\"\nimport type { CommandExecutor } from \"../contracts\"\nimport type { PresetManager } from \"../contracts\"\nimport { createRealExecutor, createDryRunExecutor } from \"../executor/index\"\nimport { createLogger, type Logger } from \"../utils/logger\"\nimport {\n compilePreset as defaultCompilePreset,\n compilePresetFromValue as defaultCompilePresetFromValue,\n createLayoutPlan as defaultCreateLayoutPlan,\n emitPlan as defaultEmitPlan,\n} from \"../core/index\"\nimport type { CoreBridge } from \"./core-bridge\"\nexport type { CoreBridge } from \"./core-bridge\"\n\ntype CLIOptions = {\n readonly presetManager?: PresetManager\n readonly createCommandExecutor?: (options: { verbose: boolean; dryRun: boolean }) => CommandExecutor\n readonly core?: CoreBridge\n}\n\nexport type CLI = {\n run(args?: string[]): Promise<number>\n}\n\nexport const createCli = (options: CLIOptions = {}): CLI => {\n const presetManager = options.presetManager ?? createPresetManager()\n const createCommandExecutor =\n options.createCommandExecutor ??\n ((opts: { verbose: boolean; dryRun: boolean }): CommandExecutor => {\n if (opts.dryRun) {\n return createDryRunExecutor({ verbose: opts.verbose })\n }\n return createRealExecutor({ verbose: opts.verbose })\n })\n\n const core: CoreBridge =\n options.core ??\n ({\n compilePreset: defaultCompilePreset,\n compilePresetFromValue: defaultCompilePresetFromValue,\n createLayoutPlan: defaultCreateLayoutPlan,\n emitPlan: defaultEmitPlan,\n } as const)\n\n const program = new Command()\n const require = createRequire(import.meta.url)\n const version = loadPackageVersion(require)\n let logger: Logger = createLogger()\n const errorHandlers = createCliErrorHandlers({\n getLogger: () => logger,\n })\n\n const setupProgram = (): void => {\n program.exitOverride()\n\n program\n .name(\"vde-layout\")\n .description(\"VDE (Vibrant Development Environment) Layout Manager - tmux pane layout management tool\")\n .version(version, \"-v, --version\", \"Show version\")\n .helpOption(\"-h, --help\", \"Show help\")\n\n program.option(\"--verbose\", \"Show detailed logs\", false)\n program.option(\"--dry-run\", \"Display commands without executing\", false)\n program.option(\"--backend <backend>\", \"Select terminal backend (tmux or wezterm)\")\n program.option(\"--config <path>\", \"Path to configuration file\")\n program.option(\"--current-window\", \"Use the current tmux window for layout (kills other panes)\", false)\n program.option(\"--new-window\", \"Always create a new tmux window for layout\", false)\n program.hook(\"preAction\", (_thisCommand, actionCommand) => {\n const runtimeOptions =\n typeof actionCommand.optsWithGlobals === \"function\"\n ? actionCommand.optsWithGlobals()\n : program.opts<{ verbose?: boolean; config?: string }>()\n logger = applyRuntimeOptions({\n runtimeOptions,\n createLogger,\n presetManager,\n })\n })\n\n program\n .command(\"list\")\n .description(\"List available presets\")\n .action(async () => {\n lastExitCode = await listPresets({\n presetManager,\n logger,\n onError: errorHandlers.handleError,\n })\n })\n\n program\n .argument(\"[preset]\", 'Preset name (defaults to \"default\" preset when omitted)')\n .action(async (presetName?: string) => {\n const opts = program.opts<{\n verbose?: boolean\n dryRun?: boolean\n currentWindow?: boolean\n newWindow?: boolean\n backend?: string\n }>()\n lastExitCode = await executePreset({\n presetName,\n options: {\n verbose: opts.verbose === true,\n dryRun: opts.dryRun === true,\n currentWindow: opts.currentWindow === true,\n newWindow: opts.newWindow === true,\n backend: opts.backend,\n },\n presetManager,\n createCommandExecutor,\n core,\n logger,\n handleError: errorHandlers.handleError,\n handlePipelineFailure: errorHandlers.handlePipelineFailure,\n })\n })\n }\n\n let lastExitCode = 0\n setupProgram()\n\n const run = async (args: string[] = process.argv.slice(2)): Promise<number> => {\n lastExitCode = 0\n logger = createLogger()\n\n try {\n await program.parseAsync(args, { from: \"user\" })\n } catch (error) {\n if (error instanceof CommanderError) {\n return error.exitCode\n }\n return errorHandlers.handleError(error)\n }\n\n return lastExitCode\n }\n\n return { run }\n}\n","#!/usr/bin/env node\nimport { createCli } from \"./cli/index\"\n\n/**\n * Main entry point\n * Launches the CLI application\n */\nconst main = async (): Promise<void> => {\n const cli = createCli()\n try {\n // Pass arguments excluding the first two elements (node, script path) from process.argv\n const exitCode = await cli.run(process.argv.slice(2))\n if (typeof exitCode === \"number\" && exitCode !== 0) {\n process.exit(exitCode)\n }\n } catch (error) {\n // Format and display error message appropriately\n if (error instanceof Error) {\n console.error(\"Error:\", error.message)\n\n // Also display stack trace in debug mode\n if (process.env.VDE_DEBUG === \"true\") {\n console.error(error.stack)\n }\n } else {\n console.error(\"An unexpected error occurred:\", String(error))\n }\n\n process.exit(1)\n }\n}\n\n// Execute immediately\nvoid main()\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["yaml","parseCommand","toCommandString","parseCommand","toCommandString","SINGLE_QUOTE","SHELL_SINGLE_QUOTE_ESCAPE","findNewPaneId","resolveSplitOrientationFromStep","resolveSplitPercentageFromStep","input","output","selectPreset","defaultSelectPreset","defaultCompilePreset","defaultCompilePresetFromValue","defaultCreateLayoutPlan","defaultEmitPlan"],"sources":["../src/utils/errors.ts","../src/models/schema.ts","../src/config/validator.ts","../src/config/loader.ts","../src/layout/preset.ts","../src/cli/package-version.ts","../src/core/errors.ts","../src/core/compile.ts","../src/core/planner.ts","../src/core/emitter.ts","../src/cli/error-handling.ts","../src/utils/logger.ts","../src/cli/runtime-and-list.ts","../src/executor/real-executor.ts","../src/executor/dry-run-executor.ts","../src/executor/mock-executor.ts","../src/backends/tmux/executor.ts","../src/utils/async.ts","../src/utils/pane-map.ts","../src/executor/split-step.ts","../src/utils/template-tokens.ts","../src/executor/terminal-command-preparation.ts","../src/executor/plan-runner-helpers.ts","../src/executor/plan-runner.ts","../src/executor/step-target.ts","../src/executor/unsupported-step-kind.ts","../src/backends/tmux/backend.ts","../src/backends/wezterm/list-parser.ts","../src/backends/wezterm/cli.ts","../src/backends/wezterm/dry-run.ts","../src/backends/wezterm/layout-resolution.ts","../src/backends/wezterm/pane-map.ts","../src/backends/wezterm/step-execution.ts","../src/backends/wezterm/backend.ts","../src/executor/backend-factory.ts","../src/executor/backend-resolver.ts","../src/cli/command-helpers.ts","../src/cli/user-prompt.ts","../src/cli/window-mode.ts","../src/cli/preset-execution.ts","../src/cli/select-args.ts","../src/cli/preset-selector.ts","../src/cli/index.ts","../src/index.ts"],"sourcesContent":["export type VDELayoutError = Error & {\n readonly code: string\n readonly details: Readonly<Record<string, unknown>>\n}\n\nexport const ErrorCodes = {\n CONFIG_NOT_FOUND: \"CONFIG_NOT_FOUND\",\n CONFIG_PARSE_ERROR: \"CONFIG_PARSE_ERROR\",\n CONFIG_PERMISSION_ERROR: \"CONFIG_PERMISSION_ERROR\",\n INVALID_PRESET: \"INVALID_PRESET\",\n PRESET_NOT_FOUND: \"PRESET_NOT_FOUND\",\n INVALID_LAYOUT: \"INVALID_LAYOUT\",\n INVALID_PANE: \"INVALID_PANE\",\n INVALID_PLAN: \"INVALID_PLAN\",\n MISSING_TARGET: \"MISSING_TARGET\",\n TMUX_NOT_RUNNING: \"TMUX_NOT_RUNNING\",\n TMUX_COMMAND_FAILED: \"TMUX_COMMAND_FAILED\",\n NOT_IN_TMUX_SESSION: \"NOT_IN_TMUX_SESSION\",\n TMUX_NOT_FOUND: \"TMUX_NOT_FOUND\",\n TMUX_NOT_INSTALLED: \"TMUX_NOT_INSTALLED\",\n UNSUPPORTED_TMUX_VERSION: \"UNSUPPORTED_TMUX_VERSION\",\n BACKEND_NOT_FOUND: \"BACKEND_NOT_FOUND\",\n TERMINAL_COMMAND_FAILED: \"TERMINAL_COMMAND_FAILED\",\n TEMPLATE_TOKEN_ERROR: \"TEMPLATE_TOKEN_ERROR\",\n WEZTERM_NOT_FOUND: \"WEZTERM_NOT_FOUND\",\n UNSUPPORTED_WEZTERM_VERSION: \"UNSUPPORTED_WEZTERM_VERSION\",\n USER_CANCELLED: \"USER_CANCELLED\",\n} as const\n\nconst createBaseError = (\n name: string,\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n const error = new Error(message) as VDELayoutError\n error.name = name\n ;(error as { code: string }).code = code\n ;(error as { details: Readonly<Record<string, unknown>> }).details = details\n return error\n}\n\nexport const createConfigError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"ConfigError\", message, code, details)\n}\n\nexport const createValidationError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"ValidationError\", message, code, details)\n}\n\nexport const createTmuxError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"TmuxError\", message, code, details)\n}\n\nexport const createEnvironmentError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"EnvironmentError\", message, code, details)\n}\n\nexport const isVDELayoutError = (error: unknown): error is VDELayoutError => {\n if (typeof error !== \"object\" || error === null) {\n return false\n }\n\n if (!(\"code\" in error)) {\n return false\n }\n\n const { code } = error as { code?: unknown }\n if (typeof code !== \"string\") {\n return false\n }\n\n if (!(\"details\" in error)) {\n return false\n }\n\n return true\n}\n\nconst formatters: Record<string, (error: VDELayoutError) => string> = {\n [ErrorCodes.CONFIG_NOT_FOUND]: (error) => {\n const searchPaths = error.details.searchPaths\n if (!Array.isArray(searchPaths)) {\n return \"\"\n }\n\n const lines = [\"\", \"Searched in the following locations:\"]\n searchPaths.forEach((location) => lines.push(` - ${location}`))\n lines.push(\"\", \"To create a configuration file, run:\")\n lines.push(\" mkdir -p ~/.config/vde\")\n lines.push(' echo \"presets: {}\" > ~/.config/vde/layout.yml')\n return lines.join(\"\\n\")\n },\n [ErrorCodes.NOT_IN_TMUX_SESSION]: () => {\n return \"\\nThis command must be run inside a tmux session.\\nStart tmux first with: tmux\\n\"\n },\n [ErrorCodes.TMUX_NOT_INSTALLED]: () => {\n return (\n \"\\ntmux is required but not installed.\\n\" +\n \"Install tmux using your package manager:\\n\" +\n \" - macOS: brew install tmux\\n\" +\n \" - Ubuntu/Debian: sudo apt-get install tmux\\n\" +\n \" - Fedora: sudo dnf install tmux\\n\"\n )\n },\n [ErrorCodes.UNSUPPORTED_TMUX_VERSION]: (error) => {\n const requiredVersion = error.details.requiredVersion\n if (typeof requiredVersion !== \"string\") {\n return \"\"\n }\n return `\\nRequired tmux version: ${requiredVersion} or higher\\n`\n },\n [ErrorCodes.BACKEND_NOT_FOUND]: (error) => {\n const backend = typeof error.details.backend === \"string\" ? error.details.backend : \"terminal backend\"\n const binary = typeof error.details.binary === \"string\" ? error.details.binary : backend\n const suggestion =\n backend === \"wezterm\"\n ? [\n \"\",\n `${backend} is required but not installed.`,\n \"Install wezterm using your package manager:\",\n \" - macOS: brew install --cask wezterm\",\n \" - Ubuntu/Debian: sudo apt-get install wezterm\",\n \" - Fedora: sudo dnf install wezterm\",\n ].join(\"\\n\")\n : \"\"\n return `\\nMissing binary: ${binary}${suggestion}`\n },\n [ErrorCodes.WEZTERM_NOT_FOUND]: () => {\n return (\n \"\\nwezterm command was not found.\\n\" +\n \"Install wezterm using your package manager:\\n\" +\n \" - macOS: brew install --cask wezterm\\n\" +\n \" - Ubuntu/Debian: sudo apt-get install wezterm\\n\" +\n \" - Fedora: sudo dnf install wezterm\\n\"\n )\n },\n [ErrorCodes.UNSUPPORTED_WEZTERM_VERSION]: (error) => {\n const requiredVersion = typeof error.details.requiredVersion === \"string\" ? error.details.requiredVersion : \"\"\n const detected = typeof error.details.detectedVersion === \"string\" ? error.details.detectedVersion : \"\"\n const lines = [\"\", \"Unsupported wezterm version detected.\"]\n if (detected) {\n lines.push(`Detected version: ${detected}`)\n }\n if (requiredVersion) {\n lines.push(`Required version: ${requiredVersion} or higher`)\n }\n return lines.join(\"\\n\")\n },\n}\n\nexport const formatError = (error: Error): string => {\n if (!isVDELayoutError(error)) {\n return `${error.name}: ${error.message}`\n }\n\n let message = `Error: ${error.message}`\n\n const formatter = formatters[error.code]\n if (formatter) {\n message += `\\n${formatter(error)}`\n }\n\n const commandDetail = error.details.command\n if (commandDetail !== undefined) {\n message += `\\nCommand: ${JSON.stringify(commandDetail)}`\n }\n\n const stderrDetail = error.details.stderr\n if (stderrDetail !== undefined) {\n message += `\\nstderr: ${String(stderrDetail)}`\n }\n\n const presetDetail = error.details.preset\n if (presetDetail !== undefined) {\n message += `\\npreset: ${String(presetDetail)}`\n }\n\n const nestedErrors = error.details.errors\n if (Array.isArray(nestedErrors) && nestedErrors.length > 0) {\n message += \"\\nValidation errors:\\n\"\n nestedErrors.forEach((item) => {\n message += ` - ${String(item)}\\n`\n })\n }\n\n return message\n}\n","import { z } from \"zod\"\n\nexport const WindowModeSchema = z.enum([\"new-window\", \"current-window\"])\nconst TerminalBackendSchema = z.enum([\"tmux\", \"wezterm\"])\nexport const SELECT_UI_MODES = [\"auto\", \"fzf\"] as const\nexport const SELECT_SURFACE_MODES = [\"auto\", \"inline\", \"tmux-popup\"] as const\nexport const SelectUiModeSchema = z.enum(SELECT_UI_MODES)\nexport const SelectSurfaceModeSchema = z.enum(SELECT_SURFACE_MODES)\n\nconst SelectorFzfSchema = z\n .object({\n extraArgs: z.array(z.string().min(1)).optional(),\n })\n .strict()\n\nconst SelectorDefaultsSchema = z\n .object({\n ui: SelectUiModeSchema.optional(),\n surface: SelectSurfaceModeSchema.optional(),\n tmuxPopupOpts: z.string().min(1).optional(),\n fzf: SelectorFzfSchema.optional(),\n })\n .strict()\n\n// Terminal pane schema\nconst TerminalPaneSchema = z\n .object({\n name: z.string().min(1),\n command: z.string().optional(),\n cwd: z.string().optional(),\n env: z.record(z.string()).optional(),\n delay: z.number().int().positive().optional(),\n title: z.string().optional(),\n focus: z.boolean().optional(),\n ephemeral: z.boolean().optional(),\n closeOnError: z.boolean().optional(),\n })\n .strict()\n\n// Split container schema (recursive)\nconst SplitPaneSchema: z.ZodType<unknown> = z.lazy(() =>\n z\n .object({\n type: z.enum([\"horizontal\", \"vertical\"]),\n ratio: z.array(z.number().positive()).min(1),\n panes: z.array(PaneSchema).min(1),\n })\n .strict()\n .refine((data) => data.ratio.length === data.panes.length, {\n message: \"Number of elements in ratio array does not match number of elements in panes array\",\n }),\n)\n\n// Recursive Pane schema definition\nexport const PaneSchema: z.ZodType<unknown> = z.lazy(() => z.union([SplitPaneSchema, TerminalPaneSchema]))\n\n// Layout schema definition\nexport const LayoutSchema = z\n .object({\n type: z.enum([\"horizontal\", \"vertical\"]),\n ratio: z.array(z.number().positive()).min(1),\n panes: z.array(PaneSchema).min(1),\n })\n .refine((data) => data.ratio.length === data.panes.length, {\n message: \"Number of elements in ratio array does not match number of elements in panes array\",\n })\n\n// Preset schema definition\nexport const PresetSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n layout: LayoutSchema.optional(),\n command: z.string().optional(),\n windowMode: WindowModeSchema.optional(),\n backend: TerminalBackendSchema.optional(),\n})\n\n// Config schema definition\nexport const ConfigSchema = z.object({\n defaults: z\n .object({\n windowMode: WindowModeSchema.optional(),\n selector: SelectorDefaultsSchema.optional(),\n })\n .optional(),\n presets: z.record(PresetSchema),\n})\n\n// Validation result type\ntype ValidationResult<T> = {\n success: boolean\n data?: T\n error?: string\n}\n\n// Helper function to format Zod errors consistently\nconst formatValidationError = (error: z.ZodError): string => {\n const messages = error.errors.map((e) => {\n const path = e.path.join(\".\")\n const message = e.message\n\n // Customize error message for panes array element count check\n if (path === \"layout.panes\" && message.includes(\"at least 2 element\")) {\n return `${path}: panes array must have at least 2 elements`\n }\n\n return `${path}: ${message}`\n })\n\n return messages.join(\"\\n\")\n}\n\n// Config validation\nexport const validateConfig = (data: unknown): ValidationResult<z.infer<typeof ConfigSchema>> => {\n try {\n const parsed = ConfigSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n\n// Preset validation\nexport const validatePreset = (data: unknown): ValidationResult<z.infer<typeof PresetSchema>> => {\n try {\n const parsed = PresetSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n\n// Pane validation\nexport const validatePane = (data: unknown): ValidationResult<z.infer<typeof PaneSchema>> => {\n try {\n const parsed = PaneSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n","import * as YAML from \"yaml\"\nimport { z } from \"zod\"\nimport { ConfigSchema } from \"../models/schema\"\nimport type { Config } from \"../models/types\"\nimport { createValidationError, ErrorCodes, isVDELayoutError } from \"../utils/errors\"\n\n/**\n * Parse YAML text into an object\n * @param yamlText - YAML text to parse\n * @returns Parsed object\n * @throws {ValidationError} When YAML parsing fails\n */\nconst parseYAML = (yamlText: string): unknown => {\n // Input validation\n if (!yamlText || typeof yamlText !== \"string\") {\n throw createValidationError(\"YAML text not provided\", ErrorCodes.CONFIG_PARSE_ERROR, {\n received: typeof yamlText,\n })\n }\n\n try {\n return YAML.parse(yamlText)\n } catch (error) {\n throw createValidationError(\"Failed to parse YAML\", ErrorCodes.CONFIG_PARSE_ERROR, {\n parseError: error instanceof Error ? error.message : String(error),\n yamlSnippet: yamlText.substring(0, 200),\n })\n }\n}\n\n/**\n * Validate basic configuration structure\n * @param parsed - Parsed YAML object\n * @throws {ValidationError} When structure is invalid\n */\nconst validateConfigStructure = (parsed: unknown): void => {\n // Check for empty YAML\n if (parsed === null || parsed === undefined || typeof parsed !== \"object\") {\n throw createValidationError(\"YAML is empty or invalid format\", ErrorCodes.CONFIG_PARSE_ERROR, {\n parsed: parsed,\n })\n }\n\n // Check for presets field existence\n const parsedObj = parsed as Record<string, unknown>\n if (!(\"presets\" in parsedObj) || parsedObj.presets === undefined || parsedObj.presets === null) {\n throw createValidationError(\"presets field is required\", ErrorCodes.INVALID_PRESET, {\n availableFields: Object.keys(parsedObj),\n })\n }\n\n // Check for empty presets\n const presetsObj = parsedObj.presets\n if (typeof presetsObj !== \"object\" || presetsObj === null || Object.keys(presetsObj).length === 0) {\n throw createValidationError(\"At least one preset is required\", ErrorCodes.INVALID_PRESET, {\n presets: presetsObj,\n })\n }\n}\n\n/**\n * Format Zod validation errors into user-friendly messages\n * @param error - Zod validation error\n * @returns Formatted error issues\n */\nconst formatZodErrors = (error: z.ZodError): Array<{ path: string; message: string; code: string }> => {\n return error.issues.map((issue) => {\n const path = issue.path.join(\".\")\n let message = issue.message\n\n // Custom error messages\n if (issue.code === \"invalid_type\") {\n if (issue.path.includes(\"command\") && issue.expected === \"string\") {\n message = \"command field must be a string\"\n } else if (issue.path.includes(\"workingDirectory\") && issue.expected === \"string\") {\n message = \"workingDirectory field must be a string\"\n } else if (issue.received === \"number\" && issue.expected === \"string\") {\n message = `${path} must be a string`\n } else if (issue.received === \"array\" && issue.expected === \"string\") {\n message = `${path} must be a string`\n }\n } else if (issue.code === \"invalid_union\") {\n // Detailed error messages for union types\n const unionIssue = issue as z.ZodIssue & { unionErrors?: z.ZodError[] }\n if (unionIssue.unionErrors !== undefined) {\n // When command is missing in terminal pane\n const terminalError = unionIssue.unionErrors.find(\n (e) => e.issues?.some((i) => i.path.includes(\"command\") && i.code === \"invalid_type\") === true,\n )\n if (terminalError !== undefined) {\n message = \"command field is required\"\n } else {\n // When panes is missing in split pane\n const splitError = unionIssue.unionErrors.find(\n (e) => e.issues?.some((i) => i.path.includes(\"panes\") && i.code === \"invalid_type\") === true,\n )\n if (splitError !== undefined) {\n message = \"panes field is required\"\n } else {\n message = 'Pane type must be \"terminal\" or \"split\"'\n }\n }\n } else {\n message = 'Pane type must be \"terminal\" or \"split\"'\n }\n } else if (issue.code === \"invalid_literal\") {\n if (issue.path.includes(\"direction\")) {\n message = 'direction must be \"horizontal\" or \"vertical\"'\n }\n } else if (issue.message.includes(\"required\")) {\n // Use the message as is\n message = issue.message\n } else if (issue.code === \"custom\" && issue.message.includes(\"ratio array\")) {\n message = issue.message\n } else if (issue.code === \"too_small\" && issue.message.includes(\"Array must contain at least\")) {\n // Minimum array elements error\n if (path.includes(\"panes\")) {\n message = \"panes array must contain at least 2 elements\"\n } else if (path.includes(\"ratio\")) {\n message = \"ratio array must contain at least 2 elements\"\n } else {\n message = issue.message\n }\n }\n\n return {\n path,\n message,\n code: issue.code,\n }\n })\n}\n\n/**\n * Validates YAML text and converts it to a type-safe Config object\n * @param yamlText - YAML text to validate\n * @returns Validated Config object\n * @throws {ValidationError} When YAML is invalid\n */\nexport const validateYAML = (yamlText: string): Config => {\n // Parse YAML\n const parsed = parseYAML(yamlText)\n\n // Validate basic structure\n validateConfigStructure(parsed)\n\n // Ratio sum validation removed - unnecessary due to automatic normalization\n\n // Validation with Zod schema\n try {\n const validated = ConfigSchema.parse(parsed)\n return validated\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = formatZodErrors(error)\n\n // Use the first error message as the primary message\n const primaryMessage = issues.length > 0 && issues[0] ? issues[0].message : \"Configuration validation failed\"\n\n throw createValidationError(primaryMessage, ErrorCodes.CONFIG_PARSE_ERROR, {\n issues,\n rawErrors: error.issues,\n })\n }\n\n if (isVDELayoutError(error) && error.name === \"ValidationError\") {\n throw error\n }\n\n // Other errors\n throw createValidationError(\"Unexpected validation error occurred\", ErrorCodes.CONFIG_PARSE_ERROR, {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n","import fs from \"fs-extra\"\nimport path from \"path\"\nimport os from \"os\"\nimport * as yaml from \"yaml\"\nimport type { Config } from \"../models/types\"\nimport { createConfigError, ErrorCodes } from \"../utils/errors\"\nimport { validateYAML } from \"./validator\"\n\nexport type ConfigLoaderOptions = {\n readonly configPaths?: string[]\n readonly onWarning?: (message: string) => void\n}\n\nexport type ConfigLoader = {\n readonly loadYAML: () => Promise<string>\n readonly loadConfig: () => Promise<Config>\n readonly findConfigFile: () => Promise<string | null>\n readonly getSearchPaths: () => string[]\n}\n\ntype SearchPathGroup = readonly string[]\ntype SelectorDefaults = NonNullable<NonNullable<Config[\"defaults\"]>[\"selector\"]>\n\nexport const createConfigLoader = (options: ConfigLoaderOptions = {}): ConfigLoader => {\n const explicitConfigPaths = options.configPaths\n const emitWarning: (message: string) => void = options.onWarning ?? ((message: string): void => console.warn(message))\n\n const computeCachedSearchPaths = (): string[] => {\n if (explicitConfigPaths && explicitConfigPaths.length > 0) {\n return [...explicitConfigPaths]\n }\n\n const candidates: string[] = []\n const projectCandidate = findProjectConfigCandidate()\n if (projectCandidate !== null) {\n candidates.push(projectCandidate)\n }\n\n const defaultSearchPathGroups = buildDefaultSearchPathGroups()\n candidates.push(...flattenSearchPathGroups(defaultSearchPathGroups))\n\n return [...new Set(candidates)]\n }\n\n const loadConfig = async (): Promise<Config> => {\n if (explicitConfigPaths && explicitConfigPaths.length > 0) {\n const filePath = await findFirstExisting(explicitConfigPaths)\n if (filePath === null) {\n throw createConfigError(\"Configuration file not found\", ErrorCodes.CONFIG_NOT_FOUND, {\n searchPaths: explicitConfigPaths,\n })\n }\n\n const content = await safeReadFile(filePath)\n return validateYAML(content)\n }\n\n const searchPaths = computeCachedSearchPaths()\n const defaultSearchPathGroups = buildDefaultSearchPathGroups()\n const globalPaths = await resolveFirstExistingPaths(defaultSearchPathGroups)\n const projectPath = findProjectConfigCandidate()\n const projectConfigExists = projectPath !== null ? await fs.pathExists(projectPath) : false\n\n if (globalPaths.length === 0 && !projectConfigExists) {\n throw createConfigError(\"Configuration file not found\", ErrorCodes.CONFIG_NOT_FOUND, {\n searchPaths,\n })\n }\n\n let mergedConfig: Config = { presets: {} }\n\n for (const globalPath of globalPaths) {\n const content = await safeReadFile(globalPath)\n const config = validateYAML(content)\n mergedConfig = mergeConfigs(mergedConfig, config, emitWarning)\n }\n\n if (projectPath !== null && projectConfigExists) {\n const content = await safeReadFile(projectPath)\n const config = validateYAML(content)\n mergedConfig = mergeConfigs(mergedConfig, config, emitWarning)\n }\n\n return mergedConfig\n }\n\n return {\n loadYAML: async (): Promise<string> => {\n const config = await loadConfig()\n return yaml.stringify(config)\n },\n loadConfig,\n findConfigFile: async (): Promise<string | null> => {\n const searchPaths =\n explicitConfigPaths && explicitConfigPaths.length > 0 ? [...explicitConfigPaths] : computeCachedSearchPaths()\n\n for (const searchPath of searchPaths) {\n if (await fs.pathExists(searchPath)) {\n return searchPath\n }\n }\n return null\n },\n getSearchPaths: (): string[] => computeCachedSearchPaths(),\n }\n}\n\nconst buildDefaultSearchPathGroups = (): ReadonlyArray<SearchPathGroup> => {\n const pathGroups: string[][] = []\n\n const vdeConfigPath = process.env.VDE_CONFIG_PATH\n if (vdeConfigPath !== undefined) {\n pathGroups.push([path.join(vdeConfigPath, \"layout.yml\")])\n }\n\n const homeDir = process.env.HOME ?? os.homedir()\n const xdgConfigHome = process.env.XDG_CONFIG_HOME ?? path.join(homeDir, \".config\")\n pathGroups.push([\n path.join(xdgConfigHome, \"vde\", \"layout\", \"config.yml\"),\n path.join(xdgConfigHome, \"vde\", \"layout.yml\"),\n ])\n\n return pathGroups.map((group): SearchPathGroup => [...new Set(group)])\n}\n\nconst flattenSearchPathGroups = (pathGroups: ReadonlyArray<SearchPathGroup>): string[] => {\n const paths: string[] = []\n for (const group of pathGroups) {\n paths.push(...group)\n }\n return [...new Set(paths)]\n}\n\nconst resolveFirstExistingPaths = async (pathGroups: ReadonlyArray<SearchPathGroup>): Promise<string[]> => {\n const existingPaths = await Promise.all(pathGroups.map(async (group) => findFirstExisting(group)))\n const seenPaths = new Set<string>()\n const resolvedPaths: string[] = []\n\n for (const existingPath of existingPaths) {\n if (existingPath !== null && !seenPaths.has(existingPath)) {\n seenPaths.add(existingPath)\n resolvedPaths.push(existingPath)\n }\n }\n\n return resolvedPaths\n}\n\nconst findProjectConfigCandidate = (): string | null => {\n let currentDir = process.cwd()\n const { root } = path.parse(currentDir)\n\n while (true) {\n const candidates = [\n path.join(currentDir, \".vde\", \"layout\", \"config.yml\"),\n path.join(currentDir, \".vde\", \"layout.yml\"),\n ]\n\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n return candidate\n }\n }\n\n if (currentDir === root) {\n break\n }\n\n const parent = path.dirname(currentDir)\n if (parent === currentDir) {\n break\n }\n\n currentDir = parent\n }\n\n return null\n}\n\nconst findFirstExisting = async (paths: ReadonlyArray<string>): Promise<string | null> => {\n for (const candidate of paths) {\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return null\n}\n\nconst safeReadFile = async (filePath: string): Promise<string> => {\n try {\n return await fs.readFile(filePath, \"utf8\")\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw createConfigError(`Failed to read configuration file`, ErrorCodes.CONFIG_PERMISSION_ERROR, {\n filePath,\n error: errorMessage,\n })\n }\n}\n\nconst mergeConfigs = (base: Config, override: Config, emitWarning: (message: string) => void): Config => {\n const mergedPresets: Config[\"presets\"] = { ...base.presets }\n\n for (const [presetKey, overridePreset] of Object.entries(override.presets)) {\n const basePreset = base.presets[presetKey]\n if (\n basePreset !== undefined &&\n basePreset.windowMode !== undefined &&\n overridePreset.windowMode !== undefined &&\n basePreset.windowMode !== overridePreset.windowMode\n ) {\n emitWarning(\n `[vde-layout] Preset \"${presetKey}\" windowMode conflict: \"${basePreset.windowMode}\" overridden by \"${overridePreset.windowMode}\"`,\n )\n }\n mergedPresets[presetKey] = overridePreset\n }\n\n const baseDefaults = base.defaults\n const overrideDefaults = override.defaults\n\n if (\n baseDefaults?.windowMode !== undefined &&\n overrideDefaults?.windowMode !== undefined &&\n baseDefaults.windowMode !== overrideDefaults.windowMode\n ) {\n emitWarning(\n `[vde-layout] defaults.windowMode conflict: \"${baseDefaults.windowMode}\" overridden by \"${overrideDefaults.windowMode}\"`,\n )\n }\n\n const mergedSelectorDefaults = mergeSelectorDefaults({\n baseSelector: baseDefaults?.selector,\n overrideSelector: overrideDefaults?.selector,\n emitWarning,\n })\n\n const mergedDefaults =\n baseDefaults !== undefined || overrideDefaults !== undefined\n ? {\n ...(baseDefaults ?? {}),\n ...(overrideDefaults ?? {}),\n ...(mergedSelectorDefaults !== undefined ? { selector: mergedSelectorDefaults } : {}),\n }\n : undefined\n\n return mergedDefaults === undefined\n ? {\n presets: mergedPresets,\n }\n : {\n defaults: mergedDefaults,\n presets: mergedPresets,\n }\n}\n\nconst mergeSelectorDefaults = ({\n baseSelector,\n overrideSelector,\n emitWarning,\n}: {\n readonly baseSelector: SelectorDefaults | undefined\n readonly overrideSelector: SelectorDefaults | undefined\n readonly emitWarning: (message: string) => void\n}): SelectorDefaults | undefined => {\n if (baseSelector === undefined && overrideSelector === undefined) {\n return undefined\n }\n\n if (baseSelector?.ui !== undefined && overrideSelector?.ui !== undefined && baseSelector.ui !== overrideSelector.ui) {\n emitWarning(\n `[vde-layout] defaults.selector.ui conflict: \"${baseSelector.ui}\" overridden by \"${overrideSelector.ui}\"`,\n )\n }\n\n if (\n baseSelector?.surface !== undefined &&\n overrideSelector?.surface !== undefined &&\n baseSelector.surface !== overrideSelector.surface\n ) {\n emitWarning(\n `[vde-layout] defaults.selector.surface conflict: \"${baseSelector.surface}\" overridden by \"${overrideSelector.surface}\"`,\n )\n }\n\n if (\n baseSelector?.tmuxPopupOpts !== undefined &&\n overrideSelector?.tmuxPopupOpts !== undefined &&\n baseSelector.tmuxPopupOpts !== overrideSelector.tmuxPopupOpts\n ) {\n emitWarning(\n `[vde-layout] defaults.selector.tmuxPopupOpts conflict: \"${baseSelector.tmuxPopupOpts}\" overridden by \"${overrideSelector.tmuxPopupOpts}\"`,\n )\n }\n\n const baseExtraArgs = baseSelector?.fzf?.extraArgs\n const overrideExtraArgs = overrideSelector?.fzf?.extraArgs\n if (\n Array.isArray(baseExtraArgs) &&\n Array.isArray(overrideExtraArgs) &&\n JSON.stringify(baseExtraArgs) !== JSON.stringify(overrideExtraArgs)\n ) {\n emitWarning(`[vde-layout] defaults.selector.fzf.extraArgs conflict: global value overridden by project value`)\n }\n\n const mergedFzf =\n baseSelector?.fzf !== undefined || overrideSelector?.fzf !== undefined\n ? {\n ...(baseSelector?.fzf ?? {}),\n ...(overrideSelector?.fzf ?? {}),\n }\n : undefined\n\n return {\n ...(baseSelector ?? {}),\n ...(overrideSelector ?? {}),\n ...(mergedFzf !== undefined ? { fzf: mergedFzf } : {}),\n }\n}\n","import { createConfigLoader, type ConfigLoaderOptions } from \"../config/loader\"\nimport { createConfigError, ErrorCodes } from \"../utils/errors\"\nimport type { Config, Preset, PresetInfo } from \"../models/types\"\nimport type { PresetManager } from \"../contracts\"\n\ntype PresetState = {\n setConfigPath: (filePath: string) => void\n loadConfig: () => Promise<void>\n getPreset: (name: string) => Preset\n listPresets: () => PresetInfo[]\n getDefaultPreset: () => Preset\n getDefaults: () => Config[\"defaults\"] | undefined\n}\n\nconst createState = (options: ConfigLoaderOptions = {}): PresetState => {\n let loaderOptions: ConfigLoaderOptions = options\n let cachedConfig: Config | null = null\n\n const setConfigPath = (filePath: string): void => {\n loaderOptions = { configPaths: [filePath] }\n cachedConfig = null\n }\n\n const loadConfig = async (): Promise<void> => {\n const loader = createConfigLoader(loaderOptions)\n cachedConfig = await loader.loadConfig()\n }\n\n const ensureConfig = (): Config => {\n if (cachedConfig === null) {\n throw createConfigError(\"Configuration not loaded\", ErrorCodes.CONFIG_NOT_FOUND)\n }\n return cachedConfig\n }\n\n const getPreset = (name: string): Preset => {\n const config = ensureConfig()\n const preset = config.presets[name]\n if (preset === undefined) {\n throw createConfigError(`Preset \"${name}\" not found`, ErrorCodes.PRESET_NOT_FOUND, {\n availablePresets: Object.keys(config.presets),\n })\n }\n return preset\n }\n\n const listPresets = (): PresetInfo[] => {\n if (cachedConfig === null) {\n return []\n }\n\n return Object.entries(cachedConfig.presets).map(([key, preset]) => ({\n key,\n name: preset.name,\n description: preset.description,\n }))\n }\n\n const getDefaultPreset = (): Preset => {\n const config = ensureConfig()\n\n if (config.presets.default !== undefined) {\n return config.presets.default\n }\n\n const firstKey = Object.keys(config.presets)[0]\n if (typeof firstKey !== \"string\" || firstKey.length === 0) {\n throw createConfigError(\"No presets defined\", ErrorCodes.PRESET_NOT_FOUND)\n }\n\n return config.presets[firstKey]!\n }\n\n const getDefaults = (): Config[\"defaults\"] | undefined => {\n const config = ensureConfig()\n return config.defaults\n }\n\n return {\n setConfigPath,\n loadConfig,\n getPreset,\n listPresets,\n getDefaultPreset,\n getDefaults,\n }\n}\n\nexport const createPresetManager = (options: ConfigLoaderOptions = {}): PresetManager => {\n const state = createState(options)\n return {\n setConfigPath: state.setConfigPath,\n loadConfig: state.loadConfig,\n getPreset: state.getPreset,\n listPresets: state.listPresets,\n getDefaultPreset: state.getDefaultPreset,\n getDefaults: state.getDefaults,\n }\n}\n","type PackageJsonModule = {\n readonly version: string\n}\n\ntype ModuleLoadError = Error & {\n readonly code?: string\n}\n\nconst CANDIDATE_PATHS = [\"../package.json\", \"../../package.json\"] as const\n\nconst isModuleNotFoundError = (error: unknown): error is ModuleLoadError => {\n return error instanceof Error && (error as ModuleLoadError).code === \"MODULE_NOT_FOUND\"\n}\n\nexport const loadPackageVersion = (requireFn: NodeJS.Require): string => {\n let lastNotFound: ModuleLoadError | undefined\n\n for (const path of CANDIDATE_PATHS) {\n try {\n return (requireFn(path) as PackageJsonModule).version\n } catch (error) {\n if (isModuleNotFoundError(error)) {\n lastNotFound = error\n continue\n }\n\n throw error\n }\n }\n\n throw lastNotFound ?? new Error(`Unable to resolve package version from candidates: ${CANDIDATE_PATHS.join(\", \")}`)\n}\n","type CoreErrorKind = \"compile\" | \"plan\" | \"emit\" | \"execution\"\n\nexport type CoreError = {\n readonly kind: CoreErrorKind\n readonly code: string\n readonly message: string\n readonly source?: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n}\n\nexport const createCoreError = (\n kind: CoreErrorKind,\n error: {\n readonly code: string\n readonly message: string\n readonly source?: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n },\n): CoreError => ({\n kind,\n code: error.code,\n message: error.message,\n source: error.source,\n path: error.path,\n details: error.details,\n})\n\nexport const isCoreError = (value: unknown): value is CoreError => {\n if (typeof value !== \"object\" || value === null) {\n return false\n }\n const candidate = value as Partial<CoreError>\n return (\n (candidate.kind === \"compile\" ||\n candidate.kind === \"plan\" ||\n candidate.kind === \"emit\" ||\n candidate.kind === \"execution\") &&\n typeof candidate.code === \"string\" &&\n typeof candidate.message === \"string\"\n )\n}\n","import { parse } from \"yaml\"\nimport { z } from \"zod\"\nimport { LayoutSchema } from \"../models/schema\"\nimport { createCoreError, type CoreError } from \"./errors\"\n\nexport type CompilePresetInput = {\n readonly document: string\n readonly source: string\n}\n\nexport type CompilePresetFromValueInput = {\n readonly value: unknown\n readonly source: string\n}\n\nexport type CompiledTerminalPane = {\n readonly kind: \"terminal\"\n readonly name: string\n readonly command?: string\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly delay?: number\n readonly title?: string\n readonly focus?: boolean\n readonly ephemeral?: boolean\n readonly closeOnError?: boolean\n readonly options?: Readonly<Record<string, unknown>>\n}\n\nexport type CompiledSplitPane = {\n readonly kind: \"split\"\n readonly orientation: \"horizontal\" | \"vertical\"\n readonly ratio: ReadonlyArray<number>\n readonly panes: ReadonlyArray<CompiledLayoutNode>\n}\n\nexport type CompiledLayoutNode = CompiledTerminalPane | CompiledSplitPane\n\ntype CompiledPresetMetadata = {\n readonly source: string\n}\n\nexport type CompiledPreset = {\n readonly name: string\n readonly version: string\n readonly command?: string\n readonly layout?: CompiledLayoutNode\n readonly metadata: CompiledPresetMetadata\n}\n\nexport type CompilePresetSuccess = {\n readonly preset: CompiledPreset\n}\n\nexport const compilePreset = ({ document, source }: CompilePresetInput): CompilePresetSuccess => {\n let parsed: unknown\n try {\n parsed = parse(document)\n } catch (error) {\n throw compileError(\"PRESET_PARSE_ERROR\", {\n source,\n message: `Failed to parse YAML: ${(error as Error).message}`,\n details: {\n reason: error instanceof Error ? error.message : String(error),\n },\n })\n }\n\n return compilePresetValue({ value: parsed, source })\n}\n\nexport const compilePresetFromValue = ({ value, source }: CompilePresetFromValueInput): CompilePresetSuccess => {\n return compilePresetValue({ value, source })\n}\n\nconst compilePresetValue = ({ value, source }: CompilePresetFromValueInput): CompilePresetSuccess => {\n const parsed = value\n\n if (!isRecord(parsed)) {\n throw compileError(\"PRESET_INVALID_DOCUMENT\", {\n source,\n message: \"Preset definition is not an object\",\n path: \"preset\",\n })\n }\n\n const name = typeof parsed.name === \"string\" && parsed.name.trim().length > 0 ? parsed.name : \"Unnamed preset\"\n const validatedLayout = validateLayoutDefinition(parsed.layout, {\n source,\n path: \"preset.layout\",\n })\n\n const layout = parseLayoutNode(validatedLayout, {\n source,\n path: \"preset.layout\",\n })\n\n return {\n preset: {\n name,\n version: \"legacy\",\n command: typeof parsed.command === \"string\" ? parsed.command : undefined,\n layout: layout ?? undefined,\n metadata: { source },\n },\n }\n}\n\nconst validateLayoutDefinition = (\n layout: unknown,\n context: { readonly source: string; readonly path: string },\n): unknown => {\n if (layout === undefined || layout === null) {\n return layout\n }\n\n if (!isRecord(layout) || !looksSplitLikeNode(layout)) {\n return layout\n }\n\n const normalizedLayout = sanitizeLayoutForSchemaValidation(layout)\n const validated = LayoutSchema.safeParse(normalizedLayout)\n if (validated.success) {\n return layout\n }\n\n const issue = validated.error.issues[0]\n if (!issue) {\n throw compileError(\"LAYOUT_INVALID_NODE\", {\n source: context.source,\n message: \"Layout node is invalid\",\n path: context.path,\n details: { layout },\n })\n }\n\n throw convertLayoutIssueToCompileError({\n issue,\n source: context.source,\n basePath: context.path,\n layout,\n })\n}\n\nconst parseLayoutNode = (\n node: unknown,\n context: { readonly source: string; readonly path: string },\n): CompiledLayoutNode | null => {\n if (node === undefined || node === null) {\n return null\n }\n\n if (!isRecord(node)) {\n throw compileError(\"LAYOUT_INVALID_NODE\", {\n source: context.source,\n message: \"Layout node is invalid\",\n path: context.path,\n details: { node },\n })\n }\n\n if (\"type\" in node || \"ratio\" in node || \"panes\" in node) {\n return parseSplitPane(node, context)\n }\n\n if (typeof node.name === \"string\") {\n return parseTerminalPane(node)\n }\n\n throw compileError(\"LAYOUT_INVALID_NODE\", {\n source: context.source,\n message: \"Layout node is invalid\",\n path: context.path,\n details: { node },\n })\n}\n\nconst parseSplitPane = (\n node: Record<string, unknown>,\n context: { readonly source: string; readonly path: string },\n): CompiledSplitPane => {\n const orientation = node.type\n const panesInput = node.panes\n const ratioInput = node.ratio\n if (\n (orientation !== \"horizontal\" && orientation !== \"vertical\") ||\n !Array.isArray(panesInput) ||\n !Array.isArray(ratioInput)\n ) {\n throw compileError(\"LAYOUT_INVALID_NODE\", {\n source: context.source,\n message: \"Layout node is invalid\",\n path: context.path,\n details: { node },\n })\n }\n\n const panes = panesInput.map((child, index) =>\n parseLayoutNode(child, {\n source: context.source,\n path: `${context.path}.panes[${index}]`,\n }),\n )\n const ratio = ratioInput.map((value): number => Number(value))\n\n return {\n kind: \"split\",\n orientation,\n ratio,\n panes: panes.filter((pane): pane is CompiledLayoutNode => pane !== null),\n }\n}\n\nconst parseTerminalPane = (node: Record<string, unknown>): CompiledTerminalPane => {\n const name = typeof node.name === \"string\" ? node.name : \"\"\n const command = typeof node.command === \"string\" ? node.command : undefined\n const cwd = typeof node.cwd === \"string\" ? node.cwd : undefined\n const delay = typeof node.delay === \"number\" && Number.isFinite(node.delay) && node.delay > 0 ? node.delay : undefined\n const title = typeof node.title === \"string\" && node.title.length > 0 ? node.title : undefined\n const focus = node.focus === true ? true : undefined\n const ephemeral = node.ephemeral === true ? true : undefined\n const closeOnError = node.closeOnError === true ? true : undefined\n const env = normalizeEnv(node.env)\n\n const knownKeys = new Set([\n \"name\",\n \"command\",\n \"cwd\",\n \"env\",\n \"focus\",\n \"ephemeral\",\n \"closeOnError\",\n \"options\",\n \"title\",\n \"delay\",\n ])\n const options = collectOptions(node, knownKeys)\n\n return {\n kind: \"terminal\",\n name,\n command,\n cwd,\n env,\n delay,\n title,\n focus,\n ephemeral,\n closeOnError,\n options,\n }\n}\n\nconst normalizeEnv = (env: unknown): Readonly<Record<string, string>> | undefined => {\n if (!isRecord(env)) {\n return undefined\n }\n\n const entries = Object.entries(env).reduce<Record<string, string>>((accumulator, [key, value]) => {\n if (typeof value === \"string\") {\n accumulator[key] = value\n }\n return accumulator\n }, {})\n\n return Object.keys(entries).length > 0 ? entries : undefined\n}\n\nconst collectOptions = (\n node: Record<string, unknown>,\n excludedKeys: ReadonlySet<string>,\n): Readonly<Record<string, unknown>> | undefined => {\n const optionsEntries = Object.entries(node).filter(([key]) => !excludedKeys.has(key))\n if (optionsEntries.length === 0) {\n return undefined\n }\n\n return optionsEntries.reduce<Record<string, unknown>>((accumulator, [key, value]) => {\n accumulator[key] = value\n return accumulator\n }, {})\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null\n}\n\nconst looksSplitLikeNode = (value: Record<string, unknown>): boolean => {\n return \"type\" in value || \"ratio\" in value || \"panes\" in value\n}\n\nconst sanitizeLayoutForSchemaValidation = (node: unknown): unknown => {\n if (!isRecord(node)) {\n return node\n }\n\n if (looksSplitLikeNode(node)) {\n const panes = Array.isArray(node.panes)\n ? node.panes.map((child) => sanitizeLayoutForSchemaValidation(child))\n : node.panes\n return {\n type: node.type,\n ratio: node.ratio,\n panes,\n }\n }\n\n return {\n name: node.name,\n command: node.command,\n cwd: node.cwd,\n env: normalizeEnv(node.env),\n delay: node.delay,\n title: node.title,\n focus: node.focus,\n ephemeral: node.ephemeral,\n closeOnError: node.closeOnError,\n }\n}\n\nconst convertLayoutIssueToCompileError = ({\n issue,\n source,\n basePath,\n layout,\n}: {\n readonly issue: z.ZodIssue\n readonly source: string\n readonly basePath: string\n readonly layout: unknown\n}): CoreError => {\n if (isMissingArrayIssue(issue, \"panes\")) {\n return compileError(\"LAYOUT_PANES_MISSING\", {\n source,\n message: \"panes array is missing or empty\",\n path: `${basePath}.panes`,\n })\n }\n\n if (isMissingArrayIssue(issue, \"ratio\")) {\n return compileError(\"LAYOUT_RATIO_MISSING\", {\n source,\n message: \"ratio array is missing or empty\",\n path: `${basePath}.ratio`,\n })\n }\n\n if (issue.path.includes(\"type\")) {\n return compileError(\"LAYOUT_INVALID_ORIENTATION\", {\n source,\n message: \"layout.type must be horizontal or vertical\",\n path: `${basePath}.type`,\n details: {\n type: getValueAtPath(layout, issue.path),\n },\n })\n }\n\n if (issue.message.includes(\"Number of elements in ratio array does not match number of elements in panes array\")) {\n return compileError(\"LAYOUT_RATIO_MISMATCH\", {\n source,\n message: \"ratio and panes arrays must have the same length\",\n path: basePath,\n details: getRatioLengthDetails(layout),\n })\n }\n\n if (issue.path.includes(\"ratio\")) {\n return compileError(\"RATIO_INVALID_VALUE\", {\n source,\n message: \"ratio value must be a positive number\",\n path: formatPath(basePath, issue.path),\n details: {\n value: getValueAtPath(layout, issue.path),\n },\n })\n }\n\n return compileError(\"LAYOUT_INVALID_NODE\", {\n source,\n message: \"Layout node is invalid\",\n path: formatPath(basePath, issue.path),\n details: {\n issue: issue.message,\n node: getValueAtPath(layout, issue.path),\n },\n })\n}\n\nconst isMissingArrayIssue = (issue: z.ZodIssue, field: \"panes\" | \"ratio\"): boolean => {\n if (issue.path.length !== 1 || issue.path[0] !== field) {\n return false\n }\n\n return issue.code === \"invalid_type\" || (issue.code === \"too_small\" && issue.type === \"array\")\n}\n\nconst getRatioLengthDetails = (layout: unknown): Readonly<Record<string, unknown>> | undefined => {\n if (!isRecord(layout)) {\n return undefined\n }\n\n const ratio = layout.ratio\n const panes = layout.panes\n if (!Array.isArray(ratio) || !Array.isArray(panes)) {\n return undefined\n }\n\n return {\n ratioLength: ratio.length,\n panesLength: panes.length,\n }\n}\n\nconst formatPath = (basePath: string, path: ReadonlyArray<string | number>): string => {\n if (path.length === 0) {\n return basePath\n }\n\n return path.reduce<string>((accumulator, segment) => {\n if (typeof segment === \"number\") {\n return `${accumulator}[${segment}]`\n }\n return `${accumulator}.${segment}`\n }, basePath)\n}\n\nconst getValueAtPath = (value: unknown, path: ReadonlyArray<string | number>): unknown => {\n let current: unknown = value\n\n for (const segment of path) {\n if (typeof segment === \"number\") {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current[segment]\n continue\n }\n\n if (!isRecord(current)) {\n return undefined\n }\n current = current[segment]\n }\n\n return current\n}\n\nconst compileError = (\n code: string,\n error: {\n readonly source?: string\n readonly message: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n },\n): CoreError => {\n return createCoreError(\"compile\", {\n code,\n message: error.message,\n source: error.source,\n path: error.path,\n details: error.details,\n })\n}\n","import type { CompiledLayoutNode, CompiledPreset, CompiledSplitPane, CompiledTerminalPane } from \"./compile\"\nimport { createCoreError, type CoreError } from \"./errors\"\n\ntype CreateLayoutPlanInput = {\n readonly preset: CompiledPreset\n}\n\ntype PlanTerminal = {\n readonly kind: \"terminal\"\n readonly id: string\n readonly name: string\n readonly command?: string\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly delay?: number\n readonly title?: string\n readonly focus: boolean\n readonly ephemeral?: boolean\n readonly closeOnError?: boolean\n readonly options?: Readonly<Record<string, unknown>>\n}\n\ntype PlanSplit = {\n readonly kind: \"split\"\n readonly id: string\n readonly orientation: \"horizontal\" | \"vertical\"\n readonly ratio: ReadonlyArray<number>\n readonly panes: ReadonlyArray<PlanNode>\n}\n\nexport type PlanNode = PlanTerminal | PlanSplit\n\nexport type LayoutPlan = {\n readonly root: PlanNode\n readonly focusPaneId: string\n}\n\nexport type CreateLayoutPlanSuccess = {\n readonly plan: LayoutPlan\n}\n\nexport const createLayoutPlan = ({ preset }: CreateLayoutPlanInput): CreateLayoutPlanSuccess => {\n if (!preset.layout) {\n const terminal = createTerminalNode({\n id: \"root\",\n terminal: {\n kind: \"terminal\",\n name: preset.name,\n command: preset.command,\n },\n focusOverride: true,\n })\n\n return {\n plan: {\n root: terminal,\n focusPaneId: terminal.id,\n },\n }\n }\n\n const { node, focusPaneIds, terminalPaneIds } = buildLayoutNode(preset.layout, {\n parentId: \"root\",\n path: \"preset.layout\",\n source: preset.metadata.source,\n })\n\n if (focusPaneIds.length > 1) {\n throw planError(\"FOCUS_CONFLICT\", {\n message: \"Multiple panes specify focus=true\",\n path: \"preset.layout\",\n source: preset.metadata.source,\n details: { focusPaneIds },\n })\n }\n\n if (terminalPaneIds.length === 0) {\n throw planError(\"NO_TERMINAL_PANES\", {\n message: \"No terminal panes are defined\",\n path: \"preset.layout\",\n source: preset.metadata.source,\n })\n }\n\n const focusPaneId = focusPaneIds[0] ?? terminalPaneIds[0]!\n const root = ensureFocus(node, focusPaneId)\n\n return {\n plan: {\n root,\n focusPaneId,\n },\n }\n}\n\ntype BuildResult = {\n readonly node: PlanNode\n readonly focusPaneIds: ReadonlyArray<string>\n readonly terminalPaneIds: ReadonlyArray<string>\n}\n\nconst buildLayoutNode = (\n node: CompiledLayoutNode,\n context: { readonly parentId: string; readonly path: string; readonly source: string },\n): BuildResult => {\n if (node.kind === \"split\") {\n return buildSplitNode(node, context)\n }\n\n return {\n node: createTerminalNode({ id: context.parentId, terminal: node }),\n focusPaneIds: node.focus === true ? [context.parentId] : [],\n terminalPaneIds: [context.parentId],\n }\n}\n\nconst buildSplitNode = (\n node: CompiledSplitPane,\n context: { readonly parentId: string; readonly path: string; readonly source: string },\n): BuildResult => {\n const ratio = normalizeRatio(node.ratio, context)\n\n const panes: PlanNode[] = []\n const focusPaneIds: string[] = []\n const terminalPaneIds: string[] = []\n\n for (let index = 0; index < node.panes.length; index += 1) {\n const childId = `${context.parentId}.${index}`\n const childContext = {\n parentId: childId,\n path: `${context.path}.panes[${index}]`,\n source: context.source,\n }\n\n const childResult = buildLayoutNode(node.panes[index]!, childContext)\n panes.push(childResult.node)\n focusPaneIds.push(...childResult.focusPaneIds)\n terminalPaneIds.push(...childResult.terminalPaneIds)\n }\n\n return {\n node: {\n kind: \"split\",\n id: context.parentId,\n orientation: node.orientation,\n ratio,\n panes,\n },\n focusPaneIds,\n terminalPaneIds,\n }\n}\n\nconst createTerminalNode = ({\n id,\n terminal,\n focusOverride,\n}: {\n readonly id: string\n readonly terminal: CompiledTerminalPane\n readonly focusOverride?: boolean\n}): PlanTerminal => {\n return {\n kind: \"terminal\",\n id,\n name: terminal.name,\n command: terminal.command,\n cwd: terminal.cwd,\n env: terminal.env,\n delay: terminal.delay,\n title: terminal.title,\n options: terminal.options,\n focus: focusOverride === true ? true : terminal.focus === true,\n ephemeral: terminal.ephemeral,\n closeOnError: terminal.closeOnError,\n }\n}\n\nconst ensureFocus = (node: PlanNode, focusPaneId: string): PlanNode => {\n if (node.kind === \"terminal\") {\n return {\n ...node,\n focus: node.id === focusPaneId,\n }\n }\n\n return {\n ...node,\n panes: node.panes.map((pane) => ensureFocus(pane, focusPaneId)),\n }\n}\n\nconst normalizeRatio = (\n ratio: ReadonlyArray<number>,\n context: { readonly path: string; readonly source: string },\n): number[] => {\n const total = ratio.reduce((sum, value, index) => {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n throw planError(\"RATIO_INVALID_VALUE\", {\n message: \"ratio value must be a non-negative number\",\n path: `${context.path}.ratio[${index}]`,\n source: context.source,\n details: { value },\n })\n }\n return sum + value\n }, 0)\n\n if (total === 0) {\n return ratio.map(() => 1 / ratio.length)\n }\n\n return ratio.map((value) => value / total)\n}\n\nconst planError = (\n code: string,\n error: {\n readonly message: string\n readonly source?: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n },\n): CoreError => {\n return createCoreError(\"plan\", {\n code,\n message: error.message,\n source: error.source,\n path: error.path,\n details: error.details,\n })\n}\n","import { createHash } from \"crypto\"\nimport type { LayoutPlan, PlanNode } from \"./planner\"\n\ntype EmitPlanInput = {\n readonly plan: LayoutPlan\n}\n\ntype CommandStepKind = \"split\" | \"focus\"\n\nexport type CommandStep = {\n readonly id: string\n readonly kind: CommandStepKind\n readonly command?: ReadonlyArray<string>\n readonly summary: string\n readonly targetPaneId?: string\n readonly createdPaneId?: string\n readonly orientation?: \"horizontal\" | \"vertical\"\n readonly percentage?: number\n}\n\nexport type EmittedTerminal = {\n readonly virtualPaneId: string\n readonly command?: string\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly delay?: number\n readonly title?: string\n readonly focus: boolean\n readonly name: string\n readonly ephemeral?: boolean\n readonly closeOnError?: boolean\n}\n\ntype PlanEmissionSummary = {\n readonly stepsCount: number\n readonly focusPaneId: string\n readonly initialPaneId: string\n}\n\nexport type PlanEmission = {\n readonly steps: ReadonlyArray<CommandStep>\n readonly summary: PlanEmissionSummary\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly hash: string\n}\n\ntype SplitNode = Extract<PlanNode, { kind: \"split\" }>\n\nexport const emitPlan = ({ plan }: EmitPlanInput): PlanEmission => {\n const steps: CommandStep[] = []\n collectSplitSteps(plan.root, steps)\n\n steps.push({\n id: `${plan.focusPaneId}:focus`,\n kind: \"focus\",\n summary: `select pane ${plan.focusPaneId}`,\n targetPaneId: plan.focusPaneId,\n })\n\n const hash = createPlanHash(plan, steps)\n const initialPaneId = determineInitialPaneId(plan.root)\n const terminals = collectTerminals(plan.root)\n\n return {\n steps,\n summary: {\n stepsCount: steps.length,\n focusPaneId: plan.focusPaneId,\n initialPaneId,\n },\n terminals,\n hash,\n }\n}\n\nconst collectSplitSteps = (node: PlanNode, steps: CommandStep[]): void => {\n if (node.kind === \"terminal\") {\n return\n }\n\n appendSplitSteps(node, steps)\n node.panes.forEach((pane) => collectSplitSteps(pane, steps))\n}\n\nconst appendSplitSteps = (node: SplitNode, steps: CommandStep[]): void => {\n const directionFlag = node.orientation === \"horizontal\" ? \"-h\" : \"-v\"\n\n for (let index = 1; index < node.panes.length; index += 1) {\n const remainingIncludingTarget = node.ratio.slice(index - 1).reduce((sum, value) => sum + value, 0)\n const remainingAfterTarget = node.ratio.slice(index).reduce((sum, value) => sum + value, 0)\n\n const desiredPercentage =\n remainingIncludingTarget === 0 ? 0 : (remainingAfterTarget / remainingIncludingTarget) * 100\n const percentage = clampPercent(desiredPercentage)\n const targetPaneId = node.panes[index - 1]?.id ?? node.id\n const createdPaneId = node.panes[index]?.id\n\n steps.push({\n id: `${node.id}:split:${index}`,\n kind: \"split\",\n summary: `split ${targetPaneId} (${directionFlag})`,\n targetPaneId,\n createdPaneId,\n orientation: node.orientation,\n percentage,\n })\n }\n}\n\nconst clampPercent = (value: number): number => {\n return Math.min(99, Math.max(1, Math.round(value)))\n}\n\nconst collectTerminals = (node: PlanNode): EmittedTerminal[] => {\n if (node.kind === \"terminal\") {\n return [\n {\n virtualPaneId: node.id,\n command: node.command,\n cwd: node.cwd,\n env: node.env,\n delay: node.delay,\n title: node.title,\n focus: node.focus,\n name: node.name,\n ephemeral: node.ephemeral,\n closeOnError: node.closeOnError,\n },\n ]\n }\n\n return node.panes.flatMap((pane) => collectTerminals(pane))\n}\n\nconst determineInitialPaneId = (node: PlanNode): string => {\n if (node.kind === \"terminal\") {\n return node.id\n }\n\n let current: PlanNode = node\n while (current.kind === \"split\") {\n current = current.panes[0]!\n }\n return current.id\n}\n\nconst createPlanHash = (plan: LayoutPlan, steps: ReadonlyArray<CommandStep>): string => {\n const digest = createHash(\"sha256\")\n const normalized = {\n focusPaneId: plan.focusPaneId,\n root: plan.root,\n steps,\n }\n digest.update(JSON.stringify(normalized))\n return digest.digest(\"hex\")\n}\n","import { isCoreError, type CoreError } from \"../core/index\"\nimport type { Logger } from \"../utils/logger\"\n\ntype CliErrorHandlers = {\n handleCoreError: (error: CoreError) => number\n handleError: (error: unknown) => number\n handlePipelineFailure: (error: unknown) => number\n}\n\nexport const createCliErrorHandlers = ({ getLogger }: { getLogger: () => Logger }): CliErrorHandlers => {\n const handleCoreError = (error: CoreError): number => {\n const header = [`[${error.kind}]`, `[${error.code}]`]\n if (typeof error.path === \"string\" && error.path.length > 0) {\n header.push(`[${error.path}]`)\n }\n\n const lines = [`${header.join(\" \")} ${error.message}`.trim()]\n\n if (typeof error.source === \"string\" && error.source.length > 0) {\n lines.push(`source: ${error.source}`)\n }\n\n const commandDetail = error.details?.command\n if (Array.isArray(commandDetail)) {\n const parts = commandDetail.filter((segment): segment is string => typeof segment === \"string\")\n if (parts.length > 0) {\n lines.push(`command: ${parts.join(\" \")}`)\n }\n } else if (typeof commandDetail === \"string\" && commandDetail.length > 0) {\n lines.push(`command: ${commandDetail}`)\n }\n\n const stderrDetail = error.details?.stderr\n if (typeof stderrDetail === \"string\" && stderrDetail.length > 0) {\n lines.push(`stderr: ${stderrDetail}`)\n } else if (stderrDetail !== undefined) {\n lines.push(`stderr: ${String(stderrDetail)}`)\n }\n\n getLogger().error(lines.join(\"\\n\"))\n return 1\n }\n\n const handleError = (error: unknown): number => {\n if (error instanceof Error) {\n getLogger().error(error.message, error)\n } else {\n getLogger().error(\"An unexpected error occurred\")\n }\n\n return 1\n }\n\n const handlePipelineFailure = (error: unknown): number => {\n if (isCoreError(error)) {\n return handleCoreError(error)\n }\n return handleError(error)\n }\n\n return {\n handleCoreError,\n handleError,\n handlePipelineFailure,\n }\n}\n","import chalk from \"chalk\"\n\nexport enum LogLevel {\n ERROR = 0,\n WARN = 1,\n INFO = 2,\n DEBUG = 3,\n}\n\ntype LoggerOptions = {\n readonly level?: LogLevel\n readonly prefix?: string\n}\n\nexport type Logger = {\n readonly level: LogLevel\n readonly prefix: string\n error: (message: string, error?: Error) => void\n warn: (message: string) => void\n info: (message: string) => void\n debug: (message: string) => void\n success: (message: string) => void\n createChild: (suffix: string) => Logger\n}\n\nconst resolveDefaultLogLevel = (): LogLevel => {\n if (process.env.VDE_DEBUG === \"true\") {\n return LogLevel.DEBUG\n }\n if (process.env.VDE_VERBOSE === \"true\") {\n return LogLevel.INFO\n }\n return LogLevel.WARN\n}\n\nconst formatMessage = (prefix: string, message: string): string => {\n return prefix ? `${prefix} ${message}` : message\n}\n\nexport const createLogger = (options: LoggerOptions = {}): Logger => {\n const level = options.level ?? resolveDefaultLogLevel()\n const prefix = options.prefix ?? \"\"\n\n const build = (nextPrefix: string, nextLevel: LogLevel): Logger => {\n const resolvedPrefix = nextPrefix\n\n return {\n level: nextLevel,\n prefix: resolvedPrefix,\n error(message: string, error?: Error): void {\n if (nextLevel >= LogLevel.ERROR) {\n console.error(chalk.red(formatMessage(resolvedPrefix, `Error: ${message}`)))\n if (error && process.env.VDE_DEBUG === \"true\") {\n console.error(chalk.gray(error.stack))\n }\n }\n },\n warn(message: string): void {\n if (nextLevel >= LogLevel.WARN) {\n console.warn(chalk.yellow(formatMessage(resolvedPrefix, message)))\n }\n },\n info(message: string): void {\n if (nextLevel >= LogLevel.INFO) {\n console.log(formatMessage(resolvedPrefix, message))\n }\n },\n debug(message: string): void {\n if (nextLevel >= LogLevel.DEBUG) {\n console.log(chalk.gray(formatMessage(resolvedPrefix, `[DEBUG] ${message}`)))\n }\n },\n success(message: string): void {\n console.log(chalk.green(formatMessage(resolvedPrefix, message)))\n },\n createChild(suffix: string): Logger {\n const childPrefix = resolvedPrefix ? `${resolvedPrefix} ${suffix}` : suffix\n return build(childPrefix, nextLevel)\n },\n }\n }\n\n return build(prefix, level)\n}\n","import chalk from \"chalk\"\n\nimport type { PresetInfo } from \"../models/types\"\nimport type { PresetManager } from \"../contracts\"\nimport { LogLevel, type Logger } from \"../utils/logger\"\n\ntype RuntimeOptions = {\n readonly verbose?: boolean\n readonly config?: string\n}\n\nexport const applyRuntimeOptions = ({\n runtimeOptions,\n createLogger,\n presetManager,\n}: {\n readonly runtimeOptions: RuntimeOptions\n readonly createLogger: (options?: { level?: LogLevel }) => Logger\n readonly presetManager: PresetManager\n}): Logger => {\n const logger =\n runtimeOptions.verbose === true\n ? createLogger({\n level: LogLevel.INFO,\n })\n : createLogger()\n\n if (\n typeof runtimeOptions.config === \"string\" &&\n runtimeOptions.config.length > 0 &&\n typeof presetManager.setConfigPath === \"function\"\n ) {\n presetManager.setConfigPath(runtimeOptions.config)\n }\n\n return logger\n}\n\nexport const listPresets = async ({\n presetManager,\n logger,\n onError,\n output = (line: string): void => console.log(line),\n}: {\n readonly presetManager: PresetManager\n readonly logger: Logger\n readonly onError: (error: unknown) => number\n readonly output?: (line: string) => void\n}): Promise<number> => {\n try {\n await presetManager.loadConfig()\n const presets = presetManager.listPresets()\n\n if (presets.length === 0) {\n logger.warn(\"No presets defined\")\n return 0\n }\n\n output(chalk.bold(\"Available presets:\\n\"))\n\n const maxKeyLength = Math.max(...presets.map((preset) => preset.key.length))\n presets.forEach((preset: PresetInfo) => {\n const paddedKey = preset.key.padEnd(maxKeyLength + 2)\n const description = preset.description ?? \"\"\n output(` ${chalk.cyan(paddedKey)} ${description}`)\n })\n\n return 0\n } catch (error) {\n return onError(error)\n }\n}\n","import { execa } from \"execa\"\nimport { createTmuxError, ErrorCodes } from \"../utils/errors\"\nimport type { CommandExecutor } from \"../contracts\"\nimport { createLogger, LogLevel } from \"../utils/logger\"\n\ntype RealExecutorOptions = {\n readonly verbose?: boolean\n}\n\nconst parseCommand = (commandOrArgs: string | string[]): string[] => {\n return typeof commandOrArgs === \"string\"\n ? commandOrArgs\n .split(\" \")\n .filter((segment) => segment.length > 0)\n .slice(1)\n : commandOrArgs\n}\n\nconst toCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n}\n\nexport const createRealExecutor = (options: RealExecutorOptions = {}): CommandExecutor => {\n const verbose = options.verbose ?? false\n const logger = createLogger({\n level: verbose ? LogLevel.INFO : LogLevel.WARN,\n prefix: \"[tmux]\",\n })\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n const args = parseCommand(commandOrArgs)\n const commandString = toCommandString(args)\n\n logger.info(`Executing: ${commandString}`)\n\n try {\n const result = await execa(\"tmux\", args)\n return result.stdout\n } catch (error) {\n const execaError = error as { exitCode?: number; stderr?: string; message: string }\n\n throw createTmuxError(\"Failed to execute tmux command\", ErrorCodes.TMUX_COMMAND_FAILED, {\n command: commandString,\n exitCode: execaError.exitCode,\n stderr: execaError.stderr,\n })\n }\n }\n\n return {\n execute,\n async executeMany(commandsList: string[][]): Promise<void> {\n for (const args of commandsList) {\n await execute(args)\n }\n },\n isDryRun(): boolean {\n return false\n },\n logCommand(command: string): void {\n logger.info(`Executing: ${command}`)\n },\n }\n}\n","import type { CommandExecutor } from \"../contracts\"\nimport { createLogger, LogLevel } from \"../utils/logger\"\n\ntype DryRunExecutorOptions = {\n readonly verbose?: boolean\n}\n\nconst parseCommand = (commandOrArgs: string | string[]): string[] => {\n return typeof commandOrArgs === \"string\"\n ? commandOrArgs\n .split(\" \")\n .filter((segment) => segment.length > 0)\n .slice(1)\n : commandOrArgs\n}\n\nconst toCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n}\n\nexport const createDryRunExecutor = (options: DryRunExecutorOptions = {}): CommandExecutor => {\n const verbose = options.verbose ?? false\n const logger = createLogger({\n level: verbose ? LogLevel.INFO : LogLevel.WARN,\n prefix: \"[tmux] [DRY RUN]\",\n })\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n const args = parseCommand(commandOrArgs)\n const commandString = toCommandString(args)\n logger.info(`Would execute: ${commandString}`)\n return \"\"\n }\n\n return {\n execute,\n async executeMany(commandsList: string[][]): Promise<void> {\n for (const args of commandsList) {\n await execute(args)\n }\n },\n isDryRun(): boolean {\n return true\n },\n logCommand(command: string): void {\n logger.info(`Would execute: ${command}`)\n },\n }\n}\n","import type { CommandExecutor } from \"../contracts\"\nimport type { TmuxExecutorContract } from \"../contracts\"\nimport { createEnvironmentError, ErrorCodes } from \"../utils/errors\"\n\nexport type MockExecutor = CommandExecutor &\n TmuxExecutorContract & {\n readonly getExecutedCommands: () => string[][]\n readonly clearExecutedCommands: () => void\n readonly setMockPaneIds: (paneIds: string[]) => void\n readonly getPaneIds: () => string[]\n }\n\nconst parseCommand = (commandOrArgs: string | string[]): string[] => {\n return typeof commandOrArgs === \"string\"\n ? commandOrArgs\n .split(\" \")\n .filter((segment) => segment.length > 0)\n .slice(1)\n : commandOrArgs\n}\n\nconst isInTmuxSession = (): boolean => {\n return Boolean(process.env.TMUX)\n}\n\nconst toCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n}\n\nexport const createMockExecutor = (): MockExecutor => {\n let mockPaneCounter = 0\n let mockPaneIds: string[] = [\"%0\"]\n let executedCommands: string[][] = []\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n const args = parseCommand(commandOrArgs)\n executedCommands.push(args)\n\n if (args[0] === \"new-window\") {\n mockPaneCounter = 0\n mockPaneIds = [\"%0\"]\n return \"%0\"\n }\n\n if (args.includes(\"display-message\") && args.includes(\"#{pane_id}\")) {\n return mockPaneIds[0] ?? \"%0\"\n }\n\n if (args.includes(\"list-panes\") && args.includes(\"#{pane_id}\")) {\n return mockPaneIds.join(\"\\n\")\n }\n\n if (args[0] === \"kill-pane\" && args.includes(\"-a\")) {\n const targetIndex = args.indexOf(\"-t\")\n const targetPane =\n (targetIndex >= 0 && targetIndex + 1 < args.length ? args[targetIndex + 1] : mockPaneIds[0]) ?? \"%0\"\n mockPaneIds = [targetPane]\n const parsedCounter = Number(targetPane.replace(\"%\", \"\"))\n if (!Number.isNaN(parsedCounter)) {\n mockPaneCounter = parsedCounter\n }\n return \"\"\n }\n\n if (args.includes(\"split-window\")) {\n mockPaneCounter += 1\n const newPaneId = `%${mockPaneCounter}`\n mockPaneIds = [...mockPaneIds, newPaneId]\n }\n\n return \"\"\n }\n\n return {\n execute,\n async executeMany(commandsList: string[][]): Promise<void> {\n for (const args of commandsList) {\n await execute(args)\n }\n },\n isDryRun(): boolean {\n return true\n },\n logCommand(): void {\n // noop\n },\n getExecutedCommands(): string[][] {\n return executedCommands\n },\n clearExecutedCommands(): void {\n executedCommands = []\n },\n setMockPaneIds(paneIds: string[]): void {\n mockPaneIds = [...paneIds]\n },\n getPaneIds(): string[] {\n return mockPaneIds\n },\n isInTmuxSession,\n async verifyTmuxEnvironment(): Promise<void> {\n if (!isInTmuxSession()) {\n throw createEnvironmentError(\"Must be run inside a tmux session\", ErrorCodes.NOT_IN_TMUX_SESSION, {\n hint: \"Please start a tmux session and try again\",\n })\n }\n },\n getCommandString: toCommandString,\n async getCurrentSessionName(): Promise<string> {\n return \"mock-session\"\n },\n }\n}\n","import { execa } from \"execa\"\nimport { createEnvironmentError, ErrorCodes } from \"../../utils/errors\"\nimport type { TmuxExecutorContract } from \"../../contracts\"\nimport type { CommandExecutor } from \"../../contracts\"\nimport { createRealExecutor, createDryRunExecutor, createMockExecutor } from \"../../executor/index\"\n\ntype TmuxExecutorOptions = {\n readonly verbose?: boolean\n readonly dryRun?: boolean\n readonly executor?: CommandExecutor\n}\n\nexport type TmuxExecutor = TmuxExecutorContract & {\n readonly getExecutor: () => CommandExecutor\n}\n\nexport const createTmuxExecutor = (options: TmuxExecutorOptions = {}): TmuxExecutor => {\n const executor = resolveExecutor(options)\n\n const isInTmuxSession = (): boolean => {\n return Boolean(process.env.TMUX)\n }\n\n const verifyTmuxEnvironment = async (): Promise<void> => {\n if (!isInTmuxSession()) {\n throw createEnvironmentError(\"Must be run inside a tmux session\", ErrorCodes.NOT_IN_TMUX_SESSION, {\n hint: \"Please start a tmux session and try again\",\n })\n }\n\n if (executor.isDryRun()) {\n return\n }\n\n try {\n await execa(\"tmux\", [\"-V\"])\n } catch (_error) {\n throw createEnvironmentError(\"tmux is not installed\", ErrorCodes.TMUX_NOT_FOUND, {\n hint: \"Please install tmux\",\n })\n }\n }\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n return executor.execute(commandOrArgs)\n }\n\n const executeMany = async (commandsList: string[][]): Promise<void> => {\n for (const command of commandsList) {\n await execute(command)\n }\n }\n\n const getCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n }\n\n const getCurrentSessionName = async (): Promise<string> => {\n return execute([\"display-message\", \"-p\", \"#{session_name}\"])\n }\n\n return {\n verifyTmuxEnvironment,\n execute,\n executeMany,\n isInTmuxSession,\n getCurrentSessionName,\n getCommandString,\n getExecutor: () => executor,\n }\n}\n\nconst resolveExecutor = (options: TmuxExecutorOptions): CommandExecutor => {\n if (options.executor) {\n return options.executor\n }\n\n if (options.dryRun === true) {\n return createDryRunExecutor({ verbose: options.verbose })\n }\n\n if (isTestEnvironment()) {\n return createMockExecutor()\n }\n\n return createRealExecutor({ verbose: options.verbose })\n}\n\nconst isTestEnvironment = (): boolean => {\n return process.env.VDE_TEST_MODE === \"true\" || process.env.NODE_ENV === \"test\" || process.env.VITEST === \"true\"\n}\n","export const waitForDelay = (ms: number): Promise<void> => {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms)\n })\n}\n","export const resolvePaneMapping = (paneMap: Map<string, string>, virtualId: string): string | undefined => {\n const direct = paneMap.get(virtualId)\n if (typeof direct === \"string\" && direct.length > 0) {\n return direct\n }\n\n let ancestor = virtualId\n while (ancestor.includes(\".\")) {\n ancestor = ancestor.slice(0, ancestor.lastIndexOf(\".\"))\n const candidate = paneMap.get(ancestor)\n if (typeof candidate === \"string\" && candidate.length > 0) {\n paneMap.set(virtualId, candidate)\n return candidate\n }\n }\n\n for (const [key, value] of paneMap.entries()) {\n if (key.startsWith(`${virtualId}.`)) {\n if (typeof value === \"string\" && value.length > 0) {\n paneMap.set(virtualId, value)\n return value\n }\n }\n }\n\n return undefined\n}\n","import type { CommandStep } from \"../core/emitter\"\nimport { createCoreError } from \"../core/errors\"\nimport { ErrorCodes } from \"../utils/errors\"\n\ntype SplitOrientation = \"horizontal\" | \"vertical\"\ntype SplitCommandStep = CommandStep & { readonly kind: \"split\" }\n\nconst asSplitStep = (step: CommandStep, field: \"orientation\" | \"percentage\"): SplitCommandStep => {\n if (step.kind !== \"split\") {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: `Non-split step cannot resolve split ${field}`,\n path: step.id,\n details: { kind: step.kind },\n })\n }\n return step as SplitCommandStep\n}\n\nexport const resolveSplitOrientation = (step: CommandStep): SplitOrientation => {\n const splitStep = asSplitStep(step, \"orientation\")\n\n if (splitStep.orientation === \"horizontal\" || splitStep.orientation === \"vertical\") {\n return splitStep.orientation\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: \"Split step missing orientation metadata\",\n path: splitStep.id,\n details: { orientation: splitStep.orientation },\n })\n}\n\nexport const resolveSplitPercentage = (step: CommandStep): string => {\n const splitStep = asSplitStep(step, \"percentage\")\n\n if (typeof splitStep.percentage === \"number\" && Number.isFinite(splitStep.percentage)) {\n return String(clampSplitPercentage(splitStep.percentage))\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: \"Split step missing percentage metadata\",\n path: splitStep.id,\n details: { percentage: splitStep.percentage },\n })\n}\n\nconst clampSplitPercentage = (value: number): number => {\n return Math.min(99, Math.max(1, Math.round(value)))\n}\n","import type { EmittedTerminal } from \"../core/emitter\"\n\n/**\n * Template token types supported in pane commands:\n * - {{pane_id:<name>}} - resolves to a specific pane's ID by name\n * - {{this_pane}} - references the current pane receiving the command\n * - {{focus_pane}} - references the intended focus pane\n */\n\ntype ReplaceTemplateTokensInput = {\n readonly command: string\n readonly currentPaneRealId: string\n readonly focusPaneRealId: string\n readonly nameToRealIdMap: ReadonlyMap<string, string>\n}\n\nexport type TemplateTokenError = Error & {\n readonly tokenType: string\n readonly availablePanes?: ReadonlyArray<string>\n}\n\ntype TemplateTokenErrorConstructor = {\n new (message: string, tokenType: string, availablePanes?: ReadonlyArray<string>): TemplateTokenError\n (message: string, tokenType: string, availablePanes?: ReadonlyArray<string>): TemplateTokenError\n readonly prototype: TemplateTokenError\n}\n\nconst TemplateTokenErrorImpl = function TemplateTokenError(\n message: string,\n tokenType: string,\n availablePanes?: ReadonlyArray<string>,\n): TemplateTokenError {\n type MutableTemplateTokenError = Error & { tokenType: string; availablePanes?: ReadonlyArray<string> }\n const error = new Error(message) as MutableTemplateTokenError\n Object.setPrototypeOf(error, TemplateTokenErrorImpl.prototype)\n error.name = \"TemplateTokenError\"\n error.tokenType = tokenType\n error.availablePanes = availablePanes\n return error as TemplateTokenError\n}\n\nTemplateTokenErrorImpl.prototype = Object.create(Error.prototype)\nTemplateTokenErrorImpl.prototype.constructor = TemplateTokenErrorImpl\n\nexport const TemplateTokenError = TemplateTokenErrorImpl as TemplateTokenErrorConstructor\n\n/**\n * Replaces template tokens in a command string with actual pane IDs.\n *\n * Uses a single-pass regex replacement to avoid nested token issues.\n * All tokens are replaced in a single pass, preventing already-replaced\n * values from being re-processed.\n *\n * @param input - Object containing the command and pane ID mappings\n * @returns The command string with all template tokens replaced\n * @throws TemplateTokenError if a referenced pane name is not found in the mapping\n */\nexport const replaceTemplateTokens = ({\n command,\n currentPaneRealId,\n focusPaneRealId,\n nameToRealIdMap,\n}: ReplaceTemplateTokensInput): string => {\n // Single-pass regex that matches all token types\n // This prevents nested token issues by replacing everything in one pass\n const tokenPattern = /\\{\\{(this_pane|focus_pane|pane_id:([^}]+))\\}\\}/g\n\n return command.replace(tokenPattern, (match, tokenContent: string, paneName?: string) => {\n if (tokenContent === \"this_pane\") {\n return currentPaneRealId\n }\n\n if (tokenContent === \"focus_pane\") {\n return focusPaneRealId\n }\n\n // Must be pane_id:<name> token\n if (tokenContent.startsWith(\"pane_id:\") && paneName !== undefined) {\n const trimmedName = paneName.trim()\n const paneId = nameToRealIdMap.get(trimmedName)\n\n if (paneId === undefined) {\n throw new TemplateTokenError(\n `Pane name \"${trimmedName}\" not found. Available panes: ${Array.from(nameToRealIdMap.keys()).join(\", \")}`,\n \"pane_id\",\n Array.from(nameToRealIdMap.keys()),\n )\n }\n\n return paneId\n }\n\n // Fallback: return original match if token is malformed\n return match\n })\n}\n\n/**\n * Builds a mapping from pane names to real pane IDs.\n *\n * **Duplicate Name Handling:**\n * If multiple panes share the same name, the last one in the terminals\n * array wins. This follows the iteration order of the layout tree.\n * It's recommended to use unique names for panes to avoid ambiguity\n * in template token references.\n *\n * **Virtual to Real ID Resolution:**\n * Only panes with successfully resolved real IDs (present in paneMap)\n * are included in the resulting map. This ensures that template tokens\n * only reference panes that have been properly created.\n *\n * @param terminals - Array of emitted terminals from the layout plan\n * @param paneMap - Map from virtual pane IDs to real pane IDs (backend-specific)\n * @returns A map from pane names to real pane IDs\n */\nexport const buildNameToRealIdMap = (\n terminals: ReadonlyArray<EmittedTerminal>,\n paneMap: ReadonlyMap<string, string>,\n): Map<string, string> => {\n const nameToRealIdMap = new Map<string, string>()\n\n for (const terminal of terminals) {\n const realId = paneMap.get(terminal.virtualPaneId)\n if (realId !== undefined) {\n nameToRealIdMap.set(terminal.name, realId)\n }\n }\n\n return nameToRealIdMap\n}\n","import type { EmittedTerminal } from \"../core/emitter\"\nimport { buildNameToRealIdMap, replaceTemplateTokens, TemplateTokenError } from \"../utils/template-tokens\"\n\ntype TemplateTokenErrorContext = {\n readonly terminal: EmittedTerminal\n readonly error: TemplateTokenError\n}\n\ntype PrepareTerminalCommandsInput = {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly focusPaneVirtualId: string\n readonly resolveRealPaneId: (virtualPaneId: string) => string\n readonly onTemplateTokenError: (context: TemplateTokenErrorContext) => never\n}\n\ntype PreparedTerminalCommand = {\n readonly terminal: EmittedTerminal\n readonly realPaneId: string\n readonly cwdCommand?: string\n readonly envCommands: ReadonlyArray<{\n readonly key: string\n readonly command: string\n }>\n readonly title?: string\n readonly command?: {\n readonly text: string\n readonly delayMs: number\n }\n}\n\ntype PreparedTerminalCommands = {\n readonly focusPaneRealId: string\n readonly commands: ReadonlyArray<PreparedTerminalCommand>\n}\n\nconst SINGLE_QUOTE = \"'\"\nconst SHELL_SINGLE_QUOTE_ESCAPE = `'\"'\"'`\nconst ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/\n\nconst shellQuoteLiteral = (value: string): string => {\n return `'${value.split(SINGLE_QUOTE).join(SHELL_SINGLE_QUOTE_ESCAPE)}'`\n}\n\nconst assertValidEnvKey = (key: string): void => {\n if (!ENV_KEY_PATTERN.test(key)) {\n throw new Error(`Invalid environment variable name: ${key}`)\n }\n}\n\nconst normalizeDelay = (delay: unknown): number => {\n return typeof delay === \"number\" && Number.isFinite(delay) && delay > 0 ? delay : 0\n}\n\nconst applyEphemeralSuffix = (command: string, terminal: EmittedTerminal): string => {\n if (terminal.ephemeral !== true) {\n return command\n }\n\n return terminal.closeOnError === true ? `${command}; exit` : `${command}; [ $? -eq 0 ] && exit`\n}\n\nexport const prepareTerminalCommands = ({\n terminals,\n focusPaneVirtualId,\n resolveRealPaneId,\n onTemplateTokenError,\n}: PrepareTerminalCommandsInput): PreparedTerminalCommands => {\n const paneMap = new Map<string, string>()\n for (const terminal of terminals) {\n paneMap.set(terminal.virtualPaneId, resolveRealPaneId(terminal.virtualPaneId))\n }\n\n const focusPaneRealId = paneMap.get(focusPaneVirtualId) ?? resolveRealPaneId(focusPaneVirtualId)\n const nameToRealIdMap = buildNameToRealIdMap(terminals, paneMap)\n\n const commands: PreparedTerminalCommand[] = terminals.map((terminal) => {\n const realPaneId = paneMap.get(terminal.virtualPaneId)\n if (realPaneId === undefined) {\n throw new Error(`Unknown pane: ${terminal.virtualPaneId}`)\n }\n\n const cwdCommand =\n typeof terminal.cwd === \"string\" && terminal.cwd.length > 0\n ? `cd -- ${shellQuoteLiteral(terminal.cwd)}`\n : undefined\n\n const envCommands =\n terminal.env === undefined\n ? []\n : Object.entries(terminal.env).map(([key, value]) => {\n assertValidEnvKey(key)\n return {\n key,\n command: `export ${key}=${shellQuoteLiteral(String(value))}`,\n }\n })\n\n const title = typeof terminal.title === \"string\" && terminal.title.length > 0 ? terminal.title : undefined\n\n let command:\n | {\n readonly text: string\n readonly delayMs: number\n }\n | undefined\n\n if (typeof terminal.command === \"string\" && terminal.command.length > 0) {\n try {\n const commandUsesFocusToken = terminal.command.includes(\"{{focus_pane}}\")\n const replaced = replaceTemplateTokens({\n command: terminal.command,\n currentPaneRealId: realPaneId,\n focusPaneRealId: commandUsesFocusToken ? focusPaneRealId : \"\",\n nameToRealIdMap,\n })\n\n command = {\n text: applyEphemeralSuffix(replaced, terminal),\n delayMs: normalizeDelay(terminal.delay),\n }\n } catch (error) {\n if (error instanceof TemplateTokenError) {\n return onTemplateTokenError({ terminal, error })\n }\n throw error\n }\n }\n\n return {\n terminal,\n realPaneId,\n cwdCommand,\n envCommands,\n title,\n command,\n }\n })\n\n return {\n focusPaneRealId,\n commands,\n }\n}\n","import type { CommandStep, EmittedTerminal } from \"../core/emitter\"\nimport { createCoreError } from \"../core/errors\"\nimport type { CommandExecutor } from \"../contracts\"\nimport { waitForDelay } from \"../utils/async\"\nimport { ErrorCodes } from \"../utils/errors\"\nimport { resolvePaneMapping } from \"../utils/pane-map\"\nimport { resolveSplitOrientation, resolveSplitPercentage } from \"./split-step\"\nimport { prepareTerminalCommands } from \"./terminal-command-preparation\"\n\nexport const executeSplitStep = async ({\n step,\n executor,\n paneMap,\n}: {\n readonly step: CommandStep\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n}): Promise<void> => {\n const targetVirtualId = ensureNonEmpty(step.targetPaneId, () =>\n raiseExecutionError(ErrorCodes.MISSING_TARGET, {\n message: \"Split step missing target pane metadata\",\n path: step.id,\n }),\n )\n\n const targetRealId = ensureNonEmpty(resolvePaneId(paneMap, targetVirtualId), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown target pane: ${targetVirtualId}`,\n path: step.id,\n }),\n )\n\n const panesBefore = await listPaneIds(executor, step)\n const splitCommand = buildSplitCommand(step, targetRealId)\n await executeCommand(executor, splitCommand, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to execute split step ${step.id}`,\n path: step.id,\n details: { command: splitCommand },\n })\n\n const panesAfter = await listPaneIds(executor, step)\n const newPaneId = ensureNonEmpty(findNewPaneId(panesBefore, panesAfter), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: \"Unable to determine newly created pane\",\n path: step.id,\n }),\n )\n\n const createdVirtualId = step.createdPaneId\n if (typeof createdVirtualId === \"string\" && createdVirtualId.length > 0) {\n registerPane(paneMap, createdVirtualId, newPaneId)\n }\n}\n\nexport const executeFocusStep = async ({\n step,\n executor,\n paneMap,\n}: {\n readonly step: CommandStep\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n}): Promise<void> => {\n const targetVirtualId = ensureNonEmpty(step.targetPaneId, () =>\n raiseExecutionError(ErrorCodes.MISSING_TARGET, {\n message: \"Focus step missing target pane metadata\",\n path: step.id,\n }),\n )\n\n const targetRealId = ensureNonEmpty(resolvePaneId(paneMap, targetVirtualId), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown focus pane: ${targetVirtualId}`,\n path: step.id,\n }),\n )\n\n const command = buildFocusCommand(targetRealId)\n await executeCommand(executor, command, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to execute focus step ${step.id}`,\n path: step.id,\n details: { command },\n })\n}\n\nexport const executeTerminalCommands = async ({\n terminals,\n executor,\n paneMap,\n focusPaneVirtualId,\n}: {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n readonly focusPaneVirtualId: string\n}): Promise<void> => {\n if (!paneMap.has(focusPaneVirtualId)) {\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown focus pane: ${focusPaneVirtualId}`,\n path: focusPaneVirtualId,\n })\n }\n ensureNonEmpty(resolvePaneId(paneMap, focusPaneVirtualId), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown focus pane: ${focusPaneVirtualId}`,\n path: focusPaneVirtualId,\n }),\n )\n\n const resolveRealPaneId = (virtualPaneId: string): string => {\n return ensureNonEmpty(resolvePaneId(paneMap, virtualPaneId), () =>\n raiseExecutionError(ErrorCodes.INVALID_PANE, {\n message: `Unknown terminal pane: ${virtualPaneId}`,\n path: virtualPaneId,\n }),\n )\n }\n\n const prepared = prepareTerminalCommands({\n terminals,\n focusPaneVirtualId,\n resolveRealPaneId,\n onTemplateTokenError: ({ terminal, error }): never => {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TEMPLATE_TOKEN_ERROR,\n message: `Template token resolution failed for pane ${terminal.virtualPaneId}: ${error.message}`,\n path: terminal.virtualPaneId,\n details: {\n command: terminal.command,\n tokenType: error.tokenType,\n availablePanes: error.availablePanes,\n },\n })\n },\n })\n\n for (const commandSet of prepared.commands) {\n const { terminal, realPaneId } = commandSet\n\n if (typeof commandSet.cwdCommand === \"string\") {\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, commandSet.cwdCommand, \"Enter\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to change directory for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { cwd: terminal.cwd },\n })\n }\n\n for (const envEntry of commandSet.envCommands) {\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, envEntry.command, \"Enter\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to set environment variable ${envEntry.key}`,\n path: terminal.virtualPaneId,\n })\n }\n\n if (typeof commandSet.title === \"string\") {\n await executeCommand(executor, [\"select-pane\", \"-t\", realPaneId, \"-T\", commandSet.title], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to set pane title for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { title: commandSet.title },\n })\n }\n\n if (commandSet.command !== undefined) {\n if (commandSet.command.delayMs > 0) {\n await waitForDelay(commandSet.command.delayMs)\n }\n\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, commandSet.command.text, \"Enter\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to execute command for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { command: terminal.command },\n })\n }\n }\n}\n\nexport const executeCommand = async (\n executor: CommandExecutor,\n command: string[],\n context: {\n readonly code: string\n readonly message: string\n readonly path: string\n readonly details?: Record<string, unknown>\n },\n): Promise<string> => {\n try {\n return await executor.execute([...command])\n } catch (error) {\n if (error instanceof Error && \"code\" in error && \"message\" in error) {\n const candidate = error as { code?: string; message?: string; details?: Record<string, unknown> }\n throw createCoreError(\"execution\", {\n code: typeof candidate.code === \"string\" ? candidate.code : context.code,\n message: candidate.message ?? context.message,\n path: context.path,\n details: candidate.details ?? context.details,\n })\n }\n\n throw createCoreError(\"execution\", {\n code: context.code,\n message: context.message,\n path: context.path,\n details: context.details,\n })\n }\n}\n\nexport const resolveCurrentPaneId = async ({\n executor,\n contextPath,\n isDryRun,\n}: {\n executor: CommandExecutor\n contextPath: string\n isDryRun: boolean\n}): Promise<string> => {\n const envPaneId = process.env.TMUX_PANE\n if (typeof envPaneId === \"string\" && envPaneId.trim().length > 0) {\n return normalizePaneId(envPaneId)\n }\n\n if (isDryRun) {\n return \"%0\"\n }\n\n const output = await executeCommand(executor, [\"display-message\", \"-p\", \"#{pane_id}\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to resolve current tmux pane\",\n path: contextPath,\n })\n\n const paneId = output.trim()\n if (paneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.NOT_IN_TMUX_SESSION,\n message: \"Unable to determine current tmux pane\",\n path: contextPath,\n })\n }\n\n return normalizePaneId(paneId)\n}\n\nexport const listWindowPaneIds = async (executor: CommandExecutor, contextPath: string): Promise<string[]> => {\n const output = await executeCommand(executor, [\"list-panes\", \"-F\", \"#{pane_id}\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to list tmux panes\",\n path: contextPath,\n })\n\n return output\n .split(\"\\n\")\n .map((pane) => pane.trim())\n .filter((pane) => pane.length > 0)\n}\n\nconst listPaneIds = async (executor: CommandExecutor, step: CommandStep): Promise<string[]> => {\n return listWindowPaneIds(executor, step.id)\n}\n\nconst findNewPaneId = (before: string[], after: string[]): string | undefined => {\n const beforeSet = new Set(before)\n return after.find((id) => !beforeSet.has(id))\n}\n\nconst buildSplitCommand = (step: CommandStep, targetRealId: string): string[] => {\n const directionFlag = resolveSplitOrientation(step) === \"horizontal\" ? \"-h\" : \"-v\"\n const percentage = resolveSplitPercentage(step)\n return [\"split-window\", directionFlag, \"-t\", targetRealId, \"-p\", percentage]\n}\n\nconst buildFocusCommand = (targetRealId: string): string[] => {\n return [\"select-pane\", \"-t\", targetRealId]\n}\n\nexport const normalizePaneId = (raw: string): string => {\n const trimmed = raw.trim()\n return trimmed.length === 0 ? \"%0\" : trimmed\n}\n\nexport const registerPane = (paneMap: Map<string, string>, virtualId: string, realId: string): void => {\n paneMap.set(virtualId, realId)\n}\n\nexport const resolvePaneId = (paneMap: Map<string, string>, virtualId: string): string | undefined => {\n return resolvePaneMapping(paneMap, virtualId)\n}\n\nconst ensureNonEmpty = <T extends string>(value: T | undefined, buildError: () => never): T => {\n if (value === undefined || value.length === 0) {\n return buildError()\n }\n return value\n}\n\nexport const raiseExecutionError = (\n code: string,\n error: {\n readonly message: string\n readonly path: string\n readonly details?: Record<string, unknown>\n },\n): never => {\n throw createCoreError(\"execution\", {\n code,\n message: error.message,\n path: error.path,\n details: error.details,\n })\n}\n","import type { PlanEmission } from \"../core/emitter\"\nimport type { ConfirmPaneClosure } from \"../contracts\"\nimport type { CommandExecutor } from \"../contracts\"\nimport { ErrorCodes } from \"../utils/errors\"\nimport type { WindowMode } from \"../models/types\"\nimport {\n executeCommand,\n executeFocusStep,\n executeSplitStep,\n executeTerminalCommands,\n listWindowPaneIds,\n normalizePaneId,\n raiseExecutionError,\n registerPane,\n resolveCurrentPaneId,\n resolvePaneId,\n} from \"./plan-runner-helpers\"\n\ntype ExecutePlanInput = {\n readonly emission: PlanEmission\n readonly executor: CommandExecutor\n readonly windowName?: string\n readonly windowMode: WindowMode\n readonly onConfirmKill?: ConfirmPaneClosure\n}\n\ntype ExecutePlanSuccess = {\n readonly executedSteps: number\n}\n\nexport const executePlan = async ({\n emission,\n executor,\n windowName,\n windowMode,\n onConfirmKill,\n}: ExecutePlanInput): Promise<ExecutePlanSuccess> => {\n const initialVirtualPaneId = emission.summary.initialPaneId\n if (typeof initialVirtualPaneId !== \"string\" || initialVirtualPaneId.length === 0) {\n raiseExecutionError(ErrorCodes.INVALID_PLAN, {\n message: \"Plan emission is missing initial pane metadata\",\n path: \"plan.initialPaneId\",\n })\n }\n\n const paneMap = new Map<string, string>()\n\n const isDryRun = executor.isDryRun()\n\n let initialPaneId: string\n\n if (windowMode === \"current-window\") {\n const currentPaneId = await resolveCurrentPaneId({\n executor,\n contextPath: initialVirtualPaneId,\n isDryRun,\n })\n\n const panesInWindow = await listWindowPaneIds(executor, initialVirtualPaneId)\n const panesToClose = panesInWindow.filter((paneId) => paneId !== currentPaneId)\n\n if (panesToClose.length > 0) {\n let confirmed = true\n if (onConfirmKill !== undefined) {\n confirmed = await onConfirmKill({ panesToClose, dryRun: isDryRun })\n }\n\n if (confirmed !== true) {\n raiseExecutionError(ErrorCodes.USER_CANCELLED, {\n message: \"Aborted layout application for current window\",\n path: initialVirtualPaneId,\n details: { panes: panesToClose },\n })\n }\n\n await executeCommand(executor, [\"kill-pane\", \"-a\", \"-t\", currentPaneId], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to close existing panes\",\n path: initialVirtualPaneId,\n details: { command: [\"kill-pane\", \"-a\", \"-t\", currentPaneId] },\n })\n }\n\n initialPaneId = normalizePaneId(currentPaneId)\n } else {\n const newWindowCommand: string[] = [\"new-window\", \"-P\", \"-F\", \"#{pane_id}\"]\n if (typeof windowName === \"string\" && windowName.trim().length > 0) {\n newWindowCommand.push(\"-n\", windowName.trim())\n }\n\n const createdPane = await executeCommand(executor, newWindowCommand, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to create tmux window\",\n path: initialVirtualPaneId,\n })\n initialPaneId = normalizePaneId(createdPane)\n }\n\n registerPane(paneMap, initialVirtualPaneId, initialPaneId)\n\n let executedSteps = 0\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n await executeSplitStep({ step, executor, paneMap })\n executedSteps += 1\n } else if (step.kind === \"focus\") {\n await executeFocusStep({ step, executor, paneMap })\n executedSteps += 1\n } else {\n raiseExecutionError(ErrorCodes.INVALID_PLAN, {\n message: `Unsupported step kind in emission: ${String((step as { kind?: unknown }).kind)}`,\n path: step.id,\n })\n }\n }\n\n await executeTerminalCommands({\n terminals: emission.terminals,\n executor,\n paneMap,\n focusPaneVirtualId: emission.summary.focusPaneId,\n })\n\n const finalRealFocus = resolvePaneId(paneMap, emission.summary.focusPaneId)\n if (typeof finalRealFocus === \"string\" && finalRealFocus.length > 0) {\n await executeCommand(executor, [\"select-pane\", \"-t\", finalRealFocus], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to restore focus\",\n path: emission.summary.focusPaneId,\n })\n }\n\n return { executedSteps }\n}\n","import type { CommandStep } from \"../core/emitter\"\nimport { createCoreError } from \"../core/errors\"\nimport { ErrorCodes } from \"../utils/errors\"\n\nconst getStepLabel = (step: CommandStep): string => {\n if (step.kind === \"split\") {\n return \"Split\"\n }\n if (step.kind === \"focus\") {\n return \"Focus\"\n }\n return \"Step\"\n}\n\nexport const resolveRequiredStepTargetPaneId = (step: CommandStep): string => {\n if (typeof step.targetPaneId === \"string\" && step.targetPaneId.length > 0) {\n return step.targetPaneId\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.MISSING_TARGET,\n message: `${getStepLabel(step)} step missing target pane metadata`,\n path: step.id,\n })\n}\n","import { createCoreError } from \"../core/errors\"\nimport type { CoreError } from \"../core/errors\"\nimport { ErrorCodes } from \"../utils/errors\"\n\ntype UnsupportedStep = {\n readonly id: string\n readonly kind?: unknown\n}\n\nexport const createUnsupportedStepKindError = (step: UnsupportedStep): CoreError => {\n return createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: `Unsupported step kind in emission: ${String(step.kind)}`,\n path: step.id,\n })\n}\n","import { createTmuxExecutor } from \"./executor\"\nimport type { CommandStep, PlanEmission } from \"../../core/emitter\"\nimport { executePlan } from \"../../executor/plan-runner\"\nimport {\n resolveSplitOrientation as resolveSplitOrientationFromStep,\n resolveSplitPercentage as resolveSplitPercentageFromStep,\n} from \"../../executor/split-step\"\nimport { resolveRequiredStepTargetPaneId } from \"../../executor/step-target\"\nimport { createUnsupportedStepKindError } from \"../../executor/unsupported-step-kind\"\nimport type {\n ApplyPlanParameters,\n ApplyPlanResult,\n DryRunStep,\n TerminalBackend,\n TmuxTerminalBackendContext,\n} from \"../../executor/terminal-backend\"\n\nexport const createTmuxBackend = (context: TmuxTerminalBackendContext): TerminalBackend => {\n const tmuxExecutor = createTmuxExecutor({\n executor: context.executor,\n verbose: context.verbose,\n dryRun: context.dryRun,\n })\n\n const buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n return emission.steps.map((step) => ({\n backend: \"tmux\" as const,\n summary: step.summary,\n command: tmuxExecutor.getCommandString(buildTmuxCommand(step)),\n }))\n }\n\n const verifyEnvironment = async (): Promise<void> => {\n if (context.dryRun) {\n return\n }\n await tmuxExecutor.verifyTmuxEnvironment()\n }\n\n const applyPlan = async ({ emission, windowMode, windowName }: ApplyPlanParameters): Promise<ApplyPlanResult> => {\n const executionResult = await executePlan({\n emission,\n executor: tmuxExecutor.getExecutor(),\n windowMode,\n windowName,\n onConfirmKill: context.prompt,\n })\n\n return {\n executedSteps: executionResult.executedSteps,\n focusPaneId: emission.summary.focusPaneId,\n }\n }\n\n return {\n verifyEnvironment,\n applyPlan,\n getDryRunSteps: buildDryRunSteps,\n }\n}\n\nconst buildTmuxCommand = (step: CommandStep): string[] => {\n if (step.kind === \"split\") {\n const target = resolveRequiredStepTargetPaneId(step)\n const direction = resolveSplitOrientationFromStep(step) === \"horizontal\" ? \"-h\" : \"-v\"\n const percent = resolveSplitPercentageFromStep(step)\n return [\"split-window\", direction, \"-t\", target, \"-p\", percent]\n }\n\n if (step.kind === \"focus\") {\n const target = resolveRequiredStepTargetPaneId(step)\n return [\"select-pane\", \"-t\", target]\n }\n\n throw createUnsupportedStepKindError(step)\n}\n","type WeztermListPane = {\n readonly paneId: string\n readonly isActive: boolean\n}\n\ntype WeztermListTab = {\n readonly tabId: string\n readonly isActive: boolean\n readonly panes: ReadonlyArray<WeztermListPane>\n}\n\nexport type WeztermListWindow = {\n readonly windowId: string\n readonly isActive: boolean\n readonly workspace?: string\n readonly tabs: ReadonlyArray<WeztermListTab>\n}\n\nexport type WeztermListResult = {\n readonly windows: ReadonlyArray<WeztermListWindow>\n}\n\ntype RawListPane = {\n readonly pane_id?: number | string\n readonly is_active?: unknown\n}\n\ntype RawListTab = {\n readonly tab_id?: number | string\n readonly is_active?: unknown\n readonly panes?: RawListPane[]\n}\n\ntype RawListWindow = {\n readonly window_id?: number | string\n readonly is_active?: unknown\n readonly workspace?: unknown\n readonly tabs?: RawListTab[]\n}\n\ntype RawListEntry = {\n readonly window_id?: number | string\n readonly tab_id?: number | string\n readonly pane_id?: number | string\n readonly workspace?: unknown\n readonly is_active?: unknown\n}\n\ntype RawListResult = {\n readonly windows?: RawListWindow[]\n}\n\nconst toIdString = (value: unknown): string | undefined => {\n if (typeof value === \"string\") {\n return value\n }\n if (typeof value === \"number\") {\n return value.toString()\n }\n return undefined\n}\n\nconst isNonEmptyString = (value: string | undefined): value is string => {\n return typeof value === \"string\" && value.length > 0\n}\n\nconst toWorkspaceString = (value: unknown): string | undefined => {\n if (typeof value === \"string\" && value.length > 0) {\n return value\n }\n return undefined\n}\n\ntype MutableTabRecord = {\n tabId: string\n isActive: boolean\n panes: WeztermListPane[]\n}\n\ntype MutableWindowRecord = {\n windowId: string\n isActive: boolean\n workspace?: string\n tabs: Map<string, MutableTabRecord>\n}\n\ntype NormalizedArrayEntry = {\n windowId: string\n tabId: string\n paneId: string\n workspace?: string\n isActive: boolean\n}\n\nconst toImmutablePanes = (panes: ReadonlyArray<WeztermListPane>): WeztermListPane[] => {\n return panes.map(\n (pane): WeztermListPane => ({\n paneId: pane.paneId,\n isActive: pane.isActive,\n }),\n )\n}\n\nconst toImmutableTabs = (tabs: ReadonlyMap<string, MutableTabRecord>): WeztermListTab[] => {\n return Array.from(tabs.values()).map(\n (tabRecord): WeztermListTab => ({\n tabId: tabRecord.tabId,\n isActive: tabRecord.isActive,\n panes: toImmutablePanes(tabRecord.panes),\n }),\n )\n}\n\nconst toImmutableWindows = (windows: ReadonlyMap<string, MutableWindowRecord>): WeztermListWindow[] => {\n return Array.from(windows.values()).map(\n (windowRecord): WeztermListWindow => ({\n windowId: windowRecord.windowId,\n isActive: windowRecord.isActive,\n workspace: windowRecord.workspace,\n tabs: toImmutableTabs(windowRecord.tabs),\n }),\n )\n}\n\nconst normalizeArrayEntry = (entry: unknown): NormalizedArrayEntry | undefined => {\n if (typeof entry !== \"object\" || entry === null) {\n return undefined\n }\n const listEntry = entry as RawListEntry\n const windowIdRaw = toIdString(listEntry.window_id)\n const paneIdRaw = toIdString(listEntry.pane_id)\n const tabIdRaw = toIdString(listEntry.tab_id) ?? windowIdRaw\n if (!isNonEmptyString(windowIdRaw) || !isNonEmptyString(tabIdRaw) || !isNonEmptyString(paneIdRaw)) {\n return undefined\n }\n return {\n windowId: windowIdRaw,\n tabId: tabIdRaw,\n paneId: paneIdRaw,\n workspace: toWorkspaceString(listEntry.workspace),\n isActive: listEntry.is_active === true,\n }\n}\n\nconst getOrCreateWindowRecord = (\n windows: Map<string, MutableWindowRecord>,\n entry: NormalizedArrayEntry,\n): MutableWindowRecord => {\n const existingWindow = windows.get(entry.windowId)\n if (existingWindow) {\n if (entry.workspace !== undefined && existingWindow.workspace === undefined) {\n existingWindow.workspace = entry.workspace\n }\n return existingWindow\n }\n const createdWindow: MutableWindowRecord = {\n windowId: entry.windowId,\n isActive: false,\n workspace: entry.workspace,\n tabs: new Map(),\n }\n windows.set(entry.windowId, createdWindow)\n return createdWindow\n}\n\nconst getOrCreateTabRecord = (windowRecord: MutableWindowRecord, tabId: string): MutableTabRecord => {\n const existingTab = windowRecord.tabs.get(tabId)\n if (existingTab) {\n return existingTab\n }\n const createdTab: MutableTabRecord = {\n tabId,\n isActive: false,\n panes: [],\n }\n windowRecord.tabs.set(tabId, createdTab)\n return createdTab\n}\n\nconst parseArrayResponse = (parsed: unknown): WeztermListResult | undefined => {\n if (!Array.isArray(parsed)) {\n return undefined\n }\n\n const windowMap = new Map<string, MutableWindowRecord>()\n for (const entry of parsed) {\n const normalizedEntry = normalizeArrayEntry(entry)\n if (!normalizedEntry) {\n continue\n }\n\n const windowRecord = getOrCreateWindowRecord(windowMap, normalizedEntry)\n const tabRecord = getOrCreateTabRecord(windowRecord, normalizedEntry.tabId)\n\n windowRecord.isActive ||= normalizedEntry.isActive\n tabRecord.isActive ||= normalizedEntry.isActive\n tabRecord.panes.push({\n paneId: normalizedEntry.paneId,\n isActive: normalizedEntry.isActive,\n })\n }\n\n return { windows: toImmutableWindows(windowMap) }\n}\n\nconst parseObjectPane = (pane: unknown): WeztermListPane | undefined => {\n if (typeof pane !== \"object\" || pane === null) {\n return undefined\n }\n const rawPane = pane as RawListPane\n const paneIdRaw = toIdString(rawPane.pane_id)\n if (!isNonEmptyString(paneIdRaw)) {\n return undefined\n }\n return {\n paneId: paneIdRaw,\n isActive: rawPane.is_active === true,\n }\n}\n\nconst parseObjectTab = (tab: unknown): WeztermListTab | undefined => {\n if (typeof tab !== \"object\" || tab === null) {\n return undefined\n }\n const rawTab = tab as RawListTab\n const tabIdRaw = toIdString(rawTab.tab_id)\n if (!isNonEmptyString(tabIdRaw)) {\n return undefined\n }\n\n const paneRecords = Array.isArray(rawTab.panes) ? rawTab.panes : []\n const panes: WeztermListPane[] = []\n for (const pane of paneRecords) {\n const mappedPane = parseObjectPane(pane)\n if (mappedPane) {\n panes.push(mappedPane)\n }\n }\n\n return {\n tabId: tabIdRaw,\n isActive: rawTab.is_active === true,\n panes,\n }\n}\n\nconst parseObjectWindow = (window: unknown): WeztermListWindow | undefined => {\n if (typeof window !== \"object\" || window === null) {\n return undefined\n }\n const rawWindow = window as RawListWindow\n const windowIdRaw = toIdString(rawWindow.window_id)\n if (!isNonEmptyString(windowIdRaw)) {\n return undefined\n }\n\n const tabs: WeztermListTab[] = []\n const rawTabs = Array.isArray(rawWindow.tabs) ? rawWindow.tabs : []\n for (const tab of rawTabs) {\n const mappedTab = parseObjectTab(tab)\n if (mappedTab) {\n tabs.push(mappedTab)\n }\n }\n\n return {\n windowId: windowIdRaw,\n isActive: rawWindow.is_active === true,\n workspace: toWorkspaceString(rawWindow.workspace),\n tabs,\n }\n}\n\nconst parseObjectResponse = (parsed: unknown): WeztermListResult | undefined => {\n if (typeof parsed !== \"object\" || parsed === null) {\n return undefined\n }\n\n const candidate = parsed as Partial<RawListResult>\n const rawWindows = Array.isArray(candidate.windows) ? candidate.windows : []\n const windows: WeztermListWindow[] = []\n for (const window of rawWindows) {\n const mappedWindow = parseObjectWindow(window)\n if (mappedWindow) {\n windows.push(mappedWindow)\n }\n }\n return { windows }\n}\n\nexport const parseWeztermListResult = (stdout: string): WeztermListResult | undefined => {\n try {\n const parsed: unknown = JSON.parse(stdout)\n return parseArrayResponse(parsed) ?? parseObjectResponse(parsed)\n } catch {\n return undefined\n }\n}\n","import { execa } from \"execa\"\nimport { createEnvironmentError, ErrorCodes } from \"../../utils/errors\"\nimport { createCoreError } from \"../../core/errors\"\nimport { parseWeztermListResult, type WeztermListResult } from \"./list-parser\"\n\nexport type { WeztermListResult } from \"./list-parser\"\n\nconst WEZTERM_BINARY = \"wezterm\"\nconst MINIMUM_VERSION = \"20220624-141144-bd1b7c5d\"\nconst VERSION_REGEX = /(\\d{8})-(\\d{6})-([0-9a-fA-F]+)/i\n\ntype ExecaLikeError = Error & {\n readonly exitCode?: number\n readonly code?: string\n readonly stderr?: string\n readonly stdout?: string\n}\n\nexport const verifyWeztermAvailability = async (): Promise<{ version: string }> => {\n let stdout: string\n try {\n const result = await execa(WEZTERM_BINARY, [\"--version\"])\n stdout = result.stdout\n } catch (error) {\n const execaError = error as ExecaLikeError\n if (execaError.code === \"ENOENT\") {\n throw createEnvironmentError(\"wezterm is not installed\", ErrorCodes.BACKEND_NOT_FOUND, {\n backend: \"wezterm\",\n binary: WEZTERM_BINARY,\n })\n }\n throw createEnvironmentError(\"Failed to execute wezterm --version\", ErrorCodes.WEZTERM_NOT_FOUND, {\n backend: \"wezterm\",\n binary: WEZTERM_BINARY,\n stderr: execaError.stderr,\n })\n }\n\n const detectedVersion = extractVersion(stdout)\n if (detectedVersion === undefined) {\n throw createEnvironmentError(\"Unable to determine wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n requiredVersion: MINIMUM_VERSION,\n detectedVersion: stdout.trim(),\n })\n }\n\n if (!isVersionSupported(detectedVersion, MINIMUM_VERSION)) {\n throw createEnvironmentError(\"Unsupported wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n requiredVersion: MINIMUM_VERSION,\n detectedVersion,\n })\n }\n\n return { version: detectedVersion }\n}\n\nexport type RunWeztermErrorContext = {\n readonly message: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n}\n\nexport const runWeztermCli = async (args: string[], errorContext: RunWeztermErrorContext): Promise<string> => {\n try {\n const result = await execa(WEZTERM_BINARY, [\"cli\", ...args])\n return result.stdout\n } catch (error) {\n const execaError = error as ExecaLikeError\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: errorContext.message,\n path: errorContext.path,\n details: {\n command: [WEZTERM_BINARY, \"cli\", ...args],\n stderr: execaError.stderr,\n exitCode: execaError.exitCode,\n backend: \"wezterm\",\n ...(errorContext.details ?? {}),\n },\n })\n }\n}\n\nexport const listWeztermWindows = async (): Promise<WeztermListResult> => {\n const stdout = await runWeztermCli([\"list\", \"--format\", \"json\"], { message: \"Failed to list wezterm panes\" })\n const result = parseWeztermListResult(stdout)\n if (result === undefined) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"Invalid wezterm list output\",\n details: { stdout },\n })\n }\n return result\n}\n\nexport const killWeztermPane = async (paneId: string): Promise<void> => {\n await runWeztermCli([\"kill-pane\", \"--pane-id\", paneId], {\n message: `Failed to kill wezterm pane ${paneId}`,\n path: paneId,\n })\n}\n\nconst extractVersion = (raw: string): string | undefined => {\n const match = raw.match(VERSION_REGEX)\n if (!match) {\n return undefined\n }\n const date = match[1]\n const time = match[2]\n const commit = match[3]\n if (date === undefined || time === undefined || commit === undefined) {\n return undefined\n }\n return `${date}-${time}-${commit.toLowerCase()}`\n}\n\nconst isVersionSupported = (detected: string, minimum: string): boolean => {\n const parse = (version: string): { build: number; commit: string } | undefined => {\n const match = version.match(VERSION_REGEX)\n if (!match) {\n return undefined\n }\n const date = match[1]\n const time = match[2]\n const commit = match[3]\n if (date === undefined || time === undefined || commit === undefined) {\n return undefined\n }\n const build = Number(`${date}${time}`)\n if (Number.isNaN(build)) {\n return undefined\n }\n return { build, commit: commit.toLowerCase() }\n }\n\n const detectedInfo = parse(detected)\n const minimumInfo = parse(minimum)\n if (detectedInfo === undefined || minimumInfo === undefined) {\n return false\n }\n\n if (detectedInfo.build > minimumInfo.build) {\n return true\n }\n if (detectedInfo.build < minimumInfo.build) {\n return false\n }\n\n return detectedInfo.commit >= minimumInfo.commit\n}\n","import type { PlanEmission } from \"../../core/emitter\"\nimport { createCoreError } from \"../../core/errors\"\nimport { resolveSplitOrientation, resolveSplitPercentage } from \"../../executor/split-step\"\nimport { resolveRequiredStepTargetPaneId } from \"../../executor/step-target\"\nimport { prepareTerminalCommands } from \"../../executor/terminal-command-preparation\"\nimport type { DryRunStep } from \"../../executor/terminal-backend\"\nimport { ErrorCodes } from \"../../utils/errors\"\n\nconst SINGLE_QUOTE = \"'\"\nconst SHELL_SINGLE_QUOTE_ESCAPE = `'\"'\"'`\n\nexport const buildSplitArguments = (params: {\n readonly targetPaneId: string\n readonly percent: string\n readonly horizontal: boolean\n}): string[] => {\n const directionFlag = params.horizontal ? \"--right\" : \"--bottom\"\n return [\"split-pane\", directionFlag, \"--percent\", params.percent, \"--pane-id\", params.targetPaneId]\n}\n\nexport const buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n const steps: DryRunStep[] = []\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n const target = resolveRequiredStepTargetPaneId(step)\n const args = buildSplitArguments({\n targetPaneId: target,\n percent: resolveSplitPercentage(step),\n horizontal: resolveSplitOrientation(step) === \"horizontal\",\n })\n steps.push({\n backend: \"wezterm\",\n summary: step.summary,\n command: `wezterm cli ${args.join(\" \")}`,\n })\n continue\n }\n\n if (step.kind === \"focus\") {\n const target = resolveRequiredStepTargetPaneId(step)\n steps.push({\n backend: \"wezterm\",\n summary: step.summary,\n command: `wezterm cli activate-pane --pane-id ${target}`,\n })\n continue\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: `Unsupported step kind in emission: ${String((step as { kind?: unknown }).kind)}`,\n path: step.id,\n })\n }\n\n const prepared = prepareTerminalCommands({\n terminals: emission.terminals,\n focusPaneVirtualId: emission.summary.focusPaneId,\n resolveRealPaneId: (virtualPaneId: string): string => virtualPaneId,\n onTemplateTokenError: ({ terminal, error }): never => {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TEMPLATE_TOKEN_ERROR,\n message: `Template token resolution failed for pane ${terminal.virtualPaneId}: ${error.message}`,\n path: terminal.virtualPaneId,\n details: {\n command: terminal.command,\n tokenType: error.tokenType,\n availablePanes: error.availablePanes,\n },\n })\n },\n })\n\n const quoteForShellDisplay = (value: string): string => {\n return `${SINGLE_QUOTE}${value.split(SINGLE_QUOTE).join(SHELL_SINGLE_QUOTE_ESCAPE)}${SINGLE_QUOTE}`\n }\n\n for (const commandSet of prepared.commands) {\n const paneId = commandSet.terminal.virtualPaneId\n if (typeof commandSet.cwdCommand === \"string\") {\n steps.push({\n backend: \"wezterm\",\n summary: `set cwd for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- ${quoteForShellDisplay(commandSet.cwdCommand)}`,\n })\n }\n\n for (const envEntry of commandSet.envCommands) {\n steps.push({\n backend: \"wezterm\",\n summary: `set env ${envEntry.key} for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- ${quoteForShellDisplay(envEntry.command)}`,\n })\n }\n\n if (commandSet.command !== undefined) {\n steps.push({\n backend: \"wezterm\",\n summary: `run command for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- ${quoteForShellDisplay(commandSet.command.text)}`,\n })\n }\n }\n\n return steps\n}\n","import { createCoreError } from \"../../core/errors\"\nimport type { WindowMode } from \"../../models/types\"\nimport type { ConfirmPaneClosure } from \"../../contracts\"\nimport { waitForDelay } from \"../../utils/async\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport { killWeztermPane, type WeztermListResult } from \"./cli\"\nimport type { ExecuteWeztermCommand, ListWeztermWindows } from \"./shared\"\n\nconst PANE_REGISTRATION_RETRIES = 5\nconst PANE_REGISTRATION_DELAY_MS = 100\n\ntype InitialPaneResolution = {\n readonly paneId: string\n readonly windowId: string\n}\n\ntype CurrentWindowResolution = InitialPaneResolution & {\n readonly panesToClose: ReadonlyArray<string>\n}\n\nconst resolveCurrentWindow = async (context: {\n readonly list: WeztermListResult\n readonly prompt?: ConfirmPaneClosure\n readonly dryRun: boolean\n readonly logCommand: (args: ReadonlyArray<string>) => void\n readonly preferredPaneId?: string\n}): Promise<CurrentWindowResolution> => {\n const hasPreferredPane = typeof context.preferredPaneId === \"string\" && context.preferredPaneId.length > 0\n const preferredPaneId = hasPreferredPane ? (context.preferredPaneId as string) : undefined\n const preferredWindowId =\n preferredPaneId !== undefined ? findWindowContainingPane(context.list, preferredPaneId) : undefined\n\n const activeWindow =\n (preferredWindowId !== undefined\n ? context.list.windows.find((window) => window.windowId === preferredWindowId)\n : undefined) ??\n context.list.windows.find((window) => window.isActive) ??\n context.list.windows[0]\n\n if (!activeWindow) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"No active wezterm window detected\",\n details: { hint: \"Launch wezterm and ensure a window is focused, or run with --new-window.\" },\n })\n }\n\n const activeTab =\n (preferredPaneId !== undefined\n ? activeWindow.tabs.find((tab) => tab.panes.some((pane) => pane.paneId === preferredPaneId))\n : undefined) ??\n activeWindow.tabs.find((tab) => tab.isActive) ??\n activeWindow.tabs[0]\n\n if (!activeTab) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"No active wezterm tab detected\",\n path: activeWindow.windowId,\n details: { hint: \"Ensure a wezterm tab is focused before using --current-window.\" },\n })\n }\n\n const activePane =\n (preferredPaneId !== undefined ? activeTab.panes.find((pane) => pane.paneId === preferredPaneId) : undefined) ??\n activeTab.panes.find((pane) => pane.isActive) ??\n activeTab.panes[0]\n\n if (!activePane) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"No active wezterm pane detected\",\n path: activeTab.tabId,\n details: { hint: \"Ensure a wezterm pane is active before using --current-window.\" },\n })\n }\n\n const panesToClose = activeTab.panes.filter((pane) => pane.paneId !== activePane.paneId).map((pane) => pane.paneId)\n\n if (panesToClose.length > 0) {\n let confirmed = true\n if (context.prompt) {\n confirmed = await context.prompt({ panesToClose, dryRun: context.dryRun })\n }\n\n if (confirmed !== true) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.USER_CANCELLED,\n message: \"Aborted layout application for current wezterm window\",\n path: activePane.paneId,\n details: { panes: panesToClose },\n })\n }\n\n for (const paneId of panesToClose) {\n context.logCommand([\"kill-pane\", \"--pane-id\", paneId])\n await killWeztermPane(paneId)\n }\n }\n\n return {\n paneId: activePane.paneId,\n windowId: activeWindow.windowId,\n panesToClose,\n }\n}\n\nconst findActiveWindow = (\n list: WeztermListResult,\n): { windowId: string; tabs: (typeof list.windows)[number][\"tabs\"] } | undefined => {\n return list.windows.find((window) => window.isActive) ?? list.windows[0]\n}\n\nconst findWindowContainingPane = (list: WeztermListResult, paneId: string): string | undefined => {\n for (const window of list.windows) {\n for (const tab of window.tabs) {\n for (const pane of tab.panes) {\n if (pane.paneId === paneId) {\n return window.windowId\n }\n }\n }\n }\n return undefined\n}\n\nexport const findWorkspaceForPane = (list: WeztermListResult, paneId: string): string | undefined => {\n for (const window of list.windows) {\n for (const tab of window.tabs) {\n for (const pane of tab.panes) {\n if (pane.paneId === paneId) {\n return window.workspace\n }\n }\n }\n }\n return undefined\n}\n\nconst filterWindowsByWorkspace = (list: WeztermListResult, workspace?: string): WeztermListResult => {\n if (workspace === undefined || workspace.length === 0) {\n return list\n }\n const scoped = list.windows.filter((window) => window.workspace === workspace)\n if (scoped.length === 0) {\n return list\n }\n return { windows: scoped }\n}\n\nexport const collectPaneIdsForWindow = (list: WeztermListResult, windowId: string): Set<string> => {\n const targetWindow = list.windows.find((window) => window.windowId === windowId)\n if (!targetWindow) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: `Wezterm window ${windowId} not found`,\n details: { windowId },\n })\n }\n\n const paneIds = targetWindow.tabs.flatMap((tab) => tab.panes.map((pane) => pane.paneId))\n return new Set(paneIds)\n}\n\nconst waitForPaneRegistration = async ({\n paneId,\n listWindows,\n windowHint,\n}: {\n readonly paneId: string\n readonly listWindows: ListWeztermWindows\n readonly windowHint?: string\n}): Promise<string> => {\n for (let attempt = 0; attempt < PANE_REGISTRATION_RETRIES; attempt += 1) {\n const snapshot = await listWindows()\n\n if (typeof windowHint === \"string\") {\n try {\n const panes = collectPaneIdsForWindow(snapshot, windowHint)\n if (panes.has(paneId)) {\n return windowHint\n }\n } catch {\n // window may not be ready yet; fall through to global search.\n }\n }\n\n const located = findWindowContainingPane(snapshot, paneId)\n if (typeof located === \"string\" && located.length > 0) {\n return located\n }\n\n if (attempt < PANE_REGISTRATION_RETRIES - 1) {\n await waitForDelay(PANE_REGISTRATION_DELAY_MS)\n }\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"Unable to locate spawned wezterm window\",\n details: { paneId, hint: \"Verify that wezterm is running and the CLI client can connect.\" },\n })\n}\n\nconst extractSpawnPaneId = (output: string): string => {\n const trimmed = output.trim()\n if (trimmed.length === 0) {\n return \"\"\n }\n\n const lastLine = trimmed.split(\"\\n\").pop() ?? \"\"\n const tokens = lastLine.split(/\\s+/).filter((segment) => segment.length > 0)\n if (tokens.length === 0) {\n return \"\"\n }\n // wezterm cli spawn outputs pane-id first, followed by optional window or tab metadata\n const [paneId] = tokens\n if (typeof paneId !== \"string\") {\n return \"\"\n }\n return paneId.trim()\n}\n\nexport const resolveInitialPane = async ({\n windowMode,\n prompt,\n dryRun,\n listWindows,\n runCommand,\n logCommand,\n initialCwd,\n workspaceHint,\n initialList,\n preferredPaneId,\n}: {\n readonly windowMode: WindowMode\n readonly prompt?: ConfirmPaneClosure\n readonly dryRun: boolean\n readonly listWindows: ListWeztermWindows\n readonly runCommand: ExecuteWeztermCommand\n readonly logCommand: (args: ReadonlyArray<string>) => void\n readonly initialCwd?: string\n readonly workspaceHint?: string\n readonly initialList?: WeztermListResult\n readonly preferredPaneId?: string\n}): Promise<InitialPaneResolution> => {\n const hasPreferredPane = typeof preferredPaneId === \"string\" && preferredPaneId.length > 0\n const preferredPaneIdValue = hasPreferredPane ? (preferredPaneId as string) : undefined\n\n if (windowMode === \"current-window\") {\n const snapshot = initialList ?? (await listWindows())\n const scoped = filterWindowsByWorkspace(snapshot, workspaceHint)\n return resolveCurrentWindow({ list: scoped, prompt, dryRun, logCommand, preferredPaneId: preferredPaneIdValue })\n }\n\n const existingSnapshot = initialList ?? (await listWindows())\n const scopedExisting = filterWindowsByWorkspace(existingSnapshot, workspaceHint)\n const scopedPreferredWindowId =\n preferredPaneIdValue !== undefined ? findWindowContainingPane(scopedExisting, preferredPaneIdValue) : undefined\n const activeWindow =\n (scopedPreferredWindowId !== undefined\n ? scopedExisting.windows.find((window) => window.windowId === scopedPreferredWindowId)\n : undefined) ?? findActiveWindow(scopedExisting)\n\n if (activeWindow) {\n const args = [\"spawn\", \"--window-id\", activeWindow.windowId] as string[]\n if (typeof initialCwd === \"string\" && initialCwd.length > 0) {\n args.push(\"--cwd\", initialCwd)\n }\n const spawnOutput = await runCommand(args, {\n message: \"Failed to spawn wezterm tab\",\n })\n const paneId = extractSpawnPaneId(spawnOutput)\n if (paneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"wezterm spawn did not return a pane id\",\n details: { stdout: spawnOutput },\n })\n }\n const windowId = await waitForPaneRegistration({\n paneId,\n listWindows,\n windowHint: activeWindow.windowId,\n })\n return { paneId, windowId }\n }\n\n const args = [\"spawn\", \"--new-window\"] as string[]\n if (typeof initialCwd === \"string\" && initialCwd.length > 0) {\n args.push(\"--cwd\", initialCwd)\n }\n if (typeof workspaceHint === \"string\" && workspaceHint.length > 0) {\n args.push(\"--workspace\", workspaceHint)\n }\n const spawnOutput = await runCommand(args, {\n message: \"Failed to spawn wezterm window\",\n })\n const paneId = extractSpawnPaneId(spawnOutput)\n if (paneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"wezterm spawn did not return a pane id\",\n details: { stdout: spawnOutput },\n })\n }\n\n const newWindowId = await waitForPaneRegistration({\n paneId,\n listWindows,\n })\n return { paneId, windowId: newWindowId }\n}\n","import { createCoreError } from \"../../core/errors\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport { resolvePaneMapping } from \"../../utils/pane-map\"\nimport type { PaneMap } from \"./shared\"\n\nexport const registerPaneWithAncestors = (map: PaneMap, virtualId: string, realId: string): void => {\n map.set(virtualId, realId)\n\n let ancestor = virtualId\n while (ancestor.includes(\".\")) {\n ancestor = ancestor.slice(0, ancestor.lastIndexOf(\".\"))\n if (!map.has(ancestor)) {\n map.set(ancestor, realId)\n } else {\n break\n }\n }\n}\n\nexport const resolveRealPaneId = (\n paneMap: PaneMap,\n virtualId: string,\n context: { readonly stepId: string },\n): string => {\n const resolved = resolvePaneMapping(paneMap, virtualId)\n if (typeof resolved === \"string\" && resolved.length > 0) {\n return resolved\n }\n\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: `Unknown wezterm pane mapping for ${virtualId}`,\n path: context.stepId,\n })\n}\n","import type { CommandStep, EmittedTerminal } from \"../../core/emitter\"\nimport { createCoreError } from \"../../core/errors\"\nimport { resolveSplitOrientation, resolveSplitPercentage } from \"../../executor/split-step\"\nimport { prepareTerminalCommands } from \"../../executor/terminal-command-preparation\"\nimport { waitForDelay } from \"../../utils/async\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport { buildSplitArguments } from \"./dry-run\"\nimport { collectPaneIdsForWindow } from \"./layout-resolution\"\nimport { registerPaneWithAncestors, resolveRealPaneId } from \"./pane-map\"\nimport type { ExecuteWeztermCommand, ListWeztermWindows, LogPaneMapping, PaneMap } from \"./shared\"\n\nconst findNewPaneId = (before: Set<string>, after: Set<string>): string | undefined => {\n for (const paneId of after) {\n if (!before.has(paneId)) {\n return paneId\n }\n }\n return undefined\n}\n\nconst appendCarriageReturn = (value: string): string => {\n return value.endsWith(\"\\r\") ? value : `${value}\\r`\n}\n\nconst sendTextToPane = async ({\n paneId,\n text,\n runCommand,\n context,\n}: {\n readonly paneId: string\n readonly text: string\n readonly runCommand: ExecuteWeztermCommand\n readonly context: { readonly message: string; readonly path: string; readonly details?: Record<string, unknown> }\n}): Promise<void> => {\n await runCommand([\"send-text\", \"--pane-id\", paneId, \"--no-paste\", \"--\", appendCarriageReturn(text)], context)\n}\n\nexport const applyFocusStep = async ({\n step,\n paneMap,\n runCommand,\n}: {\n readonly step: CommandStep\n readonly paneMap: PaneMap\n readonly runCommand: ExecuteWeztermCommand\n}): Promise<void> => {\n const targetVirtualId = step.targetPaneId\n if (typeof targetVirtualId !== \"string\" || targetVirtualId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: \"Focus step missing target pane metadata\",\n path: step.id,\n })\n }\n\n const targetRealId = resolveRealPaneId(paneMap, targetVirtualId, { stepId: step.id })\n\n await runCommand([\"activate-pane\", \"--pane-id\", targetRealId], {\n message: `Failed to execute focus step ${step.id}`,\n path: step.id,\n })\n}\n\nexport const applySplitStep = async ({\n step,\n paneMap,\n windowId,\n runCommand,\n listWindows,\n logPaneMapping,\n}: {\n readonly step: CommandStep\n readonly paneMap: PaneMap\n readonly windowId: string\n readonly runCommand: ExecuteWeztermCommand\n readonly listWindows: ListWeztermWindows\n readonly logPaneMapping: LogPaneMapping\n}): Promise<void> => {\n const targetVirtualId = step.targetPaneId\n if (typeof targetVirtualId !== \"string\" || targetVirtualId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: \"Split step missing target pane metadata\",\n path: step.id,\n })\n }\n\n const targetRealId = resolveRealPaneId(paneMap, targetVirtualId, { stepId: step.id })\n\n const beforeList = await listWindows()\n const beforePaneIds = collectPaneIdsForWindow(beforeList, windowId)\n\n const args = buildSplitArguments({\n targetPaneId: targetRealId,\n percent: resolveSplitPercentage(step),\n horizontal: resolveSplitOrientation(step) === \"horizontal\",\n })\n\n await runCommand(args, {\n message: `Failed to execute split step ${step.id}`,\n path: step.id,\n })\n\n const afterList = await listWindows()\n const afterPaneIds = collectPaneIdsForWindow(afterList, windowId)\n\n const newPaneId = findNewPaneId(beforePaneIds, afterPaneIds)\n if (typeof newPaneId !== \"string\" || newPaneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"Unable to determine newly created wezterm pane\",\n path: step.id,\n })\n }\n\n if (typeof step.createdPaneId === \"string\" && step.createdPaneId.length > 0) {\n registerPaneWithAncestors(paneMap, step.createdPaneId, newPaneId)\n logPaneMapping(step.createdPaneId, newPaneId)\n }\n}\n\nexport const applyTerminalCommands = async ({\n terminals,\n paneMap,\n runCommand,\n focusPaneVirtualId,\n}: {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly paneMap: PaneMap\n readonly runCommand: ExecuteWeztermCommand\n readonly focusPaneVirtualId: string\n}): Promise<void> => {\n if (!paneMap.has(focusPaneVirtualId)) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: `Unknown focus pane: ${focusPaneVirtualId}`,\n path: focusPaneVirtualId,\n })\n }\n\n const prepared = prepareTerminalCommands({\n terminals,\n focusPaneVirtualId,\n resolveRealPaneId: (virtualPaneId: string): string =>\n resolveRealPaneId(paneMap, virtualPaneId, {\n stepId: virtualPaneId,\n }),\n onTemplateTokenError: ({ terminal, error }): never => {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.TEMPLATE_TOKEN_ERROR,\n message: `Template token resolution failed for pane ${terminal.virtualPaneId}: ${error.message}`,\n path: terminal.virtualPaneId,\n details: {\n command: terminal.command,\n tokenType: error.tokenType,\n availablePanes: error.availablePanes,\n },\n })\n },\n })\n\n for (const commandSet of prepared.commands) {\n const { terminal, realPaneId } = commandSet\n\n if (typeof commandSet.cwdCommand === \"string\") {\n await sendTextToPane({\n paneId: realPaneId,\n text: commandSet.cwdCommand,\n runCommand,\n context: {\n message: `Failed to change directory for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { cwd: terminal.cwd },\n },\n })\n }\n\n for (const envEntry of commandSet.envCommands) {\n await sendTextToPane({\n paneId: realPaneId,\n text: envEntry.command,\n runCommand,\n context: {\n message: `Failed to set environment variable ${envEntry.key}`,\n path: terminal.virtualPaneId,\n },\n })\n }\n\n if (commandSet.command !== undefined) {\n if (commandSet.command.delayMs > 0) {\n await waitForDelay(commandSet.command.delayMs)\n }\n\n await sendTextToPane({\n paneId: realPaneId,\n text: commandSet.command.text,\n runCommand,\n context: {\n message: `Failed to execute command for pane ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n details: { command: terminal.command },\n },\n })\n }\n }\n}\n","import type { PlanEmission } from \"../../core/emitter\"\nimport { createCoreError } from \"../../core/errors\"\nimport type {\n ApplyPlanParameters,\n ApplyPlanResult,\n TerminalBackend,\n WeztermTerminalBackendContext,\n} from \"../../executor/terminal-backend\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport { listWeztermWindows, runWeztermCli, verifyWeztermAvailability, type WeztermListResult } from \"./cli\"\nimport { buildDryRunSteps } from \"./dry-run\"\nimport { findWorkspaceForPane, resolveInitialPane } from \"./layout-resolution\"\nimport { registerPaneWithAncestors } from \"./pane-map\"\nimport { applyFocusStep, applySplitStep, applyTerminalCommands } from \"./step-execution\"\nimport type { ExecuteWeztermCommand, PaneMap } from \"./shared\"\n\nconst ensureVirtualPaneId = (emission: PlanEmission): string => {\n const { initialPaneId } = emission.summary\n if (typeof initialPaneId !== \"string\" || initialPaneId.length === 0) {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: \"Plan emission is missing initial pane metadata\",\n path: \"plan.initialPaneId\",\n })\n }\n return initialPaneId\n}\n\nexport const createWeztermBackend = (context: WeztermTerminalBackendContext): TerminalBackend => {\n const formatCommand = (args: ReadonlyArray<string>): string => {\n return `wezterm cli ${args.join(\" \")}`\n }\n\n const logCommand = (args: ReadonlyArray<string>): void => {\n const message = `[wezterm] ${formatCommand(args)}`\n if (context.verbose) {\n context.logger.info(message)\n } else {\n context.logger.debug(message)\n }\n }\n\n const logPaneMapping = (virtualId: string, realId: string): void => {\n const message = `[wezterm] pane ${virtualId} -> ${realId}`\n if (context.verbose) {\n context.logger.info(message)\n } else {\n context.logger.debug(message)\n }\n }\n\n const runCommand: ExecuteWeztermCommand = async (args, errorContext) => {\n const commandArgs = [...args]\n logCommand(commandArgs)\n return runWeztermCli(commandArgs, errorContext)\n }\n\n const listWindows = async (): Promise<WeztermListResult> => {\n logCommand([\"list\", \"--format\", \"json\"])\n return listWeztermWindows()\n }\n\n const verifyEnvironment = async (): Promise<void> => {\n if (context.dryRun) {\n return\n }\n await verifyWeztermAvailability()\n }\n\n const applyPlan = async ({ emission, windowMode }: ApplyPlanParameters): Promise<ApplyPlanResult> => {\n const initialVirtualPaneId = ensureVirtualPaneId(emission)\n const paneMap: PaneMap = new Map()\n const initialTerminal = emission.terminals.find((terminal) => terminal.virtualPaneId === initialVirtualPaneId)\n const initialCwd =\n typeof initialTerminal?.cwd === \"string\" && initialTerminal.cwd.length > 0 ? initialTerminal.cwd : context.cwd\n\n let cachedInitialList: WeztermListResult | undefined\n let workspaceHint: string | undefined\n if (typeof context.paneId === \"string\" && context.paneId.length > 0) {\n try {\n cachedInitialList = await listWindows()\n workspaceHint = findWorkspaceForPane(cachedInitialList, context.paneId)\n } catch {\n cachedInitialList = undefined\n workspaceHint = undefined\n }\n }\n\n const { paneId: initialPaneId, windowId } = await resolveInitialPane({\n windowMode,\n prompt: context.prompt,\n dryRun: context.dryRun,\n listWindows,\n runCommand,\n logCommand,\n initialCwd,\n workspaceHint,\n initialList: cachedInitialList,\n preferredPaneId: context.paneId,\n })\n registerPaneWithAncestors(paneMap, initialVirtualPaneId, initialPaneId)\n logPaneMapping(initialVirtualPaneId, initialPaneId)\n\n let executedSteps = 0\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n await applySplitStep({\n step,\n paneMap,\n windowId,\n runCommand,\n listWindows,\n logPaneMapping,\n })\n executedSteps += 1\n } else if (step.kind === \"focus\") {\n await applyFocusStep({\n step,\n paneMap,\n runCommand,\n })\n executedSteps += 1\n } else {\n throw createCoreError(\"execution\", {\n code: ErrorCodes.INVALID_PLAN,\n message: `Unsupported step kind in emission: ${String((step as { kind?: unknown }).kind)}`,\n path: step.id,\n })\n }\n }\n\n await applyTerminalCommands({\n terminals: emission.terminals,\n paneMap,\n runCommand,\n focusPaneVirtualId: emission.summary.focusPaneId,\n })\n\n const focusVirtual = emission.summary.focusPaneId\n const focusPaneId = typeof focusVirtual === \"string\" ? paneMap.get(focusVirtual) : undefined\n\n return {\n executedSteps,\n focusPaneId,\n }\n }\n\n return {\n verifyEnvironment,\n applyPlan,\n getDryRunSteps: buildDryRunSteps,\n }\n}\n","import type {\n TerminalBackend,\n TerminalBackendContext,\n TerminalBackendKind,\n TmuxTerminalBackendContext,\n WeztermTerminalBackendContext,\n} from \"./terminal-backend\"\nimport { createTmuxBackend } from \"../backends/tmux/backend\"\nimport { createWeztermBackend } from \"../backends/wezterm/backend\"\n\nexport function createTerminalBackend(kind: \"tmux\", context: TmuxTerminalBackendContext): TerminalBackend\nexport function createTerminalBackend(kind: \"wezterm\", context: WeztermTerminalBackendContext): TerminalBackend\nexport function createTerminalBackend(kind: TerminalBackendKind, context: TerminalBackendContext): TerminalBackend {\n if (kind === \"tmux\") {\n if (!(\"executor\" in context)) {\n throw new Error(\"tmux backend requires executor context\")\n }\n return createTmuxBackend(context)\n }\n\n if (kind === \"wezterm\") {\n return createWeztermBackend(context)\n }\n\n throw new Error(`Unsupported backend \"${kind}\"`)\n}\n","import type { TerminalBackendKind } from \"./terminal-backend\"\n\ntype ResolveBackendOptions = {\n readonly cliFlag?: TerminalBackendKind\n readonly presetBackend?: TerminalBackendKind\n readonly env: NodeJS.ProcessEnv\n}\n\nconst KNOWN_BACKENDS: TerminalBackendKind[] = [\"tmux\", \"wezterm\"]\n\nexport const resolveTerminalBackendKind = ({\n cliFlag,\n presetBackend,\n env,\n}: ResolveBackendOptions): TerminalBackendKind => {\n const selectedBackend = cliFlag ?? presetBackend\n if (selectedBackend !== undefined) {\n if (!KNOWN_BACKENDS.includes(selectedBackend)) {\n throw new Error(`Unknown backend \"${selectedBackend}\"`)\n }\n return selectedBackend\n }\n\n if (typeof env.TMUX === \"string\" && env.TMUX.trim().length > 0) {\n return \"tmux\"\n }\n\n return \"tmux\"\n}\n","import chalk from \"chalk\"\n\nimport type { WindowMode } from \"../models/types\"\nimport type { DryRunStep } from \"../executor/terminal-backend\"\n\nexport const renderDryRun = (\n steps: ReadonlyArray<DryRunStep>,\n output: (message: string) => void = (message): void => console.log(message),\n): void => {\n output(chalk.bold(\"\\nPlanned terminal steps (dry-run)\"))\n steps.forEach((step, index) => {\n output(` ${index + 1}. [${step.backend}] ${step.summary}: ${step.command}`)\n })\n}\n\nexport const buildPresetSource = (presetName?: string): string => {\n return typeof presetName === \"string\" && presetName.length > 0 ? `preset://${presetName}` : \"preset://default\"\n}\n\nexport const determineCliWindowMode = (options: {\n currentWindow?: boolean\n newWindow?: boolean\n}): WindowMode | undefined => {\n if (options.currentWindow === true && options.newWindow === true) {\n throw new Error(\"Cannot use --current-window and --new-window at the same time\")\n }\n\n if (options.currentWindow === true) {\n return \"current-window\"\n }\n\n if (options.newWindow === true) {\n return \"new-window\"\n }\n\n return undefined\n}\n","import { createInterface } from \"node:readline/promises\"\nimport { stdin as input, stdout as output } from \"node:process\"\nimport type { ConfirmPaneClosure, ConfirmPaneClosureContext } from \"../contracts\"\nimport type { Logger } from \"../utils/logger\"\n\nexport const createPaneKillPrompter = (logger: Logger): ConfirmPaneClosure => {\n return async ({ panesToClose, dryRun }: ConfirmPaneClosureContext): Promise<boolean> => {\n if (panesToClose.length === 0) {\n return true\n }\n\n const paneList = panesToClose.join(\", \")\n\n if (dryRun) {\n logger.warn(`[DRY RUN] Would close panes: ${paneList}`)\n return true\n }\n\n logger.warn(`This operation will close the following panes: ${paneList}`)\n\n if (input.isTTY !== true || output.isTTY !== true) {\n logger.error(\"Cannot prompt for confirmation because the terminal is not interactive\")\n return false\n }\n\n const rl = createInterface({ input, output })\n try {\n const answer = await rl.question(\"Continue? [y/N]: \")\n const normalized = answer.trim().toLowerCase()\n return normalized === \"y\" || normalized === \"yes\"\n } finally {\n rl.close()\n }\n }\n}\n","import type { WindowMode } from \"../models/types\"\n\ntype WindowModeSource = {\n readonly cli?: WindowMode\n readonly preset?: WindowMode\n readonly defaults?: WindowMode\n}\n\ntype WindowModeResolutionSource = \"cli\" | \"preset\" | \"defaults\" | \"fallback\"\n\ntype WindowModeResolution = {\n readonly mode: WindowMode\n readonly source: WindowModeResolutionSource\n}\n\nexport const resolveWindowMode = ({ cli, preset, defaults }: WindowModeSource): WindowModeResolution => {\n if (cli !== undefined) {\n return { mode: cli, source: \"cli\" }\n }\n\n if (preset !== undefined) {\n return { mode: preset, source: \"preset\" }\n }\n\n if (defaults !== undefined) {\n return { mode: defaults, source: \"defaults\" }\n }\n\n return { mode: \"new-window\", source: \"fallback\" }\n}\n","import { createTerminalBackend } from \"../executor/backend-factory\"\nimport { resolveTerminalBackendKind } from \"../executor/backend-resolver\"\nimport type { TerminalBackendKind } from \"../executor/terminal-backend\"\nimport type { WindowMode } from \"../models/types\"\nimport type { CommandExecutor } from \"../contracts\"\nimport type { PresetManager } from \"../contracts\"\nimport type { Logger } from \"../utils/logger\"\nimport { buildPresetSource, determineCliWindowMode, renderDryRun } from \"./command-helpers\"\nimport type { CoreBridge } from \"./core-bridge\"\nimport { createPaneKillPrompter } from \"./user-prompt\"\nimport { resolveWindowMode } from \"./window-mode\"\n\ntype ExecutePresetCliOptions = {\n readonly verbose: boolean\n readonly dryRun: boolean\n readonly currentWindow: boolean\n readonly newWindow: boolean\n readonly backend?: string\n}\n\ntype ExecutePresetInput = {\n readonly presetName: string | undefined\n readonly options: ExecutePresetCliOptions\n readonly skipLoadConfig?: boolean\n readonly presetManager: PresetManager\n readonly createCommandExecutor: (options: { verbose: boolean; dryRun: boolean }) => CommandExecutor\n readonly core: CoreBridge\n readonly logger: Logger\n readonly handleError: (error: unknown) => number\n readonly handlePipelineFailure: (error: unknown) => number\n readonly output?: (line: string) => void\n readonly cwd?: string\n readonly env?: NodeJS.ProcessEnv\n}\n\nexport const executePreset = async ({\n presetName,\n options,\n skipLoadConfig = false,\n presetManager,\n createCommandExecutor,\n core,\n logger,\n handleError,\n handlePipelineFailure,\n output = (line: string): void => console.log(line),\n cwd = process.cwd(),\n env = process.env,\n}: ExecutePresetInput): Promise<number> => {\n try {\n if (skipLoadConfig !== true) {\n await presetManager.loadConfig()\n }\n\n const preset =\n typeof presetName === \"string\" && presetName.length > 0\n ? presetManager.getPreset(presetName)\n : presetManager.getDefaultPreset()\n\n const windowModeResolution = resolveWindowModeForPreset({\n presetManager,\n options,\n presetWindowMode: preset.windowMode,\n })\n const windowMode = windowModeResolution.mode\n logger.info(`Window mode: ${windowMode} (source: ${windowModeResolution.source})`)\n const confirmPaneClosure = createPaneKillPrompter(logger)\n\n const executor = createCommandExecutor({\n verbose: options.verbose,\n dryRun: options.dryRun,\n })\n\n const backendKind = resolveTerminalBackendKind({\n cliFlag: options.backend as TerminalBackendKind | undefined,\n presetBackend: preset.backend,\n env,\n })\n logger.info(`Terminal backend: ${backendKind}`)\n const backendContextBase = {\n logger,\n dryRun: options.dryRun,\n verbose: options.verbose,\n prompt: confirmPaneClosure,\n cwd,\n paneId: env.WEZTERM_PANE,\n } as const\n\n const backend =\n backendKind === \"tmux\"\n ? createTerminalBackend(\"tmux\", {\n ...backendContextBase,\n executor,\n })\n : createTerminalBackend(\"wezterm\", backendContextBase)\n\n await backend.verifyEnvironment()\n\n if (options.dryRun === true) {\n output(\"[DRY RUN] No actual commands will be executed\")\n }\n\n let emission\n try {\n emission = buildPlanEmission({\n core,\n preset,\n presetName,\n })\n } catch (error) {\n return handlePipelineFailure(error)\n }\n\n if (options.dryRun === true) {\n const dryRunSteps = backend.getDryRunSteps(emission)\n renderDryRun(dryRunSteps, output)\n } else {\n try {\n const executionResult = await backend.applyPlan({\n emission,\n windowMode,\n windowName: resolveWindowName({\n presetName,\n presetDisplayName: preset.name,\n }),\n })\n logger.info(`Executed ${executionResult.executedSteps} ${backendKind} steps`)\n } catch (error) {\n return handlePipelineFailure(error)\n }\n }\n\n logger.success(`Applied preset \"${preset.name}\"`)\n return 0\n } catch (error) {\n return handleError(error)\n }\n}\n\nconst buildPlanEmission = ({\n core,\n preset,\n presetName,\n}: {\n readonly core: CoreBridge\n readonly preset: ReturnType<PresetManager[\"getDefaultPreset\"]>\n readonly presetName?: string\n}): ReturnType<CoreBridge[\"emitPlan\"]> => {\n const compileResult = core.compilePresetFromValue({\n value: preset,\n source: buildPresetSource(presetName),\n })\n const planResult = core.createLayoutPlan({ preset: compileResult.preset })\n return core.emitPlan({ plan: planResult.plan })\n}\n\nconst resolveWindowName = ({\n presetName,\n presetDisplayName,\n}: {\n readonly presetName: string | undefined\n readonly presetDisplayName?: string\n}): string => {\n return presetDisplayName ?? presetName ?? \"vde-layout\"\n}\n\nconst resolveWindowModeForPreset = ({\n presetManager,\n options,\n presetWindowMode,\n}: {\n readonly presetManager: PresetManager\n readonly options: ExecutePresetCliOptions\n readonly presetWindowMode: WindowMode | undefined\n}): ReturnType<typeof resolveWindowMode> => {\n const cliWindowMode = determineCliWindowMode({\n currentWindow: options.currentWindow,\n newWindow: options.newWindow,\n })\n const defaults = presetManager.getDefaults()\n return resolveWindowMode({\n cli: cliWindowMode,\n preset: presetWindowMode,\n defaults: defaults?.windowMode,\n })\n}\n","import { SELECT_SURFACE_MODES, SELECT_UI_MODES } from \"../models/schema\"\n\nexport const selectUiModes = SELECT_UI_MODES\nexport const selectSurfaceModes = SELECT_SURFACE_MODES\n\nexport type SelectUiMode = (typeof selectUiModes)[number]\nexport type SelectSurfaceMode = (typeof selectSurfaceModes)[number]\n\nconst selectUiModeSet = new Set<string>(selectUiModes)\nconst selectSurfaceModeSet = new Set<string>(selectSurfaceModes)\n\nconst isSelectUiMode = (value: string): value is SelectUiMode => {\n return selectUiModeSet.has(value)\n}\n\nconst isSelectSurfaceMode = (value: string): value is SelectSurfaceMode => {\n return selectSurfaceModeSet.has(value)\n}\n\nexport const normalizeSelectArgs = (args: readonly string[]): string[] => {\n const normalized: string[] = []\n\n for (let index = 0; index < args.length; index += 1) {\n const token = args[index]\n if (typeof token !== \"string\") {\n continue\n }\n\n if (token === \"--\") {\n normalized.push(...args.slice(index))\n break\n }\n\n if (typeof token === \"string\" && token.startsWith(\"--select=\")) {\n const mode = token.slice(\"--select=\".length)\n normalized.push(\"--select\")\n if (mode.length > 0) {\n normalized.push(\"--select-ui\", mode)\n }\n continue\n }\n\n if (token === \"--select\") {\n const nextToken = args[index + 1]\n if (typeof nextToken === \"string\" && isSelectUiMode(nextToken)) {\n normalized.push(\"--select\", \"--select-ui\", nextToken)\n index += 1\n continue\n }\n }\n\n normalized.push(token)\n }\n\n return normalized\n}\n\nexport const resolveSelectUiMode = (uiValue: string | undefined): SelectUiMode => {\n if (uiValue === undefined) {\n return \"auto\"\n }\n\n if (isSelectUiMode(uiValue)) {\n return uiValue\n }\n\n throw new Error(`Invalid value for --select-ui: \"${uiValue}\". Expected one of: ${selectUiModes.join(\", \")}`)\n}\n\nexport const resolveSelectSurfaceMode = (surfaceValue: string | undefined): SelectSurfaceMode => {\n if (surfaceValue === undefined) {\n return \"auto\"\n }\n\n if (isSelectSurfaceMode(surfaceValue)) {\n return surfaceValue\n }\n\n throw new Error(\n `Invalid value for --select-surface: \"${surfaceValue}\". Expected one of: ${selectSurfaceModes.join(\", \")}`,\n )\n}\n","import { Chalk } from \"chalk\"\nimport { execa } from \"execa\"\nimport stringWidth from \"string-width\"\nimport * as YAML from \"yaml\"\nimport type { PresetManager } from \"../contracts\"\nimport type { Preset, PresetInfo } from \"../models/types\"\nimport type { Logger } from \"../utils/logger\"\nimport { createEnvironmentError, ErrorCodes } from \"../utils/errors\"\nimport type { SelectSurfaceMode, SelectUiMode } from \"./select-args\"\n\nconst FZF_BINARY = \"fzf\"\nconst FZF_CHECK_TIMEOUT_MS = 5_000\nconst MAX_PREVIEW_BASE64_LENGTH = 64 * 1024\nconst RESERVED_FZF_ARGS = new Set([\"delimiter\", \"with-nth\", \"ansi\", \"preview\", \"preview-window\", \"tmux\"])\nconst selectorChalk = new Chalk({ level: 1 })\n\ntype ExecaLikeError = Error & {\n readonly code?: string\n readonly exitCode?: number\n readonly timedOut?: boolean\n}\n\ntype RunFzfInput = {\n readonly args: string[]\n readonly input: string\n readonly cwd: string\n readonly env: NodeJS.ProcessEnv\n}\n\ntype RunFzfResult = {\n readonly stdout: string\n}\n\nexport type SelectPresetResult =\n | {\n readonly status: \"selected\"\n readonly presetName: string\n }\n | {\n readonly status: \"cancelled\"\n }\n\nexport type SelectPresetInput = {\n readonly uiMode: SelectUiMode\n readonly surfaceMode: SelectSurfaceMode\n readonly tmuxPopupOptions?: string\n readonly fzfExtraArgs?: ReadonlyArray<string>\n readonly presetManager: PresetManager\n readonly logger: Logger\n readonly skipLoadConfig?: boolean\n readonly cwd?: string\n readonly env?: NodeJS.ProcessEnv\n readonly isInteractive?: () => boolean\n readonly checkFzfAvailability?: () => Promise<boolean>\n readonly runFzf?: (input: RunFzfInput) => Promise<RunFzfResult>\n}\n\ntype PresetRow = {\n readonly key: string\n readonly name: string\n readonly description: string\n readonly display: string\n readonly previewBase64: string\n}\n\ntype BuildPresetPreviewYamlInput = {\n readonly presetKey: string\n readonly preset: Preset\n}\n\nconst sanitizeTsvCell = (value: string | undefined): string => {\n return (value ?? \"\").replace(/[\\t\\r\\n]+/g, \" \")\n}\n\nconst padDisplayCell = (value: string, width: number): string => {\n const paddingLength = Math.max(0, width - stringWidth(value))\n return `${value}${\" \".repeat(paddingLength)}`\n}\n\nexport const buildPresetPreviewYaml = ({ presetKey, preset }: BuildPresetPreviewYamlInput): string => {\n return YAML.stringify({\n presets: {\n [presetKey]: preset,\n },\n })\n}\n\nconst defaultCheckFzfAvailability = async (): Promise<boolean> => {\n try {\n await execa(FZF_BINARY, [\"--version\"], {\n timeout: FZF_CHECK_TIMEOUT_MS,\n })\n return true\n } catch (error) {\n const execaError = error as ExecaLikeError\n if (\n execaError.code === \"ENOENT\" ||\n execaError.code === \"ETIMEDOUT\" ||\n execaError.code === \"ERR_EXECA_TIMEOUT\" ||\n execaError.timedOut === true\n ) {\n return false\n }\n throw error\n }\n}\n\nconst defaultRunFzf = async ({ args, input, cwd, env }: RunFzfInput): Promise<RunFzfResult> => {\n const result = await execa(FZF_BINARY, args, {\n input,\n cwd,\n env,\n stderr: \"inherit\",\n })\n return { stdout: result.stdout }\n}\n\nconst ensureFzfAvailable = async (checkFzfAvailability: () => Promise<boolean>): Promise<void> => {\n const available = await checkFzfAvailability()\n if (available) {\n return\n }\n\n throw createEnvironmentError(\"fzf is required for preset selection UI\", ErrorCodes.BACKEND_NOT_FOUND, {\n backend: \"fzf\",\n binary: FZF_BINARY,\n })\n}\n\nconst isTmuxSession = (env: NodeJS.ProcessEnv): boolean => {\n return typeof env.TMUX === \"string\" && env.TMUX.length > 0\n}\n\nconst resolveSurfaceMode = ({\n surfaceMode,\n env,\n}: {\n readonly surfaceMode: SelectSurfaceMode\n readonly env: NodeJS.ProcessEnv\n}): Exclude<SelectSurfaceMode, \"auto\"> => {\n if (surfaceMode === \"auto\") {\n return isTmuxSession(env) ? \"tmux-popup\" : \"inline\"\n }\n return surfaceMode\n}\n\nconst validateExtraFzfArgs = (fzfExtraArgs: ReadonlyArray<string>): void => {\n for (const arg of fzfExtraArgs) {\n if (typeof arg !== \"string\" || arg.length === 0) {\n throw new Error(\"Empty value is not allowed for --fzf-arg\")\n }\n\n if (!arg.startsWith(\"--\")) {\n continue\n }\n\n const withoutPrefix = arg.slice(2)\n if (withoutPrefix.length === 0) {\n continue\n }\n const optionName = withoutPrefix.split(\"=\")[0]\n if (optionName !== undefined && RESERVED_FZF_ARGS.has(optionName)) {\n throw new Error(`--fzf-arg cannot override reserved fzf option: --${optionName}`)\n }\n }\n}\n\nconst buildFzfArgs = ({\n surfaceMode,\n tmuxPopupOptions,\n fzfExtraArgs,\n env,\n}: {\n readonly surfaceMode: SelectSurfaceMode\n readonly tmuxPopupOptions: string | undefined\n readonly fzfExtraArgs: ReadonlyArray<string>\n readonly env: NodeJS.ProcessEnv\n}): string[] => {\n validateExtraFzfArgs(fzfExtraArgs)\n\n const resolvedSurfaceMode = resolveSurfaceMode({\n surfaceMode,\n env,\n })\n\n if (resolvedSurfaceMode === \"tmux-popup\" && isTmuxSession(env) !== true) {\n throw new Error(\"tmux popup selector surface requires running inside tmux\")\n }\n\n const surfaceArgs =\n resolvedSurfaceMode === \"tmux-popup\"\n ? [tmuxPopupOptions !== undefined ? `--tmux=${tmuxPopupOptions}` : \"--tmux\"]\n : []\n\n return [\n \"--delimiter=\\\\t\",\n \"--ansi\",\n \"--with-nth=2\",\n \"--prompt=preset> \",\n \"--layout=reverse\",\n \"--height=80%\",\n \"--border\",\n '--preview=node -e \\'process.stdout.write(Buffer.from(process.argv[1], \"base64\").toString(\"utf8\"))\\' {3}',\n \"--preview-window=right,60%,border-left,wrap\",\n ...surfaceArgs,\n ...fzfExtraArgs,\n ]\n}\n\nconst toPresetRows = ({\n presetInfos,\n presetManager,\n}: {\n readonly presetInfos: ReadonlyArray<PresetInfo>\n readonly presetManager: PresetManager\n}): ReadonlyArray<PresetRow> => {\n const rows = presetInfos.map((presetInfo) => {\n const key = sanitizeTsvCell(presetInfo.key)\n const name = sanitizeTsvCell(presetInfo.name)\n const description = sanitizeTsvCell(presetInfo.description)\n const preset = presetManager.getPreset(presetInfo.key)\n const previewYaml = buildPresetPreviewYaml({\n presetKey: presetInfo.key,\n preset,\n })\n const previewBase64 = Buffer.from(previewYaml, \"utf8\").toString(\"base64\")\n if (previewBase64.length > MAX_PREVIEW_BASE64_LENGTH) {\n throw new Error(\n `Preset preview is too large for fzf inline preview payload: \"${presetInfo.key}\" (${previewBase64.length} bytes)`,\n )\n }\n return {\n key,\n name,\n description,\n previewBase64,\n }\n })\n\n const keyColumnWidth = rows.reduce((maxWidth, row) => Math.max(maxWidth, stringWidth(row.key)), 0)\n const nameColumnWidth = rows.reduce((maxWidth, row) => Math.max(maxWidth, stringWidth(row.name)), 0)\n\n return rows.map((row) => {\n const key = padDisplayCell(row.key, keyColumnWidth)\n const name = padDisplayCell(row.name, nameColumnWidth)\n const description = row.description.length > 0 ? row.description : selectorChalk.gray(\"(no description)\")\n const display = `${selectorChalk.cyan(key)} ${selectorChalk.bold(name)} ${selectorChalk.dim(description)}`\n\n return {\n key: row.key,\n name: row.name,\n description: row.description,\n display,\n previewBase64: row.previewBase64,\n }\n })\n}\n\nconst buildFzfInput = (rows: ReadonlyArray<PresetRow>): string => {\n return rows\n .map((row, index) => {\n return [String(index), row.display, row.previewBase64].join(\"\\t\")\n })\n .join(\"\\n\")\n}\n\nconst parseSelectedPresetName = ({\n selectedLine,\n rows,\n}: {\n readonly selectedLine: string\n readonly rows: ReadonlyArray<PresetRow>\n}): string | null => {\n const trimmed = selectedLine.trim()\n if (trimmed.length === 0) {\n return null\n }\n\n const idCell = trimmed.split(\"\\t\")[0]\n const id = Number(idCell)\n if (!Number.isInteger(id) || id < 0 || id >= rows.length) {\n throw new Error(\"Invalid selection returned from fzf\")\n }\n\n return rows[id]?.key ?? null\n}\n\nconst runFzfSelector = async ({\n rows,\n fzfArgs,\n runFzf,\n cwd,\n env,\n}: {\n readonly rows: ReadonlyArray<PresetRow>\n readonly fzfArgs: ReadonlyArray<string>\n readonly runFzf: (input: RunFzfInput) => Promise<RunFzfResult>\n readonly cwd: string\n readonly env: NodeJS.ProcessEnv\n}): Promise<SelectPresetResult> => {\n try {\n const result = await runFzf({\n input: buildFzfInput(rows),\n args: [...fzfArgs],\n cwd,\n env,\n })\n\n const presetName = parseSelectedPresetName({\n selectedLine: result.stdout,\n rows,\n })\n if (presetName === null) {\n return { status: \"cancelled\" }\n }\n\n return {\n status: \"selected\",\n presetName,\n }\n } catch (error) {\n const execaError = error as ExecaLikeError\n if (execaError.exitCode === 130) {\n return { status: \"cancelled\" }\n }\n throw error\n }\n}\n\nexport const selectPreset = async ({\n uiMode,\n surfaceMode,\n tmuxPopupOptions,\n fzfExtraArgs = [],\n presetManager,\n logger,\n skipLoadConfig = false,\n cwd = process.cwd(),\n env = process.env,\n isInteractive = (): boolean =>\n process.stdin.isTTY === true && process.stdout.isTTY === true && process.stderr.isTTY === true,\n checkFzfAvailability = defaultCheckFzfAvailability,\n runFzf = defaultRunFzf,\n}: SelectPresetInput): Promise<SelectPresetResult> => {\n if (isInteractive() !== true) {\n throw new Error(\"Preset selection requires an interactive terminal\")\n }\n\n await ensureFzfAvailable(checkFzfAvailability)\n if (skipLoadConfig !== true) {\n await presetManager.loadConfig()\n }\n\n const presetInfos = presetManager.listPresets()\n if (presetInfos.length === 0) {\n throw new Error(\"No presets defined\")\n }\n\n const fzfArgs = buildFzfArgs({\n surfaceMode,\n tmuxPopupOptions,\n fzfExtraArgs,\n env,\n })\n\n logger.debug(`Preset selection UI: ${uiMode}`)\n\n const rows = toPresetRows({\n presetInfos,\n presetManager,\n })\n return runFzfSelector({\n rows,\n fzfArgs,\n runFzf,\n cwd,\n env,\n })\n}\n","import { defineCommand, parseArgs, renderUsage } from \"citty\"\nimport type { ArgsDef } from \"citty\"\nimport { createRequire } from \"module\"\nimport { createPresetManager } from \"../layout/preset\"\nimport { loadPackageVersion } from \"./package-version\"\nimport { createCliErrorHandlers } from \"./error-handling\"\nimport { applyRuntimeOptions, listPresets } from \"./runtime-and-list\"\nimport { executePreset } from \"./preset-execution\"\nimport type { CommandExecutor } from \"../contracts\"\nimport type { PresetManager } from \"../contracts\"\nimport { createRealExecutor, createDryRunExecutor } from \"../executor/index\"\nimport { createLogger, type Logger } from \"../utils/logger\"\nimport {\n normalizeSelectArgs,\n resolveSelectSurfaceMode,\n resolveSelectUiMode,\n selectSurfaceModes,\n selectUiModes,\n} from \"./select-args\"\nimport { selectPreset as defaultSelectPreset, type SelectPresetInput, type SelectPresetResult } from \"./preset-selector\"\nimport {\n compilePreset as defaultCompilePreset,\n compilePresetFromValue as defaultCompilePresetFromValue,\n createLayoutPlan as defaultCreateLayoutPlan,\n emitPlan as defaultEmitPlan,\n} from \"../core/index\"\nimport type { CoreBridge } from \"./core-bridge\"\nexport type { CoreBridge } from \"./core-bridge\"\n\ntype CLIOptions = {\n readonly presetManager?: PresetManager\n readonly createCommandExecutor?: (options: { verbose: boolean; dryRun: boolean }) => CommandExecutor\n readonly core?: CoreBridge\n readonly selectPreset?: (input: SelectPresetInput) => Promise<SelectPresetResult>\n}\n\nexport type CLI = {\n run(args?: string[]): Promise<number>\n}\n\nconst backendValues = [\"tmux\", \"wezterm\"] as const\nconst listCommandName = \"list\"\nconst EXIT_CODE_CANCELLED = 130\n\ntype OptionValueKind = \"boolean\" | \"value\"\n\ntype OptionSpec = {\n readonly kind: OptionValueKind\n readonly allowOptionLikeValue: boolean\n}\n\ntype OptionSpecs = {\n readonly longOptions: Map<string, OptionSpec>\n readonly shortOptions: Map<string, OptionSpec>\n}\n\nconst optionNamesAllowOptionLikeValue = new Set([\"fzfArg\", \"fzf-arg\"])\n\nconst toKebabCase = (value: string): string => {\n return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`)\n}\n\nconst toOptionSpec = (kind: OptionValueKind, optionName: string): OptionSpec => {\n return {\n kind,\n allowOptionLikeValue: optionNamesAllowOptionLikeValue.has(optionName),\n }\n}\n\nconst buildOptionSpecs = (argsDef: Readonly<ArgsDef>): OptionSpecs => {\n const longOptions = new Map<string, OptionSpec>()\n const shortOptions = new Map<string, OptionSpec>()\n\n for (const [argName, arg] of Object.entries(argsDef)) {\n if (arg.type === \"positional\") {\n continue\n }\n\n const valueKind: OptionValueKind = arg.type === \"boolean\" ? \"boolean\" : \"value\"\n const kebabName = toKebabCase(argName)\n longOptions.set(argName, toOptionSpec(valueKind, argName))\n longOptions.set(kebabName, toOptionSpec(valueKind, kebabName))\n\n const aliases =\n \"alias\" in arg ? (Array.isArray(arg.alias) ? arg.alias : typeof arg.alias === \"string\" ? [arg.alias] : []) : []\n for (const alias of aliases) {\n if (alias.length === 1) {\n shortOptions.set(alias, toOptionSpec(valueKind, alias))\n continue\n }\n\n longOptions.set(alias, toOptionSpec(valueKind, alias))\n const kebabAlias = toKebabCase(alias)\n longOptions.set(kebabAlias, toOptionSpec(valueKind, kebabAlias))\n }\n }\n\n return { longOptions, shortOptions }\n}\n\nconst validateRawOptions = (args: readonly string[], optionSpecs: OptionSpecs): void => {\n for (let index = 0; index < args.length; index += 1) {\n const token = args[index]\n if (typeof token !== \"string\") {\n continue\n }\n\n if (token === \"--\") {\n break\n }\n\n if (!token.startsWith(\"-\") || token === \"-\") {\n continue\n }\n\n if (token.startsWith(\"--\")) {\n const value = token.slice(2)\n if (value.length === 0) {\n continue\n }\n\n const separatorIndex = value.indexOf(\"=\")\n const rawOptionName = separatorIndex >= 0 ? value.slice(0, separatorIndex) : value\n const optionName = rawOptionName.startsWith(\"no-\") ? rawOptionName.slice(3) : rawOptionName\n const optionSpec = optionSpecs.longOptions.get(optionName)\n const kind = optionSpec?.kind\n\n if (kind === undefined) {\n throw new Error(`Unknown option: --${rawOptionName}`)\n }\n\n if (kind === \"value\") {\n if (separatorIndex >= 0) {\n const inlineValue = value.slice(separatorIndex + 1)\n if (inlineValue.length === 0) {\n throw new Error(`Missing value for option: --${optionName}`)\n }\n } else {\n const nextToken = args[index + 1]\n if (typeof nextToken !== \"string\" || nextToken.length === 0) {\n throw new Error(`Missing value for option: --${optionName}`)\n }\n if (nextToken.startsWith(\"-\") && optionSpec?.allowOptionLikeValue !== true) {\n throw new Error(`Missing value for option: --${optionName}`)\n }\n index += 1\n }\n }\n continue\n }\n\n const shortFlags = token.slice(1)\n for (let flagIndex = 0; flagIndex < shortFlags.length; flagIndex += 1) {\n const option = shortFlags[flagIndex]\n if (typeof option !== \"string\" || option.length === 0) {\n continue\n }\n\n const optionSpec = optionSpecs.shortOptions.get(option)\n const kind = optionSpec?.kind\n if (kind === undefined) {\n throw new Error(`Unknown option: -${option}`)\n }\n\n if (kind === \"value\") {\n if (flagIndex < shortFlags.length - 1) {\n break\n }\n\n const nextToken = args[index + 1]\n if (typeof nextToken !== \"string\" || nextToken.length === 0) {\n throw new Error(`Missing value for option: -${option}`)\n }\n if (nextToken.startsWith(\"-\") && optionSpec?.allowOptionLikeValue !== true) {\n throw new Error(`Missing value for option: -${option}`)\n }\n index += 1\n break\n }\n }\n }\n}\n\nconst getPositionals = (args: { readonly _: unknown[] }): string[] => {\n return args._.filter((value): value is string => typeof value === \"string\")\n}\n\nconst collectOptionValues = ({\n args,\n optionNames,\n}: {\n readonly args: readonly string[]\n readonly optionNames: ReadonlyArray<string>\n}): string[] => {\n const values: string[] = []\n const optionNameSet = new Set(optionNames)\n\n for (let index = 0; index < args.length; index += 1) {\n const token = args[index]\n if (typeof token !== \"string\") {\n continue\n }\n\n if (token === \"--\") {\n break\n }\n\n if (!token.startsWith(\"--\")) {\n continue\n }\n\n const eqIndex = token.indexOf(\"=\")\n const rawName = eqIndex >= 0 ? token.slice(2, eqIndex) : token.slice(2)\n if (optionNameSet.has(rawName) !== true) {\n continue\n }\n\n if (eqIndex >= 0) {\n values.push(token.slice(eqIndex + 1))\n continue\n }\n\n const nextToken = args[index + 1]\n if (typeof nextToken === \"string\") {\n values.push(nextToken)\n index += 1\n }\n }\n\n return values\n}\n\nexport const createCli = (options: CLIOptions = {}): CLI => {\n const presetManager = options.presetManager ?? createPresetManager()\n const createCommandExecutor =\n options.createCommandExecutor ??\n ((opts: { verbose: boolean; dryRun: boolean }): CommandExecutor => {\n if (opts.dryRun) {\n return createDryRunExecutor({ verbose: opts.verbose })\n }\n return createRealExecutor({ verbose: opts.verbose })\n })\n const selectPreset = options.selectPreset ?? defaultSelectPreset\n\n const core: CoreBridge =\n options.core ??\n ({\n compilePreset: defaultCompilePreset,\n compilePresetFromValue: defaultCompilePresetFromValue,\n createLayoutPlan: defaultCreateLayoutPlan,\n emitPlan: defaultEmitPlan,\n } as const)\n\n const require = createRequire(import.meta.url)\n const version = loadPackageVersion(require)\n let logger: Logger = createLogger()\n const errorHandlers = createCliErrorHandlers({\n getLogger: () => logger,\n })\n\n const rootArgsDef = {\n preset: {\n type: \"positional\",\n description: 'Preset name (defaults to \"default\" preset when omitted)',\n required: false,\n },\n verbose: {\n type: \"boolean\",\n description: \"Show detailed logs\",\n },\n dryRun: {\n type: \"boolean\",\n description: \"Display commands without executing\",\n },\n backend: {\n type: \"enum\",\n options: [...backendValues],\n description: \"Select terminal backend (tmux or wezterm)\",\n },\n config: {\n type: \"string\",\n valueHint: \"path\",\n description: \"Path to configuration file\",\n },\n currentWindow: {\n type: \"boolean\",\n description: \"Use the current tmux window for layout (kills other panes)\",\n },\n newWindow: {\n type: \"boolean\",\n description: \"Always create a new tmux window for layout\",\n },\n select: {\n type: \"boolean\",\n description: \"Select preset from interactive UI\",\n },\n selectUi: {\n type: \"enum\",\n options: [...selectUiModes],\n description: \"Select preset UI backend (auto or fzf)\",\n },\n selectSurface: {\n type: \"enum\",\n options: [...selectSurfaceModes],\n description: \"Select selector surface mode (auto, inline, or tmux-popup)\",\n },\n selectTmuxPopupOpts: {\n type: \"string\",\n valueHint: \"opts\",\n description: \"tmux popup options used for fzf --tmux=<opts> (example: 80%,70%)\",\n },\n fzfArg: {\n type: \"string\",\n valueHint: \"arg\",\n description: \"Additional argument passed to fzf selector (repeatable)\",\n },\n help: {\n type: \"boolean\",\n alias: \"h\",\n description: \"Show help\",\n },\n version: {\n type: \"boolean\",\n alias: \"v\",\n description: \"Show version\",\n },\n } satisfies ArgsDef\n\n const listCommand = defineCommand<typeof rootArgsDef>({\n meta: {\n name: listCommandName,\n description: \"List available presets\",\n },\n })\n\n const rootCommand = defineCommand({\n meta: {\n name: \"vde-layout\",\n description: \"VDE (Vibrant Development Environment) Layout Manager - tmux pane layout management tool\",\n version,\n },\n args: rootArgsDef,\n subCommands: {\n [listCommandName]: listCommand,\n },\n })\n\n const optionSpecs = buildOptionSpecs(rootArgsDef)\n\n const run = async (args: string[] = process.argv.slice(2)): Promise<number> => {\n logger = createLogger()\n\n try {\n const normalizedArgs = normalizeSelectArgs(args)\n validateRawOptions(normalizedArgs, optionSpecs)\n const parsedArgs = parseArgs(normalizedArgs, rootArgsDef)\n const fzfCliArgs = collectOptionValues({\n args: normalizedArgs,\n optionNames: [\"fzf-arg\", \"fzfArg\"],\n })\n const positionals = getPositionals(parsedArgs)\n const headPositional = positionals[0]\n\n if (parsedArgs.help === true) {\n const usage =\n headPositional === listCommandName\n ? await renderUsage(listCommand, rootCommand)\n : await renderUsage(rootCommand)\n console.log(`${usage}\\n`)\n return 0\n }\n\n if (parsedArgs.version === true) {\n console.log(version)\n return 0\n }\n\n logger = applyRuntimeOptions({\n runtimeOptions: {\n verbose: parsedArgs.verbose === true,\n config: typeof parsedArgs.config === \"string\" ? parsedArgs.config : undefined,\n },\n createLogger,\n presetManager,\n })\n\n if (headPositional === listCommandName) {\n const extraArgs = positionals.slice(1)\n if (extraArgs.length > 0) {\n throw new Error(\n `too many arguments for '${listCommandName}'. Expected 0 arguments but got ${extraArgs.length}.`,\n )\n }\n\n return await listPresets({\n presetManager,\n logger,\n onError: errorHandlers.handleError,\n })\n }\n\n if (positionals.length > 1) {\n throw new Error(`too many arguments. Expected at most 1 argument but got ${positionals.length}.`)\n }\n\n if (parsedArgs.selectUi !== undefined && parsedArgs.select !== true) {\n throw new Error(\"--select-ui requires --select\")\n }\n\n if (parsedArgs.selectSurface !== undefined && parsedArgs.select !== true) {\n throw new Error(\"--select-surface requires --select\")\n }\n\n if (parsedArgs.selectTmuxPopupOpts !== undefined && parsedArgs.select !== true) {\n throw new Error(\"--select-tmux-popup-opts requires --select\")\n }\n\n if (fzfCliArgs.length > 0 && parsedArgs.select !== true) {\n throw new Error(\"--fzf-arg requires --select\")\n }\n\n if (parsedArgs.select === true && typeof headPositional === \"string\" && headPositional.length > 0) {\n throw new Error(\"Cannot use preset argument with --select\")\n }\n\n let resolvedPresetName = headPositional\n let configLoaded = false\n if (parsedArgs.select === true) {\n await presetManager.loadConfig()\n configLoaded = true\n\n const selectorDefaults = presetManager.getDefaults()?.selector\n const selectUiMode = resolveSelectUiMode(\n typeof parsedArgs.selectUi === \"string\" ? parsedArgs.selectUi : selectorDefaults?.ui,\n )\n const selectSurfaceMode = resolveSelectSurfaceMode(\n typeof parsedArgs.selectSurface === \"string\" ? parsedArgs.selectSurface : selectorDefaults?.surface,\n )\n const selectTmuxPopupOptions =\n typeof parsedArgs.selectTmuxPopupOpts === \"string\"\n ? parsedArgs.selectTmuxPopupOpts\n : selectorDefaults?.tmuxPopupOpts\n const configFzfArgs = selectorDefaults?.fzf?.extraArgs ?? []\n const selection = await selectPreset({\n uiMode: selectUiMode,\n surfaceMode: selectSurfaceMode,\n tmuxPopupOptions: selectTmuxPopupOptions,\n fzfExtraArgs: [...configFzfArgs, ...fzfCliArgs],\n presetManager,\n logger,\n skipLoadConfig: true,\n })\n\n if (selection.status === \"cancelled\") {\n return EXIT_CODE_CANCELLED\n }\n\n resolvedPresetName = selection.presetName\n }\n\n return await executePreset({\n presetName: resolvedPresetName,\n skipLoadConfig: configLoaded,\n options: {\n verbose: parsedArgs.verbose === true,\n dryRun: parsedArgs.dryRun === true,\n currentWindow: parsedArgs.currentWindow === true,\n newWindow: parsedArgs.newWindow === true,\n backend: typeof parsedArgs.backend === \"string\" ? parsedArgs.backend : undefined,\n },\n presetManager,\n createCommandExecutor,\n core,\n logger,\n handleError: errorHandlers.handleError,\n handlePipelineFailure: errorHandlers.handlePipelineFailure,\n })\n } catch (error) {\n return errorHandlers.handleError(error)\n }\n }\n\n return { run }\n}\n","#!/usr/bin/env node\nimport { createCli } from \"./cli/index\"\n\n/**\n * Main entry point\n * Launches the CLI application\n */\nconst main = async (): Promise<void> => {\n const cli = createCli()\n try {\n // Pass arguments excluding the first two elements (node, script path) from process.argv\n const exitCode = await cli.run(process.argv.slice(2))\n if (typeof exitCode === \"number\" && exitCode !== 0) {\n process.exit(exitCode)\n }\n } catch (error) {\n // Format and display error message appropriately\n if (error instanceof Error) {\n console.error(\"Error:\", error.message)\n\n // Also display stack trace in debug mode\n if (process.env.VDE_DEBUG === \"true\") {\n console.error(error.stack)\n }\n } else {\n console.error(\"An unexpected error occurred:\", String(error))\n }\n\n process.exit(1)\n }\n}\n\n// Execute immediately\nvoid main()\n"],"mappings":"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"}