UNPKG

vde-layout

Version:

Terminal multiplexer layout management tool for VDE (Vibe Coding Development Environment)

1 lines 323 kB
{"version":3,"file":"index.mjs","names":["yaml","parseCommand","toCommandString","parseCommand","toCommandString","SINGLE_QUOTE","SHELL_SINGLE_QUOTE_ESCAPE","findNewPaneId","resolveSplitOrientationFromStep","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/backends/pane-tracking.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/sidebar-detection.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/after-apply-hook.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  SPLIT_SIZE_RESOLUTION_FAILED: \"SPLIT_SIZE_RESOLUTION_FAILED\",\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  [ErrorCodes.SPLIT_SIZE_RESOLUTION_FAILED]: (error) => {\n    const paneId = typeof error.details.paneId === \"string\" ? error.details.paneId : \"\"\n    const paneCells = typeof error.details.paneCells === \"number\" ? String(error.details.paneCells) : \"\"\n    const detected = typeof error.details.detectedVersion === \"string\" ? error.details.detectedVersion : \"\"\n    const required = typeof error.details.requiredVersion === \"string\" ? error.details.requiredVersion : \"\"\n    const lines = [\"\", \"Unable to resolve split size from pane dimensions.\"]\n    if (paneId) {\n      lines.push(`Pane ID: ${paneId}`)\n    }\n    if (paneCells) {\n      lines.push(`Pane cells: ${paneCells}`)\n    }\n    if (detected) {\n      lines.push(`Detected version: ${detected}`)\n    }\n    if (required) {\n      lines.push(`Required version: ${required}`)\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 HooksSchema = z\n  .object({\n    afterApply: 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\nconst RatioValueSchema = z.union([\n  z.number().positive(),\n  z.string().regex(/^[1-9][0-9]*c$/, {\n    message: 'ratio value must be a positive number or \"<positive-integer>c\"',\n  }),\n])\n\nconst hasNumericWeight = (ratio: ReadonlyArray<number | string>): boolean => {\n  return ratio.some((value) => typeof value === \"number\")\n}\n\nexport const LayoutIssueParamCodes = {\n  RATIO_LENGTH_MISMATCH: \"RATIO_LENGTH_MISMATCH\",\n  RATIO_WEIGHT_MISSING: \"RATIO_WEIGHT_MISSING\",\n} as const\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(RatioValueSchema).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      params: { code: LayoutIssueParamCodes.RATIO_LENGTH_MISMATCH },\n    })\n    .refine((data) => hasNumericWeight(data.ratio), {\n      message: \"ratio must include at least one numeric weight\",\n      params: { code: LayoutIssueParamCodes.RATIO_WEIGHT_MISSING },\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(RatioValueSchema).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    params: { code: LayoutIssueParamCodes.RATIO_LENGTH_MISMATCH },\n  })\n  .refine((data) => hasNumericWeight(data.ratio), {\n    message: \"ratio must include at least one numeric weight\",\n    params: { code: LayoutIssueParamCodes.RATIO_WEIGHT_MISSING },\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  hooks: HooksSchema.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 { LayoutIssueParamCodes, 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 CompiledRatioEntry =\n  | { readonly kind: \"weight\"; readonly weight: number }\n  | { readonly kind: \"fixed-cells\"; readonly cells: number }\n\nexport type CompiledSplitPane = {\n  readonly kind: \"split\"\n  readonly orientation: \"horizontal\" | \"vertical\"\n  readonly ratio: ReadonlyArray<CompiledRatioEntry>\n  readonly panes: ReadonlyArray<CompiledLayoutNode>\n}\n\nexport type CompiledLayoutNode = CompiledTerminalPane | CompiledSplitPane\n\ntype CompiledPresetMetadata = {\n  readonly source: string\n}\n\nexport type CompiledPresetHooks = {\n  readonly afterApply?: string\n}\n\nexport type CompiledPreset = {\n  readonly name: string\n  readonly version: string\n  readonly command?: string\n  readonly layout?: CompiledLayoutNode\n  readonly hooks?: CompiledPresetHooks\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 FIXED_RATIO_PATTERN = /^([1-9][0-9]*)c$/\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      hooks: parseHooks(parsed.hooks),\n      metadata: { source },\n    },\n  }\n}\n\nconst parseHooks = (hooks: unknown): CompiledPresetHooks | undefined => {\n  if (!isRecord(hooks)) {\n    return undefined\n  }\n\n  const afterApply = typeof hooks.afterApply === \"string\" && hooks.afterApply.length > 0 ? hooks.afterApply : undefined\n\n  return afterApply === undefined ? undefined : { afterApply }\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(\n    (value, index): CompiledRatioEntry =>\n      parseRatioEntry(value, {\n        source: context.source,\n        path: `${context.path}.ratio[${index}]`,\n      }),\n  )\n\n  if (!ratio.some((entry) => entry.kind === \"weight\")) {\n    throw compileError(\"RATIO_WEIGHT_MISSING\", {\n      source: context.source,\n      message: \"ratio must include at least one numeric weight\",\n      path: `${context.path}.ratio`,\n      details: { ratio: ratioInput },\n    })\n  }\n\n  return {\n    kind: \"split\",\n    orientation,\n    ratio,\n    panes: panes.filter((pane): pane is CompiledLayoutNode => pane !== null),\n  }\n}\n\nconst parseRatioEntry = (\n  value: unknown,\n  context: { readonly source: string; readonly path: string },\n): CompiledRatioEntry => {\n  if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n    return {\n      kind: \"weight\",\n      weight: value,\n    }\n  }\n\n  if (typeof value === \"string\") {\n    const match = value.match(FIXED_RATIO_PATTERN)\n    if (match?.[1] !== undefined) {\n      const parsed = Number(match[1])\n      if (Number.isInteger(parsed) && parsed > 0) {\n        return {\n          kind: \"fixed-cells\",\n          cells: parsed,\n        }\n      }\n    }\n  }\n\n  throw compileError(\"RATIO_INVALID_VALUE\", {\n    source: context.source,\n    message: 'ratio value must be a positive number or \"<positive-integer>c\"',\n    path: context.path,\n    details: { value },\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  const issueParamCode = getIssueParamCode(issue)\n\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 (\n    issueParamCode === LayoutIssueParamCodes.RATIO_LENGTH_MISMATCH ||\n    issue.message.includes(\"Number of elements in ratio array does not match number of elements in panes array\")\n  ) {\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 (\n    issueParamCode === LayoutIssueParamCodes.RATIO_WEIGHT_MISSING ||\n    issue.message.includes(\"ratio must include at least one numeric weight\")\n  ) {\n    const ratio = isRecord(layout) ? layout.ratio : undefined\n    return compileError(\"RATIO_WEIGHT_MISSING\", {\n      source,\n      message: \"ratio must include at least one numeric weight\",\n      path: `${basePath}.ratio`,\n      details: {\n        ratio,\n      },\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 or \"<positive-integer>c\"',\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 getIssueParamCode = (issue: z.ZodIssue): string | undefined => {\n  if (issue.code !== z.ZodIssueCode.custom) {\n    return undefined\n  }\n  const customIssue = issue as z.ZodCustomIssue\n  const code = customIssue.params?.code\n  return typeof code === \"string\" ? code : undefined\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 {\n  CompiledLayoutNode,\n  CompiledPreset,\n  CompiledRatioEntry,\n  CompiledSplitPane,\n  CompiledTerminalPane,\n} 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<CompiledRatioEntry>\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 = validateRatioEntries(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 validateRatioEntries = (\n  ratio: ReadonlyArray<CompiledRatioEntry>,\n  context: { readonly path: string; readonly source: string },\n): ReadonlyArray<CompiledRatioEntry> => {\n  let hasWeight = false\n\n  for (let index = 0; index < ratio.length; index += 1) {\n    const value = ratio[index]\n    if (value?.kind === \"weight\") {\n      if (!Number.isFinite(value.weight) || value.weight <= 0) {\n        throw planError(\"RATIO_INVALID_VALUE\", {\n          message: 'ratio value must be a positive number or \"<positive-integer>c\"',\n          path: `${context.path}.ratio[${index}]`,\n          source: context.source,\n          details: { value },\n        })\n      }\n      hasWeight = true\n      continue\n    }\n\n    if (value?.kind === \"fixed-cells\") {\n      if (!Number.isInteger(value.cells) || value.cells <= 0) {\n        throw planError(\"RATIO_INVALID_VALUE\", {\n          message: 'ratio value must be a positive number or \"<positive-integer>c\"',\n          path: `${context.path}.ratio[${index}]`,\n          source: context.source,\n          details: { value },\n        })\n      }\n      continue\n    }\n\n    throw planError(\"RATIO_INVALID_VALUE\", {\n      message: \"ratio entry is invalid\",\n      path: `${context.path}.ratio[${index}]`,\n      source: context.source,\n      details: { value },\n    })\n  }\n\n  if (!hasWeight) {\n    throw planError(\"RATIO_WEIGHT_MISSING\", {\n      message: \"ratio must include at least one numeric weight\",\n      path: `${context.path}.ratio`,\n      source: context.source,\n      details: { ratio },\n    })\n  }\n\n  return ratio\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\"\nimport type { CompiledRatioEntry } from \"./compile\"\n\ntype EmitPlanInput = {\n  readonly plan: LayoutPlan\n}\n\ntype CommandStepKind = \"split\" | \"focus\"\n\nexport type SplitSizing =\n  | { readonly mode: \"percent\"; readonly percentage: number }\n  | {\n      readonly mode: \"dynamic-cells\"\n      readonly target: CompiledRatioEntry\n      readonly remainingFixedCells: number\n      readonly remainingWeight: number\n      readonly remainingWeightPaneCount: number\n    }\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  readonly splitSizing?: SplitSizing\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  const hasFixedCells = node.ratio.some((entry) => entry.kind === \"fixed-cells\")\n\n  for (let index = 1; index < node.panes.length; index += 1) {\n    const targetPaneId = node.panes[index - 1]?.id ?? node.id\n    const createdPaneId = node.panes[index]?.id\n\n    const splitSizing = hasFixedCells\n      ? buildDynamicSplitSizing(node.ratio, index)\n      : buildPercentSplitSizing(node.ratio, index)\n\n    const percentage = splitSizing.mode === \"percent\" ? splitSizing.percentage : undefined\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      splitSizing,\n    })\n  }\n}\n\nconst buildPercentSplitSizing = (ratio: ReadonlyArray<CompiledRatioEntry>, index: number): SplitSizing => {\n  const remainingIncludingTarget = ratio\n    .slice(index - 1)\n    .reduce((sum, entry) => sum + (entry.kind === \"weight\" ? entry.weight : 0), 0)\n  const remainingAfterTarget = ratio\n    .slice(index)\n    .reduce((sum, entry) => sum + (entry.kind === \"weight\" ? entry.weight : 0), 0)\n\n  const desiredPercentage = remainingIncludingTarget <= 0 ? 0 : (remainingAfterTarget / remainingIncludingTarget) * 100\n\n  return {\n    mode: \"percent\",\n    percentage: clampPercent(desiredPercentage),\n  }\n}\n\nconst buildDynamicSplitSizing = (ratio: ReadonlyArray<CompiledRatioEntry>, index: number): SplitSizing => {\n  const target = ratio[index - 1]!\n  const remaining = ratio.slice(index)\n\n  const remainingFixedCells = remaining.reduce((sum, entry) => {\n    return entry.kind === \"fixed-cells\" ? sum + entry.cells : sum\n  }, 0)\n  const remainingWeight = remaining.reduce((sum, entry) => {\n    return entry.kind === \"weight\" ? sum + entry.weight : sum\n  }, 0)\n  const remainingWeightPaneCount = remaining.reduce((count, entry) => {\n    return entry.kind === \"weight\" ? count + 1 : count\n  }, 0)\n\n  return {\n    mode: \"dynamic-cells\",\n    target,\n    remainingFixedCells,\n    remainingWeight,\n    remainingWeightPaneCount,\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","export type PaneDimensions = {\n  readonly cols: number\n  readonly rows: number\n}\n\nexport const updatePaneSizes = ({\n  paneSizes,\n  targetPaneId,\n  createdPaneId,\n  orientation,\n  targetCells,\n  createdCells,\n}: {\n  readonly paneSizes: Map<string, PaneDimensions>\n  readonly targetPaneId: string\n  readonly createdPaneId: string\n  readonly orientation: \"horizontal\" | \"vertical\"\n  readonly targetCells: number\n  readonly createdCells: number\n}): void => {\n  const base = paneSizes.get(targetPaneId)\n  if (base === undefined) {\n    return\n  }\n\n  if (orientation === \"horizontal\") {\n    paneSizes.set(targetPaneId, { cols: targetCells, rows: base.rows })\n    paneSizes.set(createdPaneId, { cols: createdCells, rows: base.rows })\n    return\n  }\n\n  paneSizes.set(targetPaneId, { cols: base.cols, rows: targetCells })\n  paneSizes.set(createdPaneId, { cols: base.cols, rows: createdCells })\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    readonly setMockProtectedPaneIds: (paneIds: string[]) => void\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 mockProtectedPaneIds: string[] = []\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\")) {\n      const parts: string[] = []\n      if (args.includes(\"#{pane_id}\")) {\n        parts.push(mockPaneIds[0] ?? \"%0\")\n      }\n      if (args.includes(\"#{pane_width}\")) {\n        parts.push(\"200\")\n      }\n      if (args.includes(\"#{pane_height}\")) {\n        parts.push(\"60\")\n      }\n      if (parts.length > 0) {\n        return parts.join(\" \")\n      }\n    }\n\n    // The two list-panes formats below are matched by exact string equality on the\n    // -F argument, so at most one of these branches ever applies to a given call.\n    if (args.includes(\"list-panes\") && args.includes(\"#{pane_id}\\t#{@vde_sidebar}\")) {\n      const protectedPaneIds = new Set(mockProtectedPaneIds)\n      return mockPaneIds.map((paneId) => `${paneId}\\t${protectedPaneIds.has(paneId) ? \"1\" : \"\"}`).join(\"\\n\")\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      // NOTE: Real tmux's `kill-pane -a -t <target>` kills every other pane in the\n      // window, including sidebar panes. This mock deliberately diverges by keeping\n      // mockProtectedPaneIds alive so tests can simulate protection, but production\n      // code must not rely on `kill-pane -a` alone to spare the sidebar: it has to\n      // compute the kill target set explicitly via classifyWindowPanes and kill\n      // non-sidebar panes individually (see plan.md Step 1-4).\n      const targetIndex = args.indexOf(\"-t\")\n      const targetPane =\n        (targetIndex >= 0 && targetIndex + 1 < args.length ? args[targetIndex + 1] : mockPaneIds[0]) ?? \"%0\"\n      const survivingPaneIds = mockPaneIds.filter(\n        (paneId) => paneId === targetPane || mockProtectedPaneIds.includes(paneId),\n      )\n      mockPaneIds = survivingPaneIds.includes(targetPane) ? survivingPaneIds : [targetPane, ...survivingPaneIds]\n      const parsedCounter = Number(targetPane.replace(\"%\", \"\"))\n      if (!Number.isNaN(parsedCounter)) {\n        mockPaneCounter = parsedCounter\n      }\n      return \"\"\n    }\n\n    if (args[0] === \"kill-pane\") {\n      // Individual `kill-pane -t <target>` (no `-a`): only the named pane is\n      // removed, matching real tmux. Production code relies on this to close\n      // non-sidebar panes one at a time (see plan.md Step 1-4).\n      const targetIndex = args.indexOf(\"-t\")\n      const targetPane = targetIndex >= 0 && targetIndex + 1 < args.length ? args[targetIndex + 1] : undefined\n      if (typeof targetPane === \"string\") {\n        mockPaneIds = mockPaneIds.filter((paneId) => paneId !== targetPane)\n      }\n      return \"\"\n    }\n\n    if (args.includes(\"split-window\")) {\n      mockPaneCounter += 1\n      const newPaneId = `%${mockPaneCounter}`\n      mockPaneIds = [...mockPaneIds, newPaneId]\n\n      // `-P -F \"#{pane_id}\"` asks tmux to print the newly created pane id, matching\n      // real tmux's split-window behavior (see splitPaneBesideSidebar).\n      if (args.includes(\"-P\") && args.includes(\"#{pane_id}\")) {\n        return newPaneId\n      }\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    setMockProtectedPaneIds(paneIds: string[]): void {\n      mockProtectedPaneIds = [...paneIds]\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, SplitSizing } 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\nexport type SplitSizeResolutionContext = {\n  readonly paneCells?: number\n  readonly paneId?: string\n  readonly requiredVersion?: string\n  readonly detectedVersion?: string\n  readonly rawPaneRecord?: Readonly<Record<string, unknown>>\n}\n\nexport type ResolvedSplitSize =\n  | {\n      readonly mode: \"percent\"\n      readonly percentage: string\n    }\n  | {\n      readonly mode: \"cells\"\n      readonly cells: string\n      readonly targetCells: number\n      readonly createdCells: number\n    }\n\nconst asSplitStep = (step: CommandStep, field: \"orientation\" | \"percentage\" | \"sizing\"): 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\nconst resolveLegacySplitSizing = (step: SplitCommandStep): SplitSizing | undefined => {\n  if (typeof step.percentage === \"number\" && Number.isFinite(step.percentage)) {\n    return {\n      mode: \"percent\",\n      percentage: step.percentage,\n    }\n  }\n  return undefined\n}\n\nconst resolveSplitSizingMetadata = (step: SplitCommandStep): SplitSizing | undefined => {\n  if (step.splitSizing !== undefined) {\n    return step.splitSizing\n  }\n  return resolveLegacySplitSizing(step)\n}\n\nexport const resolveSplitSize = (step: CommandStep, context: SplitSizeResolutionContext = {}): ResolvedSplitSize => {\n  const splitStep = asSplitStep(step, \"sizing\")\n  const splitSizing = resolveSplitSizingMetadata(splitStep)\n\n  if (splitSizing === undefined) {\n    throw createCoreError(\"execution\", {\n      code: ErrorCodes.INVALID_PLAN,\n      message: \"Split step missing sizing metadata\",\n      path: splitStep.id,\n      details: {\n        splitSizing: splitStep.splitSizing,\n        percentage: splitStep.percentage,\n      },\n    })\n  }\n\n  if (splitSizing.mode === \"percent\") {\n    if (Number.isFinite(splitSizing.percentage)) {\n      return {\n        mode: \"percent\",\n        percentage: String(clampSplitPercentage(splitSizing.percentage)),\n      }\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: splitSizing.percentage },\n    })\n  }\n\n  const dynamic = splitSizing\n  const resolvedPaneCells = context.paneCells\n  if (typeof resolvedPaneCells !== \"number\" || !Number.isInteger(resolvedPaneCells) || resolvedPaneCells <= 0) {\n    throw createCoreError(\"execution\", {\n      code: ErrorCodes.SPLIT_SIZE_RESOLUTION_FAILED,\n      message: \"Pane size is unavailable for dynamic split sizing\",\n      path: splitStep.id,\n      details: buildDynamicResolutionDetails(splitStep, dynamic, context),\n    })\n  }\n\n  const { remainingFixedCells, remainingWeight, remainingWeightPaneCount, target } = dynamic\n  if (\n    !Number.isInteger(remainingFixedCells) ||\n    remainingFixedCells < 0 ||\n    !Number.isFinite(remainingWeight) ||\n    remainingWeight < 0 ||\n    !Number.isInteger(remainingWeightPaneCount) ||\n    remainingWeightPaneCount < 0\n  ) {\n    throw createCoreError(\"execution\", {\n      code: ErrorCodes.INVALID_PLAN,\n      message: \"Split step has invalid dynamic sizing metadata\",\n      path: splitStep.id,\n      details: buildDynamicResolutionDetails(splitStep, dynamic, context),\n    })\n  }\n\n  const minTargetCells = target.kind === \"fixed-cells\" ? target.cells : 1\n  // Together with minTargetCells, minCreatedCells reserves remainingFixedCells + remainingWeightPaneCount.\n  const minCreatedCells = remainingFixedCells + remainingWeightPaneCount\n\n  if (\n    !Number.isInteger(minTargetCells) ||\n    minTargetCells <= 0 ||\n    !Number.isInteger(minCreatedCells) ||\n    minCreatedCells < 0\n  ) {\n    throw createCoreError(\"execution\", {\n      code: ErrorCodes.INVALID_PLAN,\n      message: \"Split step has invalid minimum-cell constraints\",\n      path: splitStep.id,\n      details: buildDynamicResolutionDetails(splitStep, dynamic, context),\n    })\n  }\n\n  if (resolvedPaneCells < minTargetCells + minCreatedCells) {\n    throw createCoreError(\"execution\", {\n      code: ErrorCodes.SPLIT_SIZE_RESOLUTION_FAILED,\n      message: \"Pane is too small for requested fixed and weighted splits\",\n      path: splitStep.id,\n      details: buildDynamicResolutionDetails(splitStep, dynamic, context),\n    })\n  }\n\n  let targetCells: number\n  if (target.kind === \"fixed-cells\") {\n    targetCells = target.cells\n  } else {\n    if (!Number.isFinite(target.weight) || target.weight <= 0) {\n      throw createCoreError(\"execution\", {\n        code: ErrorCodes.INVALID_PLAN,\n        message: \"Split step has invalid weight metadata\",\n        path: splitStep.id,\n        details: buildDynamicResolutionDetails(splitStep, dynamic, context),\n      })\n    }\n\n    const availableForWeights = resolvedPaneCells - remainingFixedCells\n    const weightTotal = target.weight + remainingWeight\n    if (!Number.isFinite(weightTotal) || weightTotal <= 0) {\n      throw createCoreError(\"execution\", {\n        code: ErrorCodes.INVALID_PLAN,\n        message: \"Split step has invalid dynamic weight totals\",\n        path: splitStep.id,\n        details: buildDynamicResolutionDetails(splitStep, dynamic, context),\n      })\n    }\n\n    const rawTarget = Math.round((availableForWeights * target.weight) / weightTotal)\n    const maxTargetCells = resolvedPaneCells - minCreatedCells\n    targetCells = clamp(rawTarget, minTargetCells, maxTargetCells)\n  }\n\n  const createdCells = resolvedPaneCells - targetCells\n\n  if (targetCells < minTargetCells || createdCells < minCreatedCells || targetCells <= 0 || createdCells <= 0) {\n    throw createCoreError(\"execution\", {\n      code: ErrorCodes.SPLIT_SIZE_RESOLUTION_FAILED,\n      message: \"Unable to resolve split size without violating pane minimums\",\n      path: splitStep.id,\n      details: buildDynamicResolutionDetails(splitStep, dynamic, context, {\n        targetCells,\n        createdCells,\n      }),\n    })\n  }\n\n  return {\n    mode: \"cells\",\n    cells: String(createdCells),\n    targetCells,\n    createdCells,\n  }\n}\n\nexport const resolveSplitPercentage = (step: CommandStep): string => {\n  const splitStep = asSplitStep(step, \"percentage\")\n  const splitSizing = resolveSplitSizingMetadata(splitStep)\n  if (splitSizing?.mode === \"dynamic-cells\") {\n    throw createCoreError(\"execution\", {\n      code: ErrorCodes.INVALID_PLAN,\n      message: \"Split step uses dynamic sizing and has no percentage value\",\n      path: splitStep.id,\n      details: { splitSizing: splitStep.splitSizing },\n    })\n  }\n\n  const resolved = resolveSplitSize(step)\n  if (resolved.mode === \"percent\") {\n    return resolved.percentage\n  }\n\n  throw createCoreError(\"execution\", {\n    code: ErrorCodes.INVALID_PLAN,\n    message: \"Split step uses dynamic sizing and has no percentage value\",\n    path: splitStep.id,\n    details: { splitSizing: splitStep.splitSizing },\n  })\n}\n\nconst clampSplitPercentage = (value: number): number => {\n  return Math.min(99, Math.max(1, Math.round(value)))\n}\n\nconst clamp = (value: number, min: number, max: number): number => {\n  return Math.min(max, Math.max(min, value))\n}\n\nconst buildDynamicResolutionDetails = (\n  splitStep: SplitCommandStep,\n  splitSizing: Extract<SplitSizing, { mode: \"dynamic-cells\" }>,\n  context: SplitSizeResolutionContext,\n  extra: Readonly<Record<string, unknown>> = {},\n): Readonly<Record<string, unknown>> => {\n  return {\n    stepId: splitStep.id,\n    paneId: context.paneId,\n    paneCells: context.paneCells,\n    targetSpec: splitSizing.target,\n    remainingFixedCells: splitSizing.remainingFixedCells,\n    remainingWeight: splitSizing.remainingWeight,\n    remainingWeightPaneCount: splitSizing.remainingWeightPaneCount,\n    requiredVersion: context.requiredVersion,\n    detectedVersion: context.detectedVersion,\n    rawPaneRecord: context.rawPaneRecord,\n    ...extra,\n  }\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 * - {{window_id}} - references the real window ID the layout was applied into\n *   (e.g. tmux's `@5`). Only resolved by callers that supply `windowId`\n *   (currently hooks.afterApply); callers that omit it - e.g. pane\n *   `command:` preparation - get a TemplateTokenError if the token is used,\n *   the same as an unresolved {{pane_id:<name>}}.\n */\n\ntype ReplaceTemplateTokensInput = {\n  readonly command: string\n  readonly currentPaneRealId: string\n  readonly focusPaneRealId: string\n  readonly nameToRealIdMap: ReadonlyMap<string, string>\n  readonly windowId?: 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 *   or if {{window_id}} is used but no `windowId` was supplied\n */\nexport const replaceTemplateTokens = ({\n  command,\n  currentPaneRealId,\n  focusPaneRealId,\n  nameToRealIdMap,\n  windowId,\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|window_id|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    if (tokenContent === \"window_id\") {\n      if (windowId === undefined) {\n        throw new TemplateTokenError(\n          \"Window ID is not available. {{window_id}} can only be resolved in hooks.afterApply.\",\n          \"window_id\",\n        )\n      }\n      return windowId\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, resolveSplitSize } from \"./split-step\"\nimport { prepareTerminalCommands } from \"./terminal-command-preparation\"\n\nexport const executeSplitStep = async ({\n  step,\n  executor,\n  paneMap,\n  detectedVersion,\n}: {\n  readonly step: CommandStep\n  readonly executor: CommandExecutor\n  readonly paneMap: Map<string, string>\n  readonly detectedVersion?: 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 = await buildSplitCommand({\n    step,\n    targetRealId,\n    executor,\n    detectedVersion,\n  })\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 = async ({\n  step,\n  targetRealId,\n  executor,\n  detectedVersion,\n}: {\n  readonly step: CommandStep\n  readonly targetRealId: string\n  readonly executor: CommandExecutor\n  readonly detectedVersion?: string\n}): Promise<string[]> => {\n  const orientation = resolveSplitOrientation(step)\n  const directionFlag = orientation === \"horizontal\" ? \"-h\" : \"-v\"\n  if (isDynamicSplit(step)) {\n    const paneCells = await resolveTmuxPaneCells({\n      executor,\n      step,\n      targetRealId,\n      orientation,\n      detectedVersion,\n    })\n    const splitSize = resolveSplitSize(step, {\n      paneCells,\n      paneId: targetRealId,\n      detectedVersion,\n      rawPaneRecord: {\n        backend: \"tmux\",\n        paneId: targetRealId,\n        sourceFormat: \"tmux-format\",\n      },\n    })\n    if (splitSize.mode === \"cells\") {\n      return [\"split-window\", directionFlag, \"-t\", targetRealId, \"-l\", splitSize.cells]\n    }\n    return raiseExecutionError(ErrorCodes.INVALID_PLAN, {\n      message: \"Dynamic split resolved to a non-cell sizing mode\",\n      path: step.id,\n      details: { splitSize },\n    })\n  }\n\n  const splitSize = resolveSplitSize(step, {\n    paneId: targetRealId,\n    detectedVersion,\n  })\n  if (splitSize.mode === \"percent\") {\n    return [\"split-window\", directionFlag, \"-t\", targetRealId, \"-p\", splitSize.percentage]\n  }\n  return raiseExecutionError(ErrorCodes.INVALID_PLAN, {\n    message: \"Percent split resolved to a non-percent sizing mode\",\n    path: step.id,\n    details: { splitSize },\n  })\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 resolveTmuxPaneCells = async ({\n  executor,\n  step,\n  targetRealId,\n  orientation,\n  detectedVersion,\n}: {\n  readonly executor: CommandExecutor\n  readonly step: CommandStep\n  readonly targetRealId: string\n  readonly orientation: \"horizontal\" | \"vertical\"\n  readonly detectedVersion?: string\n}): Promise<number> => {\n  const format = orientation === \"horizontal\" ? \"#{pane_width}\" : \"#{pane_height}\"\n  const output = await executeCommand(executor, [\"display-message\", \"-p\", \"-t\", targetRealId, format], {\n    code: ErrorCodes.TMUX_COMMAND_FAILED,\n    message: \"Failed to resolve tmux pane size\",\n    path: step.id,\n    details: { command: [\"display-message\", \"-p\", \"-t\", targetRealId, format] },\n  })\n  const value = Number.parseInt(output.trim(), 10)\n  if (!Number.isInteger(value) || value <= 0) {\n    raiseExecutionError(ErrorCodes.SPLIT_SIZE_RESOLUTION_FAILED, {\n      message: \"Unable to parse tmux pane size\",\n      path: step.id,\n      details: {\n        paneId: targetRealId,\n        orientation,\n        output,\n        detectedVersion,\n      },\n    })\n  }\n  return value\n}\n\nconst isDynamicSplit = (step: CommandStep): boolean => {\n  return step.kind === \"split\" && step.splitSizing?.mode === \"dynamic-cells\"\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","// Sidebar pane detection.\n//\n// vde-tmux-sidebar marks its own pane by setting the tmux pane user option\n// `@vde_sidebar` to `1`. Verified against real tmux 3.7b that a single\n// `list-panes -F \"#{pane_id}\\t#{@vde_sidebar}\"` query expands both the pane\n// id and the pane user option value in one call: panes with the option set\n// return `1`, panes without it return an empty string. No per-pane\n// `show-options -pqv -t <pane> @vde_sidebar` fallback is needed.\nimport type { CommandExecutor } from \"../contracts\"\nimport { executeCommand } from \"./plan-runner-helpers\"\nimport { ErrorCodes } from \"../utils/errors\"\n\nexport const SIDEBAR_LIST_PANES_FORMAT = \"#{pane_id}\\t#{@vde_sidebar}\"\n\nexport type ClassifyWindowPanesResult = {\n  readonly sidebarPanes: string[]\n  readonly normalPanes: string[]\n}\n\nexport const classifyWindowPanes = async (\n  executor: CommandExecutor,\n  contextPath: string,\n  targetPaneId?: string,\n): Promise<ClassifyWindowPanesResult> => {\n  // `-t <pane-id>` scopes `list-panes` to the window that pane belongs to (tmux\n  // resolves a pane id target to its containing window), so passing the current\n  // pane id here guarantees the classification covers that pane's window even in\n  // multi-window/multi-session setups where the \"active\" window might differ.\n  const command =\n    typeof targetPaneId === \"string\" && targetPaneId.length > 0\n      ? [\"list-panes\", \"-t\", targetPaneId, \"-F\", SIDEBAR_LIST_PANES_FORMAT]\n      : [\"list-panes\", \"-F\", SIDEBAR_LIST_PANES_FORMAT]\n\n  const output = await executeCommand(executor, command, {\n    code: ErrorCodes.TMUX_COMMAND_FAILED,\n    message: \"Failed to list tmux panes for sidebar detection\",\n    path: contextPath,\n  })\n\n  const sidebarPanes: string[] = []\n  const normalPanes: string[] = []\n\n  for (const line of output.split(\"\\n\")) {\n    const [paneId, sidebarFlag] = line.split(\"\\t\")\n    if (typeof paneId !== \"string\" || paneId.trim().length === 0) {\n      continue\n    }\n\n    if (sidebarFlag?.trim() === \"1\") {\n      sidebarPanes.push(paneId.trim())\n    } else {\n      normalPanes.push(paneId.trim())\n    }\n  }\n\n  return { sidebarPanes, normalPanes }\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 { classifyWindowPanes } from \"./sidebar-detection\"\nimport {\n  executeCommand,\n  executeFocusStep,\n  executeSplitStep,\n  executeTerminalCommands,\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  readonly detectedVersion?: string\n}\n\ntype ExecutePlanSuccess = {\n  readonly executedSteps: number\n  readonly paneMap: ReadonlyMap<string, string>\n}\n\nexport const executePlan = async ({\n  emission,\n  executor,\n  windowName,\n  windowMode,\n  onConfirmKill,\n  detectedVersion,\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    // Target the classification at the current pane's own window (via `-t\n    // currentPaneId`) rather than tmux's \"active\" window, so multi-window/multi-session\n    // setups always classify the window this invocation is actually running in.\n    const { sidebarPanes, normalPanes } = await classifyWindowPanes(executor, initialVirtualPaneId, currentPaneId)\n    const sidebarPaneIds = new Set(sidebarPanes)\n\n    let originPaneId: string\n    if (sidebarPaneIds.has(currentPaneId)) {\n      // The resolved \"current pane\" is the protected sidebar pane itself. Rebuild the\n      // layout starting from the first non-sidebar pane instead, splitting a fresh one\n      // beside the sidebar when the window has no other panes to build on.\n      const [firstNormalPane] = normalPanes\n      originPaneId =\n        firstNormalPane !== undefined\n          ? firstNormalPane\n          : await splitPaneBesideSidebar({\n              executor,\n              sidebarPaneId: currentPaneId,\n              contextPath: initialVirtualPaneId,\n            })\n    } else {\n      originPaneId = currentPaneId\n    }\n\n    const panesToClose = normalPanes.filter((paneId) => paneId !== originPaneId)\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      // `kill-pane -a` would also kill protected sidebar panes in real tmux, so close\n      // each non-sidebar pane individually instead of relying on the bulk flag.\n      for (const paneId of panesToClose) {\n        await executeCommand(executor, [\"kill-pane\", \"-t\", paneId], {\n          code: ErrorCodes.TMUX_COMMAND_FAILED,\n          message: \"Failed to close existing panes\",\n          path: initialVirtualPaneId,\n          details: { command: [\"kill-pane\", \"-t\", paneId] },\n        })\n      }\n    }\n\n    initialPaneId = normalizePaneId(originPaneId)\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, detectedVersion })\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, paneMap }\n}\n\n/**\n * Splits a fresh pane beside the sidebar so it can be used as the layout's origin\n * pane. Only reached when the current window contains nothing but sidebar panes\n * (no normal pane to reuse). The split direction is fixed to a horizontal split\n * away from the sidebar (i.e. the new pane appears on the opposite side).\n *\n * Uses `-P -F \"#{pane_id}\"` to have tmux report the newly created pane id directly\n * in the split-window output, rather than diffing a follow-up `list-panes` call\n * against the pre-split pane set (which was fragile under concurrent pane changes).\n */\nconst splitPaneBesideSidebar = async ({\n  executor,\n  sidebarPaneId,\n  contextPath,\n}: {\n  readonly executor: CommandExecutor\n  readonly sidebarPaneId: string\n  readonly contextPath: string\n}): Promise<string> => {\n  const command = [\"split-window\", \"-h\", \"-P\", \"-F\", \"#{pane_id}\", \"-t\", sidebarPaneId]\n  const output = await executeCommand(executor, command, {\n    code: ErrorCodes.TMUX_COMMAND_FAILED,\n    message: \"Failed to split a pane beside the sidebar\",\n    path: contextPath,\n    details: { command },\n  })\n\n  const newPaneId = output.trim()\n  if (newPaneId.length === 0) {\n    return raiseExecutionError(ErrorCodes.INVALID_PANE, {\n      message: \"Unable to determine the pane created beside the sidebar\",\n      path: contextPath,\n    })\n  }\n\n  return newPaneId\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 { execFileSync } from \"node:child_process\"\nimport { type PaneDimensions, updatePaneSizes } from \"../pane-tracking\"\nimport { createTmuxExecutor, type TmuxExecutor } from \"./executor\"\nimport type { CommandStep, PlanEmission } from \"../../core/emitter\"\nimport { isCoreError } from \"../../core/errors\"\nimport { executePlan } from \"../../executor/plan-runner\"\nimport { SIDEBAR_LIST_PANES_FORMAT } from \"../../executor/sidebar-detection\"\nimport { resolveSplitOrientation as resolveSplitOrientationFromStep, resolveSplitSize } from \"../../executor/split-step\"\nimport { resolveRequiredStepTargetPaneId } from \"../../executor/step-target\"\nimport { createUnsupportedStepKindError } from \"../../executor/unsupported-step-kind\"\nimport { buildNameToRealIdMap } from \"../../utils/template-tokens\"\nimport type {\n  ApplyPlanParameters,\n  ApplyPlanResult,\n  DryRunStep,\n  TerminalBackend,\n  TmuxTerminalBackendContext,\n} from \"../../executor/terminal-backend\"\nimport { ErrorCodes } from \"../../utils/errors\"\n\nconst TMUX_VERSION_REGEX = /^tmux\\s+(.+)$/\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  let detectedVersion: string | undefined\n\n  const buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n    const paneSizes = new Map<string, PaneDimensions>()\n    const initialPane = emission.summary.initialPaneId\n    const initialPaneSize = resolveInitialTmuxPaneSize()\n    if (initialPaneSize !== undefined) {\n      paneSizes.set(initialPane, initialPaneSize)\n    }\n\n    return emission.steps.map((step) => ({\n      backend: \"tmux\" as const,\n      summary: step.summary,\n      command: tmuxExecutor.getCommandString(\n        buildTmuxCommand({\n          step,\n          paneSizes,\n          detectedVersion,\n        }),\n      ),\n    }))\n  }\n\n  const verifyEnvironment = async (): Promise<void> => {\n    if (context.dryRun) {\n      return\n    }\n    await tmuxExecutor.verifyTmuxEnvironment()\n    detectedVersion = await detectTmuxVersion(tmuxExecutor)\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      detectedVersion,\n    })\n\n    // The plan runner tracks a virtual-pane-id -> real-pane-id map internally; expose\n    // it (resolved) here so callers such as hooks.afterApply can address panes by\n    // name/focus without knowing tmux's virtual ids. Tests may stub executePlan\n    // without a paneMap, so fall back to an empty one rather than throwing.\n    const paneMap = executionResult.paneMap ?? new Map<string, string>()\n    const focusPaneId = paneMap.get(emission.summary.focusPaneId)\n\n    return {\n      executedSteps: executionResult.executedSteps,\n      focusPaneId,\n      paneNameToRealId: buildNameToRealIdMap(emission.terminals, paneMap),\n      windowId: await resolveTmuxWindowId({ tmuxExecutor, focusPaneId }),\n    }\n  }\n\n  return {\n    verifyEnvironment,\n    applyPlan,\n    getDryRunSteps: buildDryRunSteps,\n  }\n}\n\n// Resolves the real tmux window id (e.g. \"@5\") the layout was applied into, so\n// callers such as hooks.afterApply can pass it to external tools via {{window_id}}.\n// tmux's `-t` does not expand formats, so this literal must be resolved here rather\n// than left for the consuming command to figure out. Issued once, after the plan has\n// finished applying; any failure (e.g. the pane has since gone away) is swallowed so\n// it never affects the outcome of applyPlan itself.\nconst resolveTmuxWindowId = async ({\n  tmuxExecutor,\n  focusPaneId,\n}: {\n  readonly tmuxExecutor: TmuxExecutor\n  readonly focusPaneId: string | undefined\n}): Promise<string | undefined> => {\n  if (focusPaneId === undefined) {\n    return undefined\n  }\n\n  try {\n    const output = await tmuxExecutor.execute([\"display-message\", \"-p\", \"-t\", focusPaneId, \"#{window_id}\"])\n    const trimmed = output.trim()\n    return trimmed.length > 0 ? trimmed : undefined\n  } catch {\n    return undefined\n  }\n}\n\nconst buildTmuxCommand = ({\n  step,\n  paneSizes,\n  detectedVersion,\n}: {\n  readonly step: CommandStep\n  readonly paneSizes: Map<string, PaneDimensions>\n  readonly detectedVersion?: string\n}): string[] => {\n  if (step.kind === \"split\") {\n    const target = resolveRequiredStepTargetPaneId(step)\n    const orientation = resolveSplitOrientationFromStep(step)\n    const direction = orientation === \"horizontal\" ? \"-h\" : \"-v\"\n\n    if (step.splitSizing?.mode === \"dynamic-cells\") {\n      const paneSize = paneSizes.get(target)\n      if (paneSize !== undefined) {\n        const paneCells = orientation === \"horizontal\" ? paneSize.cols : paneSize.rows\n\n        try {\n          const splitSize = resolveSplitSize(step, {\n            paneCells,\n            paneId: target,\n            detectedVersion,\n            rawPaneRecord: {\n              backend: \"tmux\",\n              paneId: target,\n              sourceFormat: \"tmux-format\",\n              size: {\n                cols: paneSize.cols,\n                rows: paneSize.rows,\n              },\n            },\n          })\n\n          if (splitSize.mode === \"cells\") {\n            if (typeof step.createdPaneId === \"string\" && step.createdPaneId.length > 0) {\n              updatePaneSizes({\n                paneSizes,\n                targetPaneId: target,\n                createdPaneId: step.createdPaneId,\n                orientation,\n                targetCells: splitSize.targetCells,\n                createdCells: splitSize.createdCells,\n              })\n            }\n            return [\"split-window\", direction, \"-t\", target, \"-l\", splitSize.cells]\n          }\n        } catch (error) {\n          if (isCoreError(error) && error.code === ErrorCodes.SPLIT_SIZE_RESOLUTION_FAILED) {\n            // dry-run intentionally falls back to a placeholder when pane size cannot be resolved\n          } else {\n            throw error\n          }\n        }\n      }\n\n      return [\"split-window\", direction, \"-t\", target, \"-l\", \"<dynamic>\"]\n    }\n\n    const splitSize = resolveSplitSize(step, {\n      paneId: target,\n      detectedVersion,\n    })\n    if (splitSize.mode !== \"percent\") {\n      throw createUnsupportedStepKindError(step)\n    }\n    return [\"split-window\", direction, \"-t\", target, \"-p\", splitSize.percentage]\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\nconst detectTmuxVersion = async (tmuxExecutor: ReturnType<typeof createTmuxExecutor>): Promise<string | undefined> => {\n  try {\n    const raw = await tmuxExecutor.execute([\"-V\"])\n    const match = raw.trim().match(TMUX_VERSION_REGEX)\n    return match?.[1]?.trim()\n  } catch {\n    return undefined\n  }\n}\n\n// This is windowMode-independent: it only reads process.env.TMUX_PANE/TMUX and is\n// invoked purely to seed dry-run size estimates, regardless of whether the plan will\n// eventually be applied in \"current-window\" or \"new-window\" mode. The sidebar\n// correction below therefore applies unconditionally whenever the process happens to\n// be running with its current pane inside a real tmux sidebar, not just when\n// windowMode is \"current-window\".\nconst resolveInitialTmuxPaneSize = (): PaneDimensions | undefined => {\n  const tmuxPane = process.env.TMUX_PANE\n  const tmuxSession = process.env.TMUX\n  if (\n    typeof tmuxSession !== \"string\" ||\n    tmuxSession.length === 0 ||\n    typeof tmuxPane !== \"string\" ||\n    tmuxPane.length === 0\n  ) {\n    return undefined\n  }\n\n  const currentPane = queryTmuxCurrentPaneSizeAndSidebarFlag(tmuxPane)\n  if (currentPane === undefined) {\n    return undefined\n  }\n\n  if (!currentPane.isSidebar) {\n    return { cols: currentPane.cols, rows: currentPane.rows }\n  }\n\n  // The current pane is the protected sidebar. Dry-run sizing must reflect the\n  // pane the layout will actually be built from (see plan-runner's split-origin\n  // resolution, which applies the same correction when windowMode is\n  // \"current-window\"), not the sidebar itself. A real split is never performed\n  // here: when the window has no other pane yet, sizing is simply left unresolved.\n  const originPaneId = resolveDryRunOriginPaneId(tmuxPane)\n  if (originPaneId === undefined) {\n    return undefined\n  }\n\n  return queryTmuxPaneSize(originPaneId)\n}\n\nconst queryTmuxCurrentPaneSizeAndSidebarFlag = (\n  paneId: string,\n): { cols: number; rows: number; isSidebar: boolean } | undefined => {\n  try {\n    const output = execFileSync(\n      \"tmux\",\n      [\"display-message\", \"-p\", \"-t\", paneId, \"#{pane_width} #{pane_height} #{@vde_sidebar}\"],\n      {\n        encoding: \"utf8\",\n        stdio: [\"ignore\", \"pipe\", \"ignore\"],\n      },\n    ).trim()\n    const [colsRaw = \"\", rowsRaw = \"\", sidebarFlag = \"\"] = output.split(/\\s+/, 3)\n\n    const cols = Number.parseInt(colsRaw, 10)\n    const rows = Number.parseInt(rowsRaw, 10)\n    if (!Number.isInteger(cols) || cols <= 0 || !Number.isInteger(rows) || rows <= 0) {\n      return undefined\n    }\n    return { cols, rows, isSidebar: sidebarFlag === \"1\" }\n  } catch {\n    return undefined\n  }\n}\n\n// `-t targetPaneId` scopes `list-panes` to the window that pane belongs to, so the\n// caller's current pane id must be passed through here too (see the module-level\n// comment above on why this correction is windowMode-independent): without it,\n// this would list tmux's \"active\" window instead of the one this process is\n// actually running in, which can differ in multi-window/multi-session setups.\nconst resolveDryRunOriginPaneId = (targetPaneId: string): string | undefined => {\n  try {\n    const output = execFileSync(\"tmux\", [\"list-panes\", \"-t\", targetPaneId, \"-F\", SIDEBAR_LIST_PANES_FORMAT], {\n      encoding: \"utf8\",\n      stdio: [\"ignore\", \"pipe\", \"ignore\"],\n    })\n\n    for (const line of output.split(\"\\n\")) {\n      const [paneId, sidebarFlag] = line.split(\"\\t\")\n      if (typeof paneId === \"string\" && paneId.trim().length > 0 && sidebarFlag?.trim() !== \"1\") {\n        return paneId.trim()\n      }\n    }\n    return undefined\n  } catch {\n    return undefined\n  }\n}\n\nconst queryTmuxPaneSize = (paneId: string): PaneDimensions | undefined => {\n  try {\n    const sizeOutput = execFileSync(\"tmux\", [\"display-message\", \"-p\", \"-t\", paneId, \"#{pane_width} #{pane_height}\"], {\n      encoding: \"utf8\",\n      stdio: [\"ignore\", \"pipe\", \"ignore\"],\n    }).trim()\n    const [colsRaw = \"\", rowsRaw = \"\"] = sizeOutput.split(/\\s+/, 2)\n\n    const cols = Number.parseInt(colsRaw, 10)\n    const rows = Number.parseInt(rowsRaw, 10)\n    if (!Number.isInteger(cols) || cols <= 0 || !Number.isInteger(rows) || rows <= 0) {\n      return undefined\n    }\n    return { cols, rows }\n  } catch {\n    return undefined\n  }\n}\n","export type WeztermPaneSize = {\n  readonly cols?: number\n  readonly rows?: number\n}\n\nexport type WeztermRawPaneRecord = {\n  readonly backend: \"wezterm\"\n  readonly windowId?: string\n  readonly tabId?: string\n  readonly paneId: string\n  readonly isActive?: boolean\n  readonly size?: WeztermPaneSize\n  readonly sourceFormat: \"wezterm-array\" | \"wezterm-object\" | \"unknown\"\n}\n\nexport type WeztermListPane = {\n  readonly paneId: string\n  readonly isActive: boolean\n  readonly size?: WeztermPaneSize\n  readonly rawPaneRecord: WeztermRawPaneRecord\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 RawListSize = {\n  readonly cols?: unknown\n  readonly rows?: unknown\n}\n\ntype RawListPane = {\n  readonly pane_id?: number | string\n  readonly is_active?: unknown\n  readonly size?: RawListSize\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  readonly size?: RawListSize\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\nconst toPositiveInteger = (value: unknown): number | undefined => {\n  if (typeof value !== \"number\" || !Number.isInteger(value) || value <= 0) {\n    return undefined\n  }\n  return value\n}\n\nconst toPaneSize = (value: unknown): WeztermPaneSize | undefined => {\n  if (typeof value !== \"object\" || value === null) {\n    return undefined\n  }\n  const raw = value as RawListSize\n  const cols = toPositiveInteger(raw.cols)\n  const rows = toPositiveInteger(raw.rows)\n  if (cols === undefined && rows === undefined) {\n    return undefined\n  }\n  return {\n    cols,\n    rows,\n  }\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  size?: WeztermPaneSize\n}\n\nconst toImmutablePanes = (panes: ReadonlyArray<WeztermListPane>): WeztermListPane[] => {\n  return panes.map(\n    (pane): WeztermListPane => ({\n      paneId: pane.paneId,\n      isActive: pane.isActive,\n      ...(pane.size !== undefined ? { size: pane.size } : {}),\n      rawPaneRecord: pane.rawPaneRecord,\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    size: toPaneSize(listEntry.size),\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 createArrayRawPaneRecord = (entry: NormalizedArrayEntry): WeztermRawPaneRecord => {\n  return {\n    backend: \"wezterm\",\n    windowId: entry.windowId,\n    tabId: entry.tabId,\n    paneId: entry.paneId,\n    isActive: entry.isActive,\n    size: entry.size,\n    sourceFormat: \"wezterm-array\",\n  }\n}\n\nconst createObjectRawPaneRecord = ({\n  rawPane,\n  context,\n  paneId,\n  size,\n}: {\n  readonly rawPane: RawListPane\n  readonly context: { readonly windowId: string; readonly tabId: string }\n  readonly paneId: string\n  readonly size?: WeztermPaneSize\n}): WeztermRawPaneRecord => {\n  return {\n    backend: \"wezterm\",\n    windowId: context.windowId,\n    tabId: context.tabId,\n    paneId,\n    isActive: rawPane.is_active === true,\n    size,\n    sourceFormat: \"wezterm-object\",\n  }\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      ...(normalizedEntry.size !== undefined ? { size: normalizedEntry.size } : {}),\n      rawPaneRecord: createArrayRawPaneRecord(normalizedEntry),\n    })\n  }\n\n  return { windows: toImmutableWindows(windowMap) }\n}\n\nconst parseObjectPane = (\n  pane: unknown,\n  context: { readonly windowId: string; readonly tabId: string },\n): 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\n  const size = toPaneSize(rawPane.size)\n  return {\n    paneId: paneIdRaw,\n    isActive: rawPane.is_active === true,\n    ...(size !== undefined ? { size } : {}),\n    rawPaneRecord: createObjectRawPaneRecord({\n      rawPane,\n      context,\n      paneId: paneIdRaw,\n      size,\n    }),\n  }\n}\n\nconst parseObjectTab = (tab: unknown, context: { readonly windowId: string }): 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      windowId: context.windowId,\n      tabId: tabIdRaw,\n    })\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, { windowId: windowIdRaw })\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\"\nexport const WEZTERM_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: WEZTERM_MINIMUM_VERSION,\n      detectedVersion: stdout.trim(),\n    })\n  }\n\n  if (!isVersionSupported(detectedVersion, WEZTERM_MINIMUM_VERSION)) {\n    throw createEnvironmentError(\"Unsupported wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n      requiredVersion: WEZTERM_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 PaneDimensions, updatePaneSizes } from \"../pane-tracking\"\nimport type { PlanEmission } from \"../../core/emitter\"\nimport { createCoreError, isCoreError } from \"../../core/errors\"\nimport { resolveSplitOrientation, resolveSplitSize, type ResolvedSplitSize } 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\"\nconst SINGLE_QUOTE = \"'\"\nconst SHELL_SINGLE_QUOTE_ESCAPE = `'\"'\"'`\n\ntype SplitArgumentSize =\n  | ResolvedSplitSize\n  | {\n      readonly mode: \"cells-placeholder\"\n      readonly cellsPlaceholder: string\n    }\n\nexport type BuildWeztermDryRunStepsOptions = {\n  readonly initialPaneId?: string\n  readonly initialPaneSize?: PaneDimensions\n  readonly detectedVersion?: string\n}\n\nexport const buildSplitArguments = (params: {\n  readonly targetPaneId: string\n  readonly splitSize: SplitArgumentSize\n  readonly horizontal: boolean\n}): string[] => {\n  const directionFlag = params.horizontal ? \"--right\" : \"--bottom\"\n  if (params.splitSize.mode === \"percent\") {\n    return [\"split-pane\", directionFlag, \"--percent\", params.splitSize.percentage, \"--pane-id\", params.targetPaneId]\n  }\n\n  if (params.splitSize.mode === \"cells\") {\n    return [\"split-pane\", directionFlag, \"--cells\", params.splitSize.cells, \"--pane-id\", params.targetPaneId]\n  }\n\n  return [\"split-pane\", directionFlag, \"--cells\", params.splitSize.cellsPlaceholder, \"--pane-id\", params.targetPaneId]\n}\n\nexport const buildDryRunSteps = (\n  emission: PlanEmission,\n  options: BuildWeztermDryRunStepsOptions = {},\n): DryRunStep[] => {\n  const steps: DryRunStep[] = []\n  const paneSizes = new Map<string, PaneDimensions>()\n  if (options.initialPaneId !== undefined && options.initialPaneSize !== undefined) {\n    paneSizes.set(options.initialPaneId, options.initialPaneSize)\n  }\n\n  for (const step of emission.steps) {\n    if (step.kind === \"split\") {\n      const target = resolveRequiredStepTargetPaneId(step)\n      const horizontal = resolveSplitOrientation(step) === \"horizontal\"\n      const splitSize = resolveDryRunSplitSize({\n        step,\n        targetPaneId: target,\n        paneSizes,\n        orientation: horizontal ? \"horizontal\" : \"vertical\",\n        detectedVersion: options.detectedVersion,\n      })\n      const args = buildSplitArguments({\n        targetPaneId: target,\n        splitSize,\n        horizontal,\n      })\n      const summary = step.splitSizing?.mode === \"dynamic-cells\" ? `${step.summary} [dynamic-cells]` : step.summary\n      steps.push({\n        backend: \"wezterm\",\n        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\nconst resolveDryRunSplitSize = ({\n  step,\n  targetPaneId,\n  paneSizes,\n  orientation,\n  detectedVersion,\n}: {\n  readonly step: PlanEmission[\"steps\"][number]\n  readonly targetPaneId: string\n  readonly paneSizes: Map<string, PaneDimensions>\n  readonly orientation: \"horizontal\" | \"vertical\"\n  readonly detectedVersion?: string\n}): SplitArgumentSize => {\n  if (step.kind !== \"split\") {\n    throw createCoreError(\"execution\", {\n      code: ErrorCodes.INVALID_PLAN,\n      message: \"Dry-run split sizing requested for non-split step\",\n      path: step.id,\n    })\n  }\n\n  if (step.splitSizing?.mode === \"dynamic-cells\") {\n    const paneSize = paneSizes.get(targetPaneId)\n    const paneCells = paneSize ? (orientation === \"horizontal\" ? paneSize.cols : paneSize.rows) : undefined\n\n    if (typeof paneCells !== \"number\") {\n      return {\n        mode: \"cells-placeholder\",\n        cellsPlaceholder: \"<dynamic>\",\n      }\n    }\n\n    try {\n      const splitSize = resolveSplitSize(step, {\n        paneCells,\n        paneId: targetPaneId,\n        detectedVersion,\n        rawPaneRecord: {\n          backend: \"wezterm\",\n          paneId: targetPaneId,\n          sourceFormat: \"unknown\",\n          size: paneSize,\n        },\n      })\n\n      if (splitSize.mode === \"cells\" && typeof step.createdPaneId === \"string\" && step.createdPaneId.length > 0) {\n        updatePaneSizes({\n          paneSizes,\n          targetPaneId,\n          createdPaneId: step.createdPaneId,\n          orientation,\n          targetCells: splitSize.targetCells,\n          createdCells: splitSize.createdCells,\n        })\n      }\n\n      if (splitSize.mode === \"cells\") {\n        return splitSize\n      }\n    } catch (error) {\n      if (isCoreError(error) && error.code === ErrorCodes.SPLIT_SIZE_RESOLUTION_FAILED) {\n        return {\n          mode: \"cells-placeholder\",\n          cellsPlaceholder: \"<dynamic>\",\n        }\n      }\n      throw error\n    }\n\n    return {\n      mode: \"cells-placeholder\",\n      cellsPlaceholder: \"<dynamic>\",\n    }\n  }\n\n  return resolveSplitSize(step, {\n    paneId: targetPaneId,\n    detectedVersion,\n  })\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, resolveSplitSize } 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 type { WeztermPaneSize, WeztermRawPaneRecord } from \"./list-parser\"\nimport { registerPaneWithAncestors, resolveRealPaneId } from \"./pane-map\"\nimport type { ExecuteWeztermCommand, ListWeztermWindows, LogPaneMapping, PaneMap } from \"./shared\"\nimport { WEZTERM_MINIMUM_VERSION, type WeztermListResult } from \"./cli\"\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  detectedVersion,\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  readonly detectedVersion?: string\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  const orientation = resolveSplitOrientation(step)\n  const targetPane = findPaneById(beforeList, targetRealId)\n  const paneCells = resolvePaneCellsForOrientation(targetPane?.size, orientation)\n  const splitSize = resolveSplitSize(step, {\n    paneCells,\n    paneId: targetRealId,\n    requiredVersion: WEZTERM_MINIMUM_VERSION,\n    detectedVersion,\n    rawPaneRecord: targetPane?.rawPaneRecord,\n  })\n\n  const args = buildSplitArguments({\n    targetPaneId: targetRealId,\n    splitSize,\n    horizontal: orientation === \"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\nconst findPaneById = (\n  list: WeztermListResult,\n  paneId: string,\n):\n  | {\n      readonly size?: WeztermPaneSize\n      readonly rawPaneRecord?: WeztermRawPaneRecord\n    }\n  | 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 {\n            size: pane.size,\n            rawPaneRecord: pane.rawPaneRecord,\n          }\n        }\n      }\n    }\n  }\n  return undefined\n}\n\nconst resolvePaneCellsForOrientation = (\n  size: { readonly cols?: number; readonly rows?: number } | undefined,\n  orientation: \"horizontal\" | \"vertical\",\n): number | undefined => {\n  if (orientation === \"horizontal\") {\n    return size?.cols\n  }\n  return size?.rows\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 { execFileSync } from \"node:child_process\"\nimport type { PlanEmission } from \"../../core/emitter\"\nimport { createCoreError } from \"../../core/errors\"\nimport type {\n  ApplyPlanParameters,\n  ApplyPlanResult,\n  DryRunStep,\n  TerminalBackend,\n  WeztermTerminalBackendContext,\n} from \"../../executor/terminal-backend\"\nimport { ErrorCodes } from \"../../utils/errors\"\nimport type { Logger } from \"../../utils/logger\"\nimport { listWeztermWindows, runWeztermCli, verifyWeztermAvailability, type WeztermListResult } from \"./cli\"\nimport { buildDryRunSteps } from \"./dry-run\"\nimport { findWorkspaceForPane, resolveInitialPane } from \"./layout-resolution\"\nimport { parseWeztermListResult } from \"./list-parser\"\nimport { registerPaneWithAncestors } from \"./pane-map\"\nimport { applyFocusStep, applySplitStep, applyTerminalCommands } from \"./step-execution\"\nimport type { ExecuteWeztermCommand, PaneMap } from \"./shared\"\nimport { buildNameToRealIdMap } from \"../../utils/template-tokens\"\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  let detectedVersion: string | undefined\n\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    const verification = await verifyWeztermAvailability()\n    detectedVersion = verification.version\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          detectedVersion,\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      paneNameToRealId: buildNameToRealIdMap(emission.terminals, paneMap),\n      windowId,\n    }\n  }\n\n  return {\n    verifyEnvironment,\n    applyPlan,\n    getDryRunSteps: (emission: PlanEmission): DryRunStep[] => {\n      const actualPaneId =\n        typeof context.paneId === \"string\" && context.paneId.length > 0 ? context.paneId : process.env.WEZTERM_PANE\n      const initialPaneSize = resolveInitialWeztermPaneSize({\n        paneId: actualPaneId,\n        logger: context.logger,\n      })\n      return buildDryRunSteps(emission, {\n        initialPaneId: emission.summary.initialPaneId,\n        initialPaneSize,\n        detectedVersion,\n      })\n    },\n  }\n}\n\nconst resolveInitialWeztermPaneSize = ({\n  paneId,\n  logger,\n}: {\n  readonly paneId: string | undefined\n  readonly logger: Logger\n}): { readonly cols: number; readonly rows: number } | undefined => {\n  if (typeof paneId !== \"string\" || paneId.length === 0) {\n    return undefined\n  }\n\n  try {\n    const stdout = execFileSync(\"wezterm\", [\"cli\", \"list\", \"--format\", \"json\"], {\n      encoding: \"utf8\",\n      stdio: [\"ignore\", \"pipe\", \"ignore\"],\n    })\n    const parsed = parseWeztermListResult(stdout)\n    if (parsed === undefined) {\n      logger.debug(`[wezterm] Failed to parse pane list while resolving initial pane size for pane ${paneId}`)\n      return undefined\n    }\n    for (const window of parsed.windows) {\n      for (const tab of window.tabs) {\n        for (const pane of tab.panes) {\n          if (pane.paneId === paneId) {\n            if (typeof pane.size?.cols === \"number\" && typeof pane.size?.rows === \"number\") {\n              return { cols: pane.size.cols, rows: pane.size.rows }\n            }\n            return undefined\n          }\n        }\n      }\n    }\n    return undefined\n  } catch (error) {\n    const reason = error instanceof Error ? error.message : String(error)\n    logger.debug(`[wezterm] Failed to resolve initial pane size for pane ${paneId}: ${reason}`)\n    return undefined\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 { execa } from \"execa\"\nimport { replaceTemplateTokens, TemplateTokenError } from \"../utils/template-tokens\"\nimport type { Logger } from \"../utils/logger\"\n\nexport type RunHostCommand = (command: string, options: { readonly cwd: string }) => Promise<void>\n\n// Guards against a hook command that hangs indefinitely (e.g. a misbehaving sidebar\n// tool). A timed-out execution rejects, which is handled the same as any other\n// hook failure below: logged as a warning and never surfaced as a CLI error.\nconst AFTER_APPLY_HOOK_TIMEOUT_MS = 30_000\n\nexport type AfterApplyHookContext = {\n  readonly cwd: string\n  readonly focusPaneId?: string\n  readonly paneNameToRealId?: ReadonlyMap<string, string>\n  readonly windowId?: string\n}\n\ntype RunAfterApplyHookInput = {\n  readonly hookCommand: string | undefined\n  readonly context: AfterApplyHookContext\n  readonly logger: Logger\n  readonly runHostCommand?: RunHostCommand\n}\n\n// Matches the {{this_pane}}/{{focus_pane}} tokens that this module resolves to\n// context.focusPaneId (see the comment below on why they share one value).\nconst FOCUS_PANE_TOKEN_PATTERN = /\\{\\{(?:this_pane|focus_pane)\\}\\}/\n\n// Matches {{window_id}}, resolved to context.windowId (the real tmux/wezterm window\n// id the layout was applied into, e.g. tmux's \"@5\"). tmux's `-t` does not expand\n// formats, so tools like vde-tmux-sidebar need this literal passed in.\nconst WINDOW_ID_TOKEN_PATTERN = /\\{\\{window_id\\}\\}/\n\n/**\n * Runs the `hooks.afterApply` preset command once, after a preset has been applied\n * successfully. Failures (token resolution or command execution) are logged as\n * warnings and never rejected/thrown, so they cannot affect the CLI's exit code -\n * the preset apply itself has already succeeded by the time this runs.\n */\nexport const runAfterApplyHook = async ({\n  hookCommand,\n  context,\n  logger,\n  runHostCommand = createDefaultRunHostCommand(),\n}: RunAfterApplyHookInput): Promise<void> => {\n  if (typeof hookCommand !== \"string\" || hookCommand.length === 0) {\n    return\n  }\n\n  // {{this_pane}}/{{focus_pane}} resolve to context.focusPaneId (see the comment\n  // below), but replaceTemplateTokens substitutes them verbatim even when given an\n  // empty string - it only validates {{pane_id:<name>}} lookups. Treat a missing\n  // focus pane id as an unresolved token here too, rather than silently running the\n  // command with an empty pane id spliced in.\n  if (context.focusPaneId === undefined && FOCUS_PANE_TOKEN_PATTERN.test(hookCommand)) {\n    logger.warn(\n      \"hooks.afterApply skipped: failed to resolve template tokens ({{this_pane}}/{{focus_pane}} require a focus pane id, but none was available)\",\n    )\n    return\n  }\n\n  // {{window_id}} resolves to context.windowId. replaceTemplateTokens already throws\n  // TemplateTokenError for this case (caught below), but that generic message doesn't\n  // mention \"window id\" specifically; this guard produces a clearer warning up front\n  // and doubles as defense-in-depth if that throw behavior ever changes.\n  if (context.windowId === undefined && WINDOW_ID_TOKEN_PATTERN.test(hookCommand)) {\n    logger.warn(\n      \"hooks.afterApply skipped: failed to resolve template tokens ({{window_id}} requires a window id, but none was available)\",\n    )\n    return\n  }\n\n  let resolvedCommand: string\n  try {\n    resolvedCommand = replaceTemplateTokens({\n      command: hookCommand,\n      // A host-level hook is not \"sent\" to any particular tmux/wezterm pane the way\n      // a terminal pane command is, so there is no distinct \"current pane\" for it.\n      // The pane that ends up focused after the layout was applied is the closest\n      // analogue, so {{this_pane}} and {{focus_pane}} intentionally resolve to the\n      // same value here.\n      currentPaneRealId: context.focusPaneId ?? \"\",\n      focusPaneRealId: context.focusPaneId ?? \"\",\n      nameToRealIdMap: context.paneNameToRealId ?? new Map<string, string>(),\n      windowId: context.windowId,\n    })\n  } catch (error) {\n    const reason = error instanceof TemplateTokenError ? error.message : String(error)\n    logger.warn(`hooks.afterApply skipped: failed to resolve template tokens (${reason})`)\n    return\n  }\n\n  // Mirrors real-executor.ts's \"Executing: <command>\" log; logger.info is already\n  // gated on --verbose/VDE_VERBOSE by the shared logger implementation.\n  logger.info(`Executing: ${resolvedCommand}`)\n\n  try {\n    await runHostCommand(resolvedCommand, { cwd: context.cwd })\n  } catch (error) {\n    const reason = error instanceof Error ? error.message : String(error)\n    logger.warn(`hooks.afterApply failed: ${reason}`)\n  }\n}\n\n/**\n * Executes the resolved hook command through the host shell (equivalent to\n * `sh -c <command>`), rather than splitting it into argv the way tmux commands\n * are executed. hooks.afterApply commands are user-authored, free-form shell\n * text (e.g. \"vde-tmux-sidebar open {{pane_id:sidebar}} | logger\") that may rely\n * on pipes, redirection, or shell expansion, so argv-style execution would break\n * common use cases.\n */\nexport const createDefaultRunHostCommand = (): RunHostCommand => {\n  return async (command, { cwd }) => {\n    await execa(command, { shell: true, cwd, timeout: AFTER_APPLY_HOOK_TIMEOUT_MS })\n  }\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 renderDryRunHook = (\n  afterApply: string | undefined,\n  output: (message: string) => void = (message): void => console.log(message),\n): void => {\n  if (typeof afterApply !== \"string\" || afterApply.length === 0) {\n    return\n  }\n\n  // Dry-run has not created any panes, so pane ids aren't known yet; show the raw,\n  // unresolved hook command rather than attempting template token resolution.\n  output(chalk.bold(\"\\nPlanned hooks (dry-run)\"))\n  output(` 1. [afterApply] ${afterApply}`)\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 { CompiledPreset } from \"../core/index\"\nimport type { WindowMode } from \"../models/types\"\nimport type { CommandExecutor } from \"../contracts\"\nimport type { PresetManager } from \"../contracts\"\nimport type { Logger } from \"../utils/logger\"\nimport { runAfterApplyHook } from \"./after-apply-hook\"\nimport { buildPresetSource, determineCliWindowMode, renderDryRun, renderDryRunHook } 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    let compiledPreset: CompiledPreset\n    try {\n      const built = buildPlanEmission({\n        core,\n        preset,\n        presetName,\n      })\n      emission = built.emission\n      compiledPreset = built.compiledPreset\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      renderDryRunHook(compiledPreset.hooks?.afterApply, 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\n        const afterApplyCommand = compiledPreset.hooks?.afterApply\n        if (afterApplyCommand !== undefined) {\n          await runAfterApplyHook({\n            hookCommand: afterApplyCommand,\n            context: {\n              cwd,\n              focusPaneId: executionResult.focusPaneId,\n              paneNameToRealId: executionResult.paneNameToRealId,\n              windowId: executionResult.windowId,\n            },\n            logger,\n          })\n        }\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}): {\n  readonly emission: ReturnType<CoreBridge[\"emitPlan\"]>\n  readonly compiledPreset: CompiledPreset\n} => {\n  const compileResult = core.compilePresetFromValue({\n    value: preset,\n    source: buildPresetSource(presetName),\n  })\n  const planResult = core.createLayoutPlan({ preset: compileResult.preset })\n  const emission = core.emitPlan({ plan: planResult.plan })\n  return { emission, compiledPreset: compileResult.preset }\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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"}