vde-layout 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1180,6 +1180,9 @@ const toIdString = (value) => {
1180
1180
  const isNonEmptyString = (value) => {
1181
1181
  return typeof value === "string" && value.length > 0;
1182
1182
  };
1183
+ const toWorkspaceString = (value) => {
1184
+ if (typeof value === "string" && value.length > 0) return value;
1185
+ };
1183
1186
  const parseListResult = (stdout$1) => {
1184
1187
  try {
1185
1188
  const parsed = JSON.parse(stdout$1);
@@ -1195,15 +1198,17 @@ const parseListResult = (stdout$1) => {
1195
1198
  const windowId = windowIdRaw;
1196
1199
  const tabId = tabIdRaw;
1197
1200
  const paneId = paneIdRaw;
1201
+ const workspace = toWorkspaceString(listEntry.workspace);
1198
1202
  let windowRecord = windowMap.get(windowId);
1199
1203
  if (!windowRecord) {
1200
1204
  windowRecord = {
1201
1205
  windowId,
1202
1206
  isActive: false,
1207
+ workspace,
1203
1208
  tabs: /* @__PURE__ */ new Map()
1204
1209
  };
1205
1210
  windowMap.set(windowId, windowRecord);
1206
- }
1211
+ } else if (workspace !== void 0 && windowRecord.workspace === void 0) windowRecord.workspace = workspace;
1207
1212
  let tabRecord = windowRecord.tabs.get(tabId);
1208
1213
  if (!tabRecord) {
1209
1214
  tabRecord = {
@@ -1224,6 +1229,7 @@ const parseListResult = (stdout$1) => {
1224
1229
  return { windows: Array.from(windowMap.values()).map((windowRecord) => ({
1225
1230
  windowId: windowRecord.windowId,
1226
1231
  isActive: windowRecord.isActive,
1232
+ workspace: windowRecord.workspace,
1227
1233
  tabs: Array.from(windowRecord.tabs.values()).map((tabRecord) => ({
1228
1234
  tabId: tabRecord.tabId,
1229
1235
  isActive: tabRecord.isActive,
@@ -1244,6 +1250,7 @@ const parseListResult = (stdout$1) => {
1244
1250
  const windowIdRaw = toIdString(rawWindow.window_id);
1245
1251
  if (!isNonEmptyString(windowIdRaw)) continue;
1246
1252
  const windowId = windowIdRaw;
1253
+ const workspace = toWorkspaceString(rawWindow.workspace);
1247
1254
  const mappedTabs = [];
1248
1255
  const tabs = Array.isArray(rawWindow.tabs) ? rawWindow.tabs : [];
1249
1256
  for (const tab of tabs) {
@@ -1274,6 +1281,7 @@ const parseListResult = (stdout$1) => {
1274
1281
  mappedWindows.push({
1275
1282
  windowId,
1276
1283
  isActive: rawWindow.is_active === true,
1284
+ workspace,
1277
1285
  tabs: mappedTabs
1278
1286
  });
1279
1287
  }
@@ -1444,6 +1452,15 @@ const findActiveWindow = (list) => {
1444
1452
  const findWindowContainingPane = (list, paneId) => {
1445
1453
  for (const window of list.windows) for (const tab of window.tabs) for (const pane of tab.panes) if (pane.paneId === paneId) return window.windowId;
1446
1454
  };
1455
+ const findWorkspaceForPane = (list, paneId) => {
1456
+ for (const window of list.windows) for (const tab of window.tabs) for (const pane of tab.panes) if (pane.paneId === paneId) return window.workspace;
1457
+ };
1458
+ const filterWindowsByWorkspace = (list, workspace) => {
1459
+ if (workspace === void 0 || workspace.length === 0) return list;
1460
+ const scoped = list.windows.filter((window) => window.workspace === workspace);
1461
+ if (scoped.length === 0) return list;
1462
+ return { windows: scoped };
1463
+ };
1447
1464
  const delay = (ms) => {
1448
1465
  return new Promise((resolve) => {
1449
1466
  setTimeout(resolve, ms);
@@ -1468,18 +1485,20 @@ const waitForPaneRegistration = async ({ paneId, listWindows, windowHint }) => {
1468
1485
  }
1469
1486
  });
1470
1487
  };
1471
- const resolveInitialPane = async ({ windowMode, prompt, dryRun, listWindows, runCommand, logCommand, initialCwd }) => {
1488
+ const resolveInitialPane = async ({ windowMode, prompt, dryRun, listWindows, runCommand, logCommand, initialCwd, workspaceHint, initialList }) => {
1472
1489
  if (windowMode === "current-window") {
1473
- const list = await listWindows();
1490
+ const snapshot = initialList ?? await listWindows();
1491
+ const scoped = filterWindowsByWorkspace(snapshot, workspaceHint);
1474
1492
  return resolveCurrentWindow({
1475
- list,
1493
+ list: scoped,
1476
1494
  prompt,
1477
1495
  dryRun,
1478
1496
  logCommand
1479
1497
  });
1480
1498
  }
1481
- const existing = await listWindows();
1482
- const activeWindow = findActiveWindow(existing);
1499
+ const existingSnapshot = initialList ?? await listWindows();
1500
+ const scopedExisting = filterWindowsByWorkspace(existingSnapshot, workspaceHint);
1501
+ const activeWindow = findActiveWindow(scopedExisting);
1483
1502
  if (activeWindow) {
1484
1503
  const args$1 = [
1485
1504
  "spawn",
@@ -1506,6 +1525,7 @@ const resolveInitialPane = async ({ windowMode, prompt, dryRun, listWindows, run
1506
1525
  }
1507
1526
  const args = ["spawn", "--new-window"];
1508
1527
  if (typeof initialCwd === "string" && initialCwd.length > 0) args.push("--cwd", initialCwd);
1528
+ if (typeof workspaceHint === "string" && workspaceHint.length > 0) args.push("--workspace", workspaceHint);
1509
1529
  const spawnOutput = await runCommand(args, { message: "Failed to spawn wezterm window" });
1510
1530
  const paneId = extractSpawnPaneId(spawnOutput);
1511
1531
  if (paneId.length === 0) throw createFunctionalError("execution", {
@@ -1706,6 +1726,15 @@ const createWeztermBackend = (context) => {
1706
1726
  const paneMap = /* @__PURE__ */ new Map();
1707
1727
  const initialTerminal = emission.terminals.find((terminal) => terminal.virtualPaneId === initialVirtualPaneId);
1708
1728
  const initialCwd = typeof initialTerminal?.cwd === "string" && initialTerminal.cwd.length > 0 ? initialTerminal.cwd : context.cwd;
1729
+ let cachedInitialList;
1730
+ let workspaceHint;
1731
+ if (typeof context.paneId === "string" && context.paneId.length > 0) try {
1732
+ cachedInitialList = await listWindows();
1733
+ workspaceHint = findWorkspaceForPane(cachedInitialList, context.paneId);
1734
+ } catch {
1735
+ cachedInitialList = void 0;
1736
+ workspaceHint = void 0;
1737
+ }
1709
1738
  const { paneId: initialPaneId, windowId } = await resolveInitialPane({
1710
1739
  windowMode,
1711
1740
  prompt: context.prompt,
@@ -1713,7 +1742,9 @@ const createWeztermBackend = (context) => {
1713
1742
  listWindows,
1714
1743
  runCommand,
1715
1744
  logCommand,
1716
- initialCwd
1745
+ initialCwd,
1746
+ workspaceHint,
1747
+ initialList: cachedInitialList
1717
1748
  });
1718
1749
  registerPaneWithAncestors(paneMap, initialVirtualPaneId, initialPaneId);
1719
1750
  logPaneMapping(initialVirtualPaneId, initialPaneId);
@@ -2440,7 +2471,8 @@ const createCli = (options = {}) => {
2440
2471
  dryRun: options$1.dryRun,
2441
2472
  verbose: options$1.verbose,
2442
2473
  prompt: confirmPaneClosure,
2443
- cwd: process.cwd()
2474
+ cwd: process.cwd(),
2475
+ paneId: process.env.WEZTERM_PANE
2444
2476
  });
2445
2477
  await backend.verifyEnvironment();
2446
2478
  if (options$1.dryRun === true) console.log("[DRY RUN] No actual commands will be executed");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["formatters: Record<string, (error: VDELayoutError) => string>","SplitPaneSchema: z.ZodType<unknown>","PaneSchema: z.ZodType<unknown>","path","candidates: string[]","mergedConfig: Config","yaml","paths: string[]","existing: string[]","mergedPresets: Config[\"presets\"]","loaderOptions: ConfigLoaderOptions","cachedConfig: Config | null","input","output","parseCommand","toCommandString","parseCommand","toCommandString","mockPaneIds: string[]","executedCommands: string[][]","isInTmuxSession","initialPaneId: string","newWindowCommand: string[]","findNewPaneId","buildDryRunSteps","stdout: string","stdout","parse","parsed: unknown","pane: WeztermListPane","mappedWindows: WeztermListWindow[]","mappedTabs: WeztermListTab[]","mappedPanes: WeztermListPane[]","steps: DryRunStep[]","args","spawnOutput","paneId","runCommand: ExecuteWeztermCommand","paneMap: PaneMap","KNOWN_BACKENDS: TerminalBackendKind[]","severityRank: Record<DiagnosticsSeverity, number>","findings: DiagnosticsFinding[]","path","parsedPreset: unknown","parsed: unknown","panes: PlanNode[]","focusPaneIds: string[]","terminalPaneIds: string[]","steps: CommandStep[]","current: PlanNode","KNOWN_ISSUES: ReadonlyArray<string>","functionalCore: FunctionalCoreBridge","defaultCompilePreset","defaultCreateLayoutPlan","defaultEmitPlan","logger: Logger","document: Record<string, unknown>","toYAML","options","compileResult: CompilePresetSuccess","planResult: CreateLayoutPlanSuccess","emission: PlanEmission"],"sources":["../src/utils/errors.ts","../src/models/schema.ts","../src/config/validator.ts","../src/config/loader.ts","../src/layout/preset.ts","../src/cli/window-mode.ts","../src/cli/user-prompt.ts","../src/utils/logger.ts","../src/executor/real-executor.ts","../src/executor/dry-run-executor.ts","../src/executor/mock-executor.ts","../src/tmux/executor.ts","../src/core/errors.ts","../src/executor/plan-runner.ts","../src/executor/backends/tmux-backend.ts","../src/wezterm/cli.ts","../src/executor/backends/wezterm-backend.ts","../src/executor/backend-factory.ts","../src/executor/backend-resolver.ts","../src/core/diagnostics.ts","../src/core/compile.ts","../src/core/planner.ts","../src/core/emitter.ts","../src/cli.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 TMUX_NOT_RUNNING: \"TMUX_NOT_RUNNING\",\n TMUX_COMMAND_FAILED: \"TMUX_COMMAND_FAILED\",\n NOT_IN_TMUX_SESSION: \"NOT_IN_TMUX_SESSION\",\n NOT_IN_TMUX: \"NOT_IN_TMUX\",\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 WEZTERM_NOT_FOUND: \"WEZTERM_NOT_FOUND\",\n UNSUPPORTED_WEZTERM_VERSION: \"UNSUPPORTED_WEZTERM_VERSION\",\n USER_CANCELLED: \"USER_CANCELLED\",\n} as const\n\nconst createBaseError = (\n name: string,\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n const error = new Error(message) as VDELayoutError\n error.name = name\n ;(error as { code: string }).code = code\n ;(error as { details: Readonly<Record<string, unknown>> }).details = details\n return error\n}\n\nexport const createConfigError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"ConfigError\", message, code, details)\n}\n\nexport const createValidationError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"ValidationError\", message, code, details)\n}\n\nexport const createTmuxError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"TmuxError\", message, code, details)\n}\n\nexport const createEnvironmentError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"EnvironmentError\", message, code, details)\n}\n\nexport const isVDELayoutError = (error: unknown): error is VDELayoutError => {\n if (typeof error !== \"object\" || error === null) {\n return false\n }\n\n if (!(\"code\" in error)) {\n return false\n }\n\n const { code } = error as { code?: unknown }\n if (typeof code !== \"string\") {\n return false\n }\n\n if (!(\"details\" in error)) {\n return false\n }\n\n return true\n}\n\nconst formatters: Record<string, (error: VDELayoutError) => string> = {\n [ErrorCodes.CONFIG_NOT_FOUND]: (error) => {\n const searchPaths = error.details.searchPaths\n if (!Array.isArray(searchPaths)) {\n return \"\"\n }\n\n const lines = [\"\", \"Searched in the following locations:\"]\n searchPaths.forEach((location) => lines.push(` - ${location}`))\n lines.push(\"\", \"To create a configuration file, run:\")\n lines.push(\" mkdir -p ~/.config/vde\")\n lines.push(' echo \"presets: {}\" > ~/.config/vde/layout.yml')\n return lines.join(\"\\n\")\n },\n [ErrorCodes.NOT_IN_TMUX_SESSION]: () => {\n return \"\\nThis command must be run inside a tmux session.\\nStart tmux first with: tmux\\n\"\n },\n [ErrorCodes.TMUX_NOT_INSTALLED]: () => {\n return (\n \"\\ntmux is required but not installed.\\n\" +\n \"Install tmux using your package manager:\\n\" +\n \" - macOS: brew install tmux\\n\" +\n \" - Ubuntu/Debian: sudo apt-get install tmux\\n\" +\n \" - Fedora: sudo dnf install tmux\\n\"\n )\n },\n [ErrorCodes.UNSUPPORTED_TMUX_VERSION]: (error) => {\n const requiredVersion = error.details.requiredVersion\n if (typeof requiredVersion !== \"string\") {\n return \"\"\n }\n return `\\nRequired tmux version: ${requiredVersion} or higher\\n`\n },\n [ErrorCodes.BACKEND_NOT_FOUND]: (error) => {\n const backend = typeof error.details.backend === \"string\" ? error.details.backend : \"terminal backend\"\n const binary = typeof error.details.binary === \"string\" ? error.details.binary : backend\n const suggestion =\n backend === \"wezterm\"\n ? [\n \"\",\n `${backend} is required but not installed.`,\n \"Install wezterm using your package manager:\",\n \" - macOS: brew install --cask wezterm\",\n \" - Ubuntu/Debian: sudo apt-get install wezterm\",\n \" - Fedora: sudo dnf install wezterm\",\n ].join(\"\\n\")\n : \"\"\n return `\\nMissing binary: ${binary}${suggestion}`\n },\n [ErrorCodes.WEZTERM_NOT_FOUND]: () => {\n return (\n \"\\nwezterm command was not found.\\n\" +\n \"Install wezterm using your package manager:\\n\" +\n \" - macOS: brew install --cask wezterm\\n\" +\n \" - Ubuntu/Debian: sudo apt-get install wezterm\\n\" +\n \" - Fedora: sudo dnf install wezterm\\n\"\n )\n },\n [ErrorCodes.UNSUPPORTED_WEZTERM_VERSION]: (error) => {\n const requiredVersion = typeof error.details.requiredVersion === \"string\" ? error.details.requiredVersion : \"\"\n const detected = typeof error.details.detectedVersion === \"string\" ? error.details.detectedVersion : \"\"\n const lines = [\"\", \"Unsupported wezterm version detected.\"]\n if (detected) {\n lines.push(`Detected version: ${detected}`)\n }\n if (requiredVersion) {\n lines.push(`Required version: ${requiredVersion} or higher`)\n }\n return lines.join(\"\\n\")\n },\n}\n\nexport const formatError = (error: Error): string => {\n if (!isVDELayoutError(error)) {\n return `${error.name}: ${error.message}`\n }\n\n let message = `Error: ${error.message}`\n\n const formatter = formatters[error.code]\n if (formatter) {\n message += `\\n${formatter(error)}`\n }\n\n const commandDetail = error.details.command\n if (commandDetail !== undefined) {\n message += `\\nCommand: ${JSON.stringify(commandDetail)}`\n }\n\n const stderrDetail = error.details.stderr\n if (stderrDetail !== undefined) {\n message += `\\nstderr: ${String(stderrDetail)}`\n }\n\n const presetDetail = error.details.preset\n if (presetDetail !== undefined) {\n message += `\\npreset: ${String(presetDetail)}`\n }\n\n const nestedErrors = error.details.errors\n if (Array.isArray(nestedErrors) && nestedErrors.length > 0) {\n message += \"\\nValidation errors:\\n\"\n nestedErrors.forEach((item) => {\n message += ` - ${String(item)}\\n`\n })\n }\n\n return message\n}\n","import { z } from \"zod\"\n\nexport const WindowModeSchema = z.enum([\"new-window\", \"current-window\"])\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 })\n .strict()\n\n// Split container schema (recursive)\nconst SplitPaneSchema: z.ZodType<unknown> = z.lazy(() =>\n z\n .object({\n type: z.enum([\"horizontal\", \"vertical\"]),\n ratio: z.array(z.number().positive()).min(1),\n panes: z.array(PaneSchema).min(1),\n })\n .strict()\n .refine((data) => data.ratio.length === data.panes.length, {\n message: \"Number of elements in ratio array does not match number of elements in panes array\",\n }),\n)\n\n// Recursive Pane schema definition\nexport const PaneSchema: z.ZodType<unknown> = z.lazy(() => z.union([SplitPaneSchema, TerminalPaneSchema]))\n\n// Layout schema definition\nexport const LayoutSchema = z\n .object({\n type: z.enum([\"horizontal\", \"vertical\"]),\n ratio: z.array(z.number().positive()).min(1),\n panes: z.array(PaneSchema).min(1),\n })\n .refine((data) => data.ratio.length === data.panes.length, {\n message: \"Number of elements in ratio array does not match number of elements in panes array\",\n })\n\n// Preset schema definition\nexport const PresetSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n layout: LayoutSchema.optional(),\n command: z.string().optional(),\n windowMode: WindowModeSchema.optional(),\n})\n\n// Config schema definition\nexport const ConfigSchema = z.object({\n defaults: z\n .object({\n windowMode: WindowModeSchema.optional(),\n })\n .optional(),\n presets: z.record(PresetSchema),\n})\n\n// Validation result type\ntype ValidationResult<T> = {\n success: boolean\n data?: T\n error?: string\n}\n\n// Helper function to format Zod errors consistently\nconst formatValidationError = (error: z.ZodError): string => {\n const messages = error.errors.map((e) => {\n const path = e.path.join(\".\")\n const message = e.message\n\n // Customize error message for panes array element count check\n if (path === \"layout.panes\" && message.includes(\"at least 2 element\")) {\n return `${path}: panes array must have at least 2 elements`\n }\n\n return `${path}: ${message}`\n })\n\n return messages.join(\"\\n\")\n}\n\n// Config validation\nexport const validateConfig = (data: unknown): ValidationResult<z.infer<typeof ConfigSchema>> => {\n try {\n const parsed = ConfigSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n\n// Preset validation\nexport const validatePreset = (data: unknown): ValidationResult<z.infer<typeof PresetSchema>> => {\n try {\n const parsed = PresetSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n\n// Pane validation\nexport const validatePane = (data: unknown): ValidationResult<z.infer<typeof PaneSchema>> => {\n try {\n const parsed = PaneSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n","import * as YAML from \"yaml\"\nimport { z } from \"zod\"\nimport { ConfigSchema } from \"../models/schema.ts\"\nimport type { Config } from \"../models/types.ts\"\nimport { createValidationError, ErrorCodes, isVDELayoutError } from \"../utils/errors.ts\"\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.ts\"\nimport { createConfigError, ErrorCodes } from \"../utils/errors.ts\"\nimport { validateYAML } from \"./validator.ts\"\n\nexport type ConfigLoaderOptions = {\n readonly configPaths?: string[]\n}\n\nexport type ConfigLoader = {\n readonly loadYAML: () => Promise<string>\n readonly loadConfig: () => Promise<Config>\n readonly findConfigFile: () => Promise<string | null>\n readonly getSearchPaths: () => string[]\n}\n\nexport const createConfigLoader = (options: ConfigLoaderOptions = {}): ConfigLoader => {\n const explicitConfigPaths = options.configPaths\n\n const computeCachedSearchPaths = (): string[] => {\n if (explicitConfigPaths && explicitConfigPaths.length > 0) {\n return [...explicitConfigPaths]\n }\n\n const candidates: string[] = []\n const projectCandidate = findProjectConfigCandidate()\n if (projectCandidate !== null) {\n candidates.push(projectCandidate)\n }\n\n candidates.push(...buildDefaultSearchPaths())\n\n return [...new Set(candidates)]\n }\n\n const loadConfig = async (): Promise<Config> => {\n if (explicitConfigPaths && explicitConfigPaths.length > 0) {\n const filePath = await findFirstExisting(explicitConfigPaths)\n if (filePath === null) {\n throw createConfigError(\"Configuration file not found\", ErrorCodes.CONFIG_NOT_FOUND, {\n searchPaths: explicitConfigPaths,\n })\n }\n\n const content = await safeReadFile(filePath)\n return validateYAML(content)\n }\n\n const searchPaths = computeCachedSearchPaths()\n const existingPaths = await filterExistingPaths(searchPaths)\n\n if (existingPaths.length === 0) {\n throw createConfigError(\"Configuration file not found\", ErrorCodes.CONFIG_NOT_FOUND, {\n searchPaths,\n })\n }\n\n const projectPath = findProjectConfigCandidate()\n const globalPaths = existingPaths.filter((filePath) => filePath !== projectPath)\n\n let mergedConfig: Config = { presets: {} }\n\n for (const globalPath of globalPaths) {\n const content = await safeReadFile(globalPath)\n const config = validateYAML(content)\n mergedConfig = mergeConfigs(mergedConfig, config)\n }\n\n if (projectPath !== null && (await fs.pathExists(projectPath))) {\n const content = await safeReadFile(projectPath)\n const config = validateYAML(content)\n mergedConfig = mergeConfigs(mergedConfig, config)\n }\n\n return applyDefaults(mergedConfig)\n }\n\n return {\n loadYAML: async (): Promise<string> => {\n const config = await loadConfig()\n return yaml.stringify(config)\n },\n loadConfig,\n findConfigFile: async (): Promise<string | null> => {\n const searchPaths =\n explicitConfigPaths && explicitConfigPaths.length > 0 ? [...explicitConfigPaths] : computeCachedSearchPaths()\n\n for (const searchPath of searchPaths) {\n if (await fs.pathExists(searchPath)) {\n return searchPath\n }\n }\n return null\n },\n getSearchPaths: (): string[] => computeCachedSearchPaths(),\n }\n}\n\nconst buildDefaultSearchPaths = (): string[] => {\n const paths: string[] = []\n\n const vdeConfigPath = process.env.VDE_CONFIG_PATH\n if (vdeConfigPath !== undefined) {\n paths.push(path.join(vdeConfigPath, \"layout.yml\"))\n }\n\n const homeDir = process.env.HOME ?? os.homedir()\n const xdgConfigHome = process.env.XDG_CONFIG_HOME ?? path.join(homeDir, \".config\")\n paths.push(path.join(xdgConfigHome, \"vde\", \"layout.yml\"))\n\n return [...new Set(paths)]\n}\n\nconst findProjectConfigCandidate = (): string | null => {\n let currentDir = process.cwd()\n const { root } = path.parse(currentDir)\n\n while (true) {\n const candidate = path.join(currentDir, \".vde\", \"layout.yml\")\n if (fs.existsSync(candidate)) {\n return candidate\n }\n\n if (currentDir === root) {\n break\n }\n\n const parent = path.dirname(currentDir)\n if (parent === currentDir) {\n break\n }\n\n currentDir = parent\n }\n\n return null\n}\n\nconst findFirstExisting = async (paths: ReadonlyArray<string>): Promise<string | null> => {\n for (const candidate of paths) {\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return null\n}\n\nconst filterExistingPaths = async (paths: ReadonlyArray<string>): Promise<string[]> => {\n const existing: string[] = []\n for (const candidate of paths) {\n if (await fs.pathExists(candidate)) {\n existing.push(candidate)\n }\n }\n return existing\n}\n\nconst safeReadFile = async (filePath: string): Promise<string> => {\n try {\n return await fs.readFile(filePath, \"utf8\")\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw createConfigError(`Failed to read configuration file`, ErrorCodes.CONFIG_PERMISSION_ERROR, {\n filePath,\n error: errorMessage,\n })\n }\n}\n\nconst mergeConfigs = (base: Config, override: Config): 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 console.warn(\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 console.warn(\n `[vde-layout] defaults.windowMode conflict: \"${baseDefaults.windowMode}\" overridden by \"${overrideDefaults.windowMode}\"`,\n )\n }\n\n const mergedDefaults =\n baseDefaults !== undefined || overrideDefaults !== undefined\n ? {\n ...(baseDefaults ?? {}),\n ...(overrideDefaults ?? {}),\n }\n : undefined\n\n return mergedDefaults === undefined\n ? {\n presets: mergedPresets,\n }\n : {\n defaults: mergedDefaults,\n presets: mergedPresets,\n }\n}\n\nconst applyDefaults = (config: Config): Config => {\n return config\n}\n","import { createConfigLoader, type ConfigLoaderOptions } from \"../config/loader.ts\"\nimport { createConfigError, ErrorCodes } from \"../utils/errors.ts\"\nimport type { Config, Preset, PresetInfo } from \"../models/types.ts\"\nimport type { PresetManager } from \"../types/preset-manager.ts\"\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","import type { WindowMode } from \"../models/types.ts\"\n\nexport type WindowModeSource = {\n readonly cli?: WindowMode\n readonly preset?: WindowMode\n readonly defaults?: WindowMode\n}\n\nexport type WindowModeResolutionSource = \"cli\" | \"preset\" | \"defaults\" | \"fallback\"\n\nexport type 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 { createInterface } from \"node:readline/promises\"\nimport { stdin as input, stdout as output } from \"node:process\"\nimport type { ConfirmPaneClosure, ConfirmPaneClosureContext } from \"../types/confirm-pane.ts\"\nimport type { Logger } from \"../utils/logger.ts\"\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 await rl.close()\n }\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 { execa } from \"execa\"\nimport { createTmuxError, ErrorCodes } from \"../utils/errors.ts\"\nimport type { CommandExecutor } from \"../types/command-executor.ts\"\nimport { createLogger, LogLevel } from \"../utils/logger.ts\"\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 \"../types/command-executor.ts\"\nimport { createLogger, LogLevel } from \"../utils/logger.ts\"\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 \"../types/command-executor.ts\"\nimport type { TmuxExecutorContract } from \"../types/tmux.ts\"\nimport { createEnvironmentError, ErrorCodes } from \"../utils/errors.ts\"\n\nexport type MockExecutor = CommandExecutor &\n TmuxExecutorContract & {\n readonly getExecutedCommands: () => string[][]\n readonly clearExecutedCommands: () => void\n readonly setMockPaneIds: (paneIds: string[]) => void\n readonly getPaneIds: () => string[]\n }\n\nconst parseCommand = (commandOrArgs: string | string[]): string[] => {\n return typeof commandOrArgs === \"string\"\n ? commandOrArgs\n .split(\" \")\n .filter((segment) => segment.length > 0)\n .slice(1)\n : commandOrArgs\n}\n\nconst isInTmuxSession = (): boolean => {\n return Boolean(process.env.TMUX)\n}\n\nconst toCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n}\n\nexport const createMockExecutor = (): MockExecutor => {\n let mockPaneCounter = 0\n let mockPaneIds: string[] = [\"%0\"]\n let executedCommands: string[][] = []\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n const args = parseCommand(commandOrArgs)\n executedCommands.push(args)\n\n if (args[0] === \"new-window\") {\n mockPaneCounter = 0\n mockPaneIds = [\"%0\"]\n return \"%0\"\n }\n\n if (args.includes(\"display-message\") && args.includes(\"#{pane_id}\")) {\n return mockPaneIds[0] ?? \"%0\"\n }\n\n if (args.includes(\"list-panes\") && args.includes(\"#{pane_id}\")) {\n return mockPaneIds.join(\"\\n\")\n }\n\n if (args[0] === \"kill-pane\" && args.includes(\"-a\")) {\n const targetIndex = args.indexOf(\"-t\")\n const targetPane =\n (targetIndex >= 0 && targetIndex + 1 < args.length ? args[targetIndex + 1] : mockPaneIds[0]) ?? \"%0\"\n mockPaneIds = [targetPane]\n const parsedCounter = Number(targetPane.replace(\"%\", \"\"))\n if (!Number.isNaN(parsedCounter)) {\n mockPaneCounter = parsedCounter\n }\n return \"\"\n }\n\n if (args.includes(\"split-window\")) {\n mockPaneCounter += 1\n const newPaneId = `%${mockPaneCounter}`\n mockPaneIds = [...mockPaneIds, newPaneId]\n }\n\n return \"\"\n }\n\n return {\n execute,\n async executeMany(commandsList: string[][]): Promise<void> {\n for (const args of commandsList) {\n await execute(args)\n }\n },\n isDryRun(): boolean {\n return true\n },\n logCommand(): void {\n // noop\n },\n getExecutedCommands(): string[][] {\n return executedCommands\n },\n clearExecutedCommands(): void {\n executedCommands = []\n },\n setMockPaneIds(paneIds: string[]): void {\n mockPaneIds = [...paneIds]\n },\n getPaneIds(): string[] {\n return mockPaneIds\n },\n isInTmuxSession,\n async verifyTmuxEnvironment(): Promise<void> {\n if (!isInTmuxSession()) {\n throw createEnvironmentError(\"Must be run inside a tmux session\", ErrorCodes.NOT_IN_TMUX, {\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.ts\"\nimport type { TmuxExecutorContract } from \"../types/tmux.ts\"\nimport type { CommandExecutor } from \"../types/command-executor.ts\"\nimport { createRealExecutor, createDryRunExecutor, createMockExecutor } from \"../executor/index.ts\"\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, {\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","type FunctionalCoreErrorKind = \"compile\" | \"plan\" | \"emit\" | \"execution\"\n\nexport type FunctionalCoreError = {\n readonly kind: FunctionalCoreErrorKind\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 createFunctionalError = (\n kind: FunctionalCoreErrorKind,\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): FunctionalCoreError => ({\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 isFunctionalCoreError = (value: unknown): value is FunctionalCoreError => {\n if (typeof value !== \"object\" || value === null) {\n return false\n }\n const candidate = value as Partial<FunctionalCoreError>\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 type { CommandExecutor } from \"../types/command-executor.ts\"\nimport type { PlanEmission, CommandStep, EmittedTerminal } from \"../core/emitter.ts\"\nimport type { WindowMode } from \"../models/types.ts\"\nimport { ErrorCodes } from \"../utils/errors.ts\"\nimport { createFunctionalError } from \"../core/errors.ts\"\nimport type { ConfirmPaneClosure } from \"../types/confirm-pane.ts\"\n\nconst DOUBLE_QUOTE = '\"'\nconst ESCAPED_DOUBLE_QUOTE = '\\\\\"'\n\ntype ExecutePlanInput = {\n readonly emission: PlanEmission\n readonly executor: CommandExecutor\n readonly windowName?: string\n readonly windowMode: WindowMode\n readonly onConfirmKill?: ConfirmPaneClosure\n}\n\ntype ExecutePlanSuccess = {\n readonly executedSteps: number\n}\n\nexport const executePlan = async ({\n emission,\n executor,\n windowName,\n windowMode,\n onConfirmKill,\n}: ExecutePlanInput): Promise<ExecutePlanSuccess> => {\n const initialVirtualPaneId = emission.summary.initialPaneId\n if (typeof initialVirtualPaneId !== \"string\" || initialVirtualPaneId.length === 0) {\n raiseExecutionError(\"INVALID_PLAN\", {\n message: \"Plan emission is missing initial pane metadata\",\n path: \"plan.initialPaneId\",\n })\n }\n\n const paneMap = new Map<string, string>()\n\n const isDryRun = executor.isDryRun()\n\n let initialPaneId: string\n\n if (windowMode === \"current-window\") {\n const currentPaneId = await resolveCurrentPaneId({\n executor,\n contextPath: initialVirtualPaneId,\n isDryRun,\n })\n\n const panesInWindow = await listWindowPaneIds(executor, initialVirtualPaneId)\n const panesToClose = panesInWindow.filter((paneId) => paneId !== currentPaneId)\n\n if (panesToClose.length > 0) {\n let confirmed = true\n if (onConfirmKill !== undefined) {\n confirmed = await onConfirmKill({ panesToClose, dryRun: isDryRun })\n }\n\n if (confirmed !== true) {\n throw createFunctionalError(\"execution\", {\n code: ErrorCodes.USER_CANCELLED,\n message: \"Aborted layout application for current window\",\n path: initialVirtualPaneId,\n details: { panes: panesToClose },\n })\n }\n\n await executeCommand(executor, [\"kill-pane\", \"-a\", \"-t\", currentPaneId], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to close existing panes\",\n path: initialVirtualPaneId,\n details: { command: [\"kill-pane\", \"-a\", \"-t\", currentPaneId] },\n })\n }\n\n initialPaneId = normalizePaneId(currentPaneId)\n } else {\n const newWindowCommand: string[] = [\"new-window\", \"-P\", \"-F\", \"#{pane_id}\"]\n if (typeof windowName === \"string\" && windowName.trim().length > 0) {\n newWindowCommand.push(\"-n\", windowName.trim())\n }\n\n initialPaneId = normalizePaneId(\n await executeCommand(executor, newWindowCommand, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to create tmux window\",\n path: initialVirtualPaneId,\n }),\n )\n }\n\n registerPane(paneMap, initialVirtualPaneId, initialPaneId)\n\n let executedSteps = 0\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n await executeSplitStep({ step, executor, paneMap })\n } else if (step.kind === \"focus\") {\n await executeFocusStep({ step, executor, paneMap })\n }\n executedSteps += 1\n }\n\n await executeTerminalCommands({ terminals: emission.terminals, executor, paneMap })\n\n const finalRealFocus = resolvePaneId(paneMap, emission.summary.focusPaneId)\n if (typeof finalRealFocus === \"string\" && finalRealFocus.length > 0) {\n await executeCommand(executor, [\"select-pane\", \"-t\", finalRealFocus], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to restore focus\",\n path: emission.summary.focusPaneId,\n })\n }\n\n return { executedSteps }\n}\n\nconst executeSplitStep = async ({\n step,\n executor,\n paneMap,\n}: {\n readonly step: CommandStep\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n}): Promise<void> => {\n const targetVirtualId = ensureNonEmpty(step.targetPaneId, () =>\n raiseExecutionError(\"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(\"UNKNOWN_PANE\", {\n message: `Unknown target pane: ${targetVirtualId}`,\n path: step.id,\n }),\n )\n\n const panesBefore = await listPaneIds(executor, step)\n const splitCommand = replaceTarget(step.command, targetRealId)\n await executeCommand(executor, splitCommand, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to execute split step ${step.id}`,\n path: step.id,\n details: { command: splitCommand },\n })\n\n const panesAfter = await listPaneIds(executor, step)\n const newPaneId = ensureNonEmpty(findNewPaneId(panesBefore, panesAfter), () =>\n raiseExecutionError(\"UNKNOWN_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\nconst 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(\"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(\"UNKNOWN_PANE\", {\n message: `Unknown focus pane: ${targetVirtualId}`,\n path: step.id,\n }),\n )\n\n const command = replaceTarget(step.command, 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\nconst executeTerminalCommands = async ({\n terminals,\n executor,\n paneMap,\n}: {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n}): Promise<void> => {\n for (const terminal of terminals) {\n const realPaneId = ensureNonEmpty(resolvePaneId(paneMap, terminal.virtualPaneId), () =>\n raiseExecutionError(\"UNKNOWN_PANE\", {\n message: `Unknown terminal pane: ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n }),\n )\n\n if (typeof terminal.cwd === \"string\" && terminal.cwd.length > 0) {\n const escapedCwd = terminal.cwd.split(DOUBLE_QUOTE).join(ESCAPED_DOUBLE_QUOTE)\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, `cd \"${escapedCwd}\"`, \"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 if (terminal.env !== undefined) {\n for (const [key, value] of Object.entries(terminal.env)) {\n const escaped = String(value).split(DOUBLE_QUOTE).join(ESCAPED_DOUBLE_QUOTE)\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, `export ${key}=\"${escaped}\"`, \"Enter\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to set environment variable ${key}`,\n path: terminal.virtualPaneId,\n })\n }\n }\n\n if (typeof terminal.command === \"string\" && terminal.command.length > 0) {\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, terminal.command, \"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\nconst 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 createFunctionalError(\"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 createFunctionalError(\"execution\", {\n code: context.code,\n message: context.message,\n path: context.path,\n details: context.details,\n })\n }\n}\n\nconst 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 createFunctionalError(\"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\nconst 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 replaceTarget = (command: ReadonlyArray<string>, realTarget: string): string[] => {\n const next = [...command]\n const targetIndex = next.findIndex((value, index) => value === \"-t\" && index + 1 < next.length)\n if (targetIndex >= 0) {\n next[targetIndex + 1] = realTarget\n return next\n }\n\n if (next.length > 0) {\n next[next.length - 1] = realTarget\n }\n return next\n}\n\nconst normalizePaneId = (raw: string): string => {\n const trimmed = raw.trim()\n return trimmed.length === 0 ? \"%0\" : trimmed\n}\n\nconst registerPane = (paneMap: Map<string, string>, virtualId: string, realId: string): void => {\n paneMap.set(virtualId, realId)\n}\n\nconst resolvePaneId = (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\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\nconst 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 createFunctionalError(\"execution\", {\n code,\n message: error.message,\n path: error.path,\n details: error.details,\n })\n}\n","import { createTmuxExecutor } from \"../../tmux/executor.ts\"\nimport type { PlanEmission } from \"../../core/emitter.ts\"\nimport { executePlan } from \"../plan-runner.ts\"\nimport type {\n ApplyPlanParameters,\n ApplyPlanResult,\n DryRunStep,\n TerminalBackend,\n TerminalBackendContext,\n} from \"../terminal-backend.ts\"\n\nexport const createTmuxBackend = (context: TerminalBackendContext): TerminalBackend => {\n const tmuxExecutor = createTmuxExecutor({\n executor: context.executor,\n verbose: context.verbose,\n dryRun: context.dryRun,\n })\n\n const buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n return emission.steps.map((step) => ({\n backend: \"tmux\" as const,\n summary: step.summary,\n command: tmuxExecutor.getCommandString([...step.command]),\n }))\n }\n\n const verifyEnvironment = async (): Promise<void> => {\n if (context.dryRun) {\n return\n }\n await tmuxExecutor.verifyTmuxEnvironment()\n }\n\n const applyPlan = async ({ emission, windowMode, windowName }: ApplyPlanParameters): Promise<ApplyPlanResult> => {\n const executionResult = await executePlan({\n emission,\n executor: tmuxExecutor.getExecutor(),\n windowMode,\n windowName,\n onConfirmKill: context.prompt,\n })\n\n return {\n executedSteps: executionResult.executedSteps,\n focusPaneId: emission.summary.focusPaneId,\n }\n }\n\n return {\n verifyEnvironment,\n applyPlan,\n getDryRunSteps: buildDryRunSteps,\n }\n}\n","import { execa } from \"execa\"\nimport { createEnvironmentError, ErrorCodes } from \"../utils/errors.ts\"\nimport { createFunctionalError } from \"../core/errors.ts\"\n\nconst WEZTERM_BINARY = \"wezterm\"\nconst MINIMUM_VERSION = \"20220624-141144-bd1b7c5d\"\nconst VERSION_REGEX = /(\\d{8})-(\\d{6})-([0-9a-fA-F]+)/i\n\ntype ExecaLikeError = Error & {\n readonly exitCode?: number\n readonly code?: string\n readonly stderr?: string\n readonly stdout?: string\n}\n\nexport type WeztermListPane = {\n readonly paneId: string\n readonly isActive: boolean\n}\n\nexport type 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 tabs: ReadonlyArray<WeztermListTab>\n}\n\nexport type WeztermListResult = {\n readonly windows: ReadonlyArray<WeztermListWindow>\n}\n\nexport const verifyWeztermAvailability = async (): Promise<{ version: string }> => {\n let stdout: string\n try {\n const result = await execa(WEZTERM_BINARY, [\"--version\"])\n stdout = result.stdout\n } catch (error) {\n const execaError = error as ExecaLikeError\n if (execaError.code === \"ENOENT\") {\n throw createEnvironmentError(\"wezterm is not installed\", ErrorCodes.BACKEND_NOT_FOUND, {\n backend: \"wezterm\",\n binary: WEZTERM_BINARY,\n })\n }\n throw createEnvironmentError(\"Failed to execute wezterm --version\", ErrorCodes.WEZTERM_NOT_FOUND, {\n backend: \"wezterm\",\n binary: WEZTERM_BINARY,\n stderr: execaError.stderr,\n })\n }\n\n const detectedVersion = extractVersion(stdout)\n if (detectedVersion === undefined) {\n throw createEnvironmentError(\"Unable to determine wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n requiredVersion: MINIMUM_VERSION,\n detectedVersion: stdout.trim(),\n })\n }\n\n if (!isVersionSupported(detectedVersion, MINIMUM_VERSION)) {\n throw createEnvironmentError(\"Unsupported wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n requiredVersion: MINIMUM_VERSION,\n detectedVersion,\n })\n }\n\n return { version: detectedVersion }\n}\n\nexport type RunWeztermErrorContext = {\n readonly message: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n}\n\nexport const runWeztermCli = async (args: string[], errorContext: RunWeztermErrorContext): Promise<string> => {\n try {\n const result = await execa(WEZTERM_BINARY, [\"cli\", ...args])\n return result.stdout\n } catch (error) {\n const execaError = error as ExecaLikeError\n throw createFunctionalError(\"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 = parseListResult(stdout)\n if (result === undefined) {\n throw createFunctionalError(\"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\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\ntype RawListPane = {\n readonly pane_id?: number | string\n readonly is_active?: unknown\n}\n\ntype RawListTab = {\n readonly tab_id?: number | string\n readonly is_active?: unknown\n readonly panes?: RawListPane[]\n}\n\ntype RawListWindow = {\n readonly window_id?: number | string\n readonly is_active?: unknown\n readonly 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 is_active?: unknown\n}\n\ntype RawListResult = {\n readonly windows?: RawListWindow[]\n}\n\nconst parseListResult = (stdout: string): WeztermListResult | undefined => {\n try {\n const parsed: unknown = JSON.parse(stdout)\n\n if (Array.isArray(parsed)) {\n const windowMap = new Map<\n string,\n {\n windowId: string\n isActive: boolean\n tabs: Map<\n string,\n {\n tabId: string\n isActive: boolean\n panes: WeztermListPane[]\n }\n >\n }\n >()\n\n for (const entry of parsed) {\n if (typeof entry !== \"object\" || entry === null) {\n continue\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 continue\n }\n const windowId = windowIdRaw\n const tabId = tabIdRaw\n const paneId = paneIdRaw\n\n let windowRecord = windowMap.get(windowId)\n if (!windowRecord) {\n windowRecord = {\n windowId,\n isActive: false,\n tabs: new Map(),\n }\n windowMap.set(windowId, windowRecord)\n }\n\n let tabRecord = windowRecord.tabs.get(tabId)\n if (!tabRecord) {\n tabRecord = {\n tabId,\n isActive: false,\n panes: [],\n }\n windowRecord.tabs.set(tabId, tabRecord)\n }\n\n const pane: WeztermListPane = {\n paneId,\n isActive: listEntry.is_active === true,\n }\n\n windowRecord.isActive ||= listEntry.is_active === true\n tabRecord.isActive ||= listEntry.is_active === true\n tabRecord.panes.push(pane)\n }\n\n const windows = Array.from(windowMap.values()).map(\n (windowRecord): WeztermListWindow => ({\n windowId: windowRecord.windowId,\n isActive: windowRecord.isActive,\n tabs: Array.from(windowRecord.tabs.values()).map(\n (tabRecord): WeztermListTab => ({\n tabId: tabRecord.tabId,\n isActive: tabRecord.isActive,\n panes: tabRecord.panes.map(\n (pane): WeztermListPane => ({\n paneId: pane.paneId,\n isActive: pane.isActive,\n }),\n ),\n }),\n ),\n }),\n )\n\n return {\n windows,\n }\n }\n\n if (typeof parsed === \"object\" && parsed !== null) {\n const candidate = parsed as Partial<RawListResult>\n const windows = Array.isArray(candidate.windows) ? candidate.windows : []\n const mappedWindows: WeztermListWindow[] = []\n\n for (const window of windows) {\n if (typeof window !== \"object\" || window === null) {\n continue\n }\n const rawWindow = window as RawListWindow\n const windowIdRaw = toIdString(rawWindow.window_id)\n if (!isNonEmptyString(windowIdRaw)) {\n continue\n }\n const windowId = windowIdRaw\n\n const mappedTabs: WeztermListTab[] = []\n const tabs = Array.isArray(rawWindow.tabs) ? rawWindow.tabs : []\n for (const tab of tabs) {\n if (typeof tab !== \"object\" || tab === null) {\n continue\n }\n const rawTab = tab as RawListTab\n const tabIdRaw = toIdString(rawTab.tab_id)\n if (!isNonEmptyString(tabIdRaw)) {\n continue\n }\n const tabId = tabIdRaw\n\n const paneRecords = Array.isArray(rawTab.panes) ? rawTab.panes : []\n const mappedPanes: WeztermListPane[] = []\n for (const pane of paneRecords) {\n if (typeof pane !== \"object\" || pane === null) {\n continue\n }\n const rawPane = pane as RawListPane\n const paneIdRaw = toIdString(rawPane.pane_id)\n if (!isNonEmptyString(paneIdRaw)) {\n continue\n }\n const paneId = paneIdRaw\n\n mappedPanes.push({\n paneId,\n isActive: rawPane.is_active === true,\n })\n }\n\n mappedTabs.push({\n tabId,\n isActive: rawTab.is_active === true,\n panes: mappedPanes,\n })\n }\n\n mappedWindows.push({\n windowId,\n isActive: rawWindow.is_active === true,\n tabs: mappedTabs,\n })\n }\n\n return { windows: mappedWindows }\n }\n\n return undefined\n } catch {\n return undefined\n }\n}\n","import type { PlanEmission, CommandStep, EmittedTerminal } from \"../../core/emitter.ts\"\nimport { createFunctionalError } from \"../../core/errors.ts\"\nimport { ErrorCodes } from \"../../utils/errors.ts\"\nimport type {\n ApplyPlanParameters,\n ApplyPlanResult,\n DryRunStep,\n TerminalBackend,\n TerminalBackendContext,\n} from \"../terminal-backend.ts\"\nimport {\n killWeztermPane,\n listWeztermWindows,\n runWeztermCli,\n verifyWeztermAvailability,\n type RunWeztermErrorContext,\n type WeztermListResult,\n} from \"../../wezterm/cli.ts\"\n\ntype PaneMap = Map<string, string>\n\ntype ExecuteWeztermCommand = (args: ReadonlyArray<string>, errorContext: RunWeztermErrorContext) => Promise<string>\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 ensureVirtualPaneId = (emission: PlanEmission): string => {\n const { initialPaneId } = emission.summary\n if (typeof initialPaneId !== \"string\" || initialPaneId.length === 0) {\n throw createFunctionalError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: \"Plan emission is missing initial pane metadata\",\n path: \"plan.initialPaneId\",\n })\n }\n return initialPaneId\n}\n\nconst 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}\nconst resolveRealPaneId = (paneMap: PaneMap, virtualId: string, context: { readonly stepId: string }): string => {\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 throw createFunctionalError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: `Unknown wezterm pane mapping for ${virtualId}`,\n path: context.stepId,\n })\n}\n\nconst buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n const steps: DryRunStep[] = []\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n const target = step.targetPaneId ?? \"<unknown>\"\n const args = buildSplitArguments({\n targetPaneId: target,\n percent: extractPercent(step.command),\n horizontal: isHorizontalSplit(step.command),\n })\n steps.push({\n backend: \"wezterm\",\n summary: step.summary,\n command: `wezterm cli ${args.join(\" \")}`,\n })\n continue\n }\n\n if (step.kind === \"focus\") {\n const target = step.targetPaneId ?? \"<unknown>\"\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 steps.push({\n backend: \"wezterm\",\n summary: step.summary,\n command: `wezterm cli # ${step.command.join(\" \")}`,\n })\n }\n\n for (const terminal of emission.terminals) {\n const paneId = terminal.virtualPaneId\n if (typeof terminal.cwd === \"string\" && terminal.cwd.length > 0) {\n const cwdCommand = `cd \"${terminal.cwd.split('\"').join('\\\\\"')}\"`\n steps.push({\n backend: \"wezterm\",\n summary: `set cwd for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- '${cwdCommand.replace(/'/g, \"\\\\'\")}'`,\n })\n }\n\n if (terminal.env !== undefined) {\n for (const [key, value] of Object.entries(terminal.env)) {\n const envCommand = `export ${key}=\"${String(value).split('\"').join('\\\\\"')}\"`\n steps.push({\n backend: \"wezterm\",\n summary: `set env ${key} for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- '${envCommand.replace(/'/g, \"\\\\'\")}'`,\n })\n }\n }\n\n if (typeof terminal.command === \"string\" && terminal.command.length > 0) {\n steps.push({\n backend: \"wezterm\",\n summary: `run command for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- '${terminal.command.replace(/'/g, \"\\\\'\")}'`,\n })\n }\n }\n\n return steps\n}\n\nconst resolveCurrentWindow = async (context: {\n readonly list: WeztermListResult\n readonly prompt?: TerminalBackendContext[\"prompt\"]\n readonly dryRun: boolean\n readonly logCommand: (args: ReadonlyArray<string>) => void\n}): Promise<CurrentWindowResolution> => {\n const activeWindow = context.list.windows.find((window) => window.isActive) ?? context.list.windows[0]\n\n if (!activeWindow) {\n throw createFunctionalError(\"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 = activeWindow.tabs.find((tab) => tab.isActive) ?? activeWindow.tabs[0]\n\n if (!activeTab) {\n throw createFunctionalError(\"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 = activeTab.panes.find((pane) => pane.isActive) ?? activeTab.panes[0]\n\n if (!activePane) {\n throw createFunctionalError(\"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 createFunctionalError(\"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\nconst delay = (ms: number): Promise<void> => {\n return new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n}\n\nconst waitForPaneRegistration = async ({\n paneId,\n listWindows,\n windowHint,\n}: {\n readonly paneId: string\n readonly listWindows: () => Promise<WeztermListResult>\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 delay(PANE_REGISTRATION_DELAY_MS)\n }\n }\n\n throw createFunctionalError(\"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 resolveInitialPane = async ({\n windowMode,\n prompt,\n dryRun,\n listWindows,\n runCommand,\n logCommand,\n initialCwd,\n}: {\n readonly windowMode: ApplyPlanParameters[\"windowMode\"]\n readonly prompt?: TerminalBackendContext[\"prompt\"]\n readonly dryRun: boolean\n readonly listWindows: () => Promise<WeztermListResult>\n readonly runCommand: ExecuteWeztermCommand\n readonly logCommand: (args: ReadonlyArray<string>) => void\n readonly initialCwd?: string\n}): Promise<InitialPaneResolution> => {\n if (windowMode === \"current-window\") {\n const list = await listWindows()\n return resolveCurrentWindow({ list, prompt, dryRun, logCommand })\n }\n\n const existing = await listWindows()\n const activeWindow = findActiveWindow(existing)\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 createFunctionalError(\"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 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 createFunctionalError(\"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\nconst collectPaneIdsForWindow = (list: WeztermListResult, windowId: string): Set<string> => {\n const targetWindow = list.windows.find((window) => window.windowId === windowId)\n if (!targetWindow) {\n throw createFunctionalError(\"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 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\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 isHorizontalSplit = (command: ReadonlyArray<string>): boolean => {\n return command.includes(\"-h\")\n}\n\nconst extractPercent = (command: ReadonlyArray<string>): string => {\n const index = command.findIndex((segment) => segment === \"-p\")\n if (index >= 0 && index + 1 < command.length) {\n const value = command[index + 1]\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim()\n }\n }\n return \"50\"\n}\n\nconst buildSplitArguments = (params: {\n readonly targetPaneId: string\n readonly percent: string\n readonly horizontal: boolean\n}): string[] => {\n const directionFlag = params.horizontal ? \"--right\" : \"--bottom\"\n return [\"split-pane\", directionFlag, \"--percent\", params.percent, \"--pane-id\", params.targetPaneId]\n}\n\nconst 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 createFunctionalError(\"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\nconst escapeDoubleQuotes = (value: string): string => {\n return value.split('\"').join('\\\\\"')\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\nconst applyTerminalCommands = async ({\n terminals,\n paneMap,\n runCommand,\n}: {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly paneMap: PaneMap\n readonly runCommand: ExecuteWeztermCommand\n}): Promise<void> => {\n for (const terminal of terminals) {\n const realPaneId = resolveRealPaneId(paneMap, terminal.virtualPaneId, { stepId: terminal.virtualPaneId })\n\n if (typeof terminal.cwd === \"string\" && terminal.cwd.length > 0) {\n const escapedCwd = escapeDoubleQuotes(terminal.cwd)\n await sendTextToPane({\n paneId: realPaneId,\n text: `cd \"${escapedCwd}\"`,\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 if (terminal.env !== undefined) {\n for (const [key, value] of Object.entries(terminal.env)) {\n const escapedValue = escapeDoubleQuotes(String(value))\n await sendTextToPane({\n paneId: realPaneId,\n text: `export ${key}=\"${escapedValue}\"`,\n runCommand,\n context: {\n message: `Failed to set environment variable ${key}`,\n path: terminal.virtualPaneId,\n },\n })\n }\n }\n\n if (typeof terminal.command === \"string\" && terminal.command.length > 0) {\n await sendTextToPane({\n paneId: realPaneId,\n text: terminal.command,\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\nconst applySplitStep = async ({\n step,\n paneMap,\n windowId,\n runCommand,\n listWindows,\n logPaneMapping,\n}: {\n readonly step: CommandStep\n readonly paneMap: PaneMap\n readonly windowId: string\n readonly runCommand: ExecuteWeztermCommand\n readonly listWindows: () => Promise<WeztermListResult>\n readonly logPaneMapping: (virtualId: string, realId: string) => void\n}): Promise<void> => {\n const targetVirtualId = step.targetPaneId\n if (typeof targetVirtualId !== \"string\" || targetVirtualId.length === 0) {\n throw createFunctionalError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: \"Split step missing target pane metadata\",\n path: step.id,\n })\n }\n\n const targetRealId = resolveRealPaneId(paneMap, targetVirtualId, { stepId: step.id })\n\n const beforeList = await listWindows()\n const beforePaneIds = collectPaneIdsForWindow(beforeList, windowId)\n\n const args = buildSplitArguments({\n targetPaneId: targetRealId,\n percent: extractPercent(step.command),\n horizontal: isHorizontalSplit(step.command),\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 createFunctionalError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"Unable to determine newly created wezterm pane\",\n path: step.id,\n })\n }\n\n if (typeof step.createdPaneId === \"string\" && step.createdPaneId.length > 0) {\n registerPaneWithAncestors(paneMap, step.createdPaneId, newPaneId)\n logPaneMapping(step.createdPaneId, newPaneId)\n }\n}\n\nexport const createWeztermBackend = (context: TerminalBackendContext): TerminalBackend => {\n const formatCommand = (args: ReadonlyArray<string>): string => {\n return `wezterm cli ${args.join(\" \")}`\n }\n\n const logCommand = (args: ReadonlyArray<string>): void => {\n const message = `[wezterm] ${formatCommand(args)}`\n if (context.verbose) {\n context.logger.info(message)\n } else {\n context.logger.debug(message)\n }\n }\n\n const logPaneMapping = (virtualId: string, realId: string): void => {\n const message = `[wezterm] pane ${virtualId} -> ${realId}`\n if (context.verbose) {\n context.logger.info(message)\n } else {\n context.logger.debug(message)\n }\n }\n\n const runCommand: ExecuteWeztermCommand = async (args, errorContext) => {\n const commandArgs = [...args]\n logCommand(commandArgs)\n return runWeztermCli(commandArgs, errorContext)\n }\n\n const listWindows = async (): Promise<WeztermListResult> => {\n logCommand([\"list\", \"--format\", \"json\"])\n return listWeztermWindows()\n }\n\n const verifyEnvironment = async (): Promise<void> => {\n if (context.dryRun) {\n return\n }\n await verifyWeztermAvailability()\n }\n\n const applyPlan = async ({ emission, windowMode }: ApplyPlanParameters): Promise<ApplyPlanResult> => {\n const initialVirtualPaneId = ensureVirtualPaneId(emission)\n const paneMap: PaneMap = new Map()\n const initialTerminal = emission.terminals.find((terminal) => terminal.virtualPaneId === initialVirtualPaneId)\n const initialCwd =\n typeof initialTerminal?.cwd === \"string\" && initialTerminal.cwd.length > 0 ? initialTerminal.cwd : context.cwd\n\n 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 })\n registerPaneWithAncestors(paneMap, initialVirtualPaneId, initialPaneId)\n logPaneMapping(initialVirtualPaneId, initialPaneId)\n\n let executedSteps = 0\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n await applySplitStep({\n step,\n paneMap,\n windowId,\n runCommand,\n listWindows,\n logPaneMapping,\n })\n executedSteps += 1\n } else if (step.kind === \"focus\") {\n await applyFocusStep({\n step,\n paneMap,\n runCommand,\n })\n executedSteps += 1\n }\n }\n\n await applyTerminalCommands({\n terminals: emission.terminals,\n paneMap,\n runCommand,\n })\n\n const focusVirtual = emission.summary.focusPaneId\n const focusPaneId = typeof focusVirtual === \"string\" ? paneMap.get(focusVirtual) : undefined\n\n return {\n executedSteps,\n focusPaneId,\n }\n }\n\n return {\n verifyEnvironment,\n applyPlan,\n getDryRunSteps: buildDryRunSteps,\n }\n}\n","import type { TerminalBackend, TerminalBackendContext, TerminalBackendKind } from \"./terminal-backend.ts\"\nimport { createTmuxBackend } from \"./backends/tmux-backend.ts\"\nimport { createWeztermBackend } from \"./backends/wezterm-backend.ts\"\n\nexport const createTerminalBackend = (kind: TerminalBackendKind, context: TerminalBackendContext): TerminalBackend => {\n if (kind === \"tmux\") {\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.ts\"\n\ntype ResolveBackendOptions = {\n readonly cliFlag?: TerminalBackendKind\n readonly env: NodeJS.ProcessEnv\n}\n\nconst KNOWN_BACKENDS: TerminalBackendKind[] = [\"tmux\", \"wezterm\"]\n\nexport const resolveTerminalBackendKind = ({ cliFlag, env }: ResolveBackendOptions): TerminalBackendKind => {\n if (cliFlag !== undefined) {\n if (!KNOWN_BACKENDS.includes(cliFlag)) {\n throw new Error(`Unknown backend \"${cliFlag}\"`)\n }\n return cliFlag\n }\n\n if (typeof env.TMUX === \"string\" && env.TMUX.trim().length > 0) {\n return \"tmux\"\n }\n\n return \"tmux\"\n}\n","import { parse } from \"yaml\"\n\nexport type DiagnosticsSeverity = \"high\" | \"medium\" | \"low\"\n\ntype DiagnosticsFinding = {\n readonly path: string\n readonly severity: DiagnosticsSeverity\n readonly description: string\n}\n\ntype DiagnosticsBacklogItem = {\n readonly id: string\n readonly severity: DiagnosticsSeverity\n readonly summary: string\n readonly actions: ReadonlyArray<string>\n}\n\nexport type DiagnosticsReport = {\n readonly findings: ReadonlyArray<DiagnosticsFinding>\n readonly nextSteps: ReadonlyArray<string>\n readonly backlog: ReadonlyArray<DiagnosticsBacklogItem>\n}\n\ntype DiagnosticsInput = {\n readonly presetDocument: string\n readonly knownIssues?: ReadonlyArray<string>\n}\n\nconst severityRank: Record<DiagnosticsSeverity, number> = {\n high: 3,\n medium: 2,\n low: 1,\n}\n\ntype FindingAccumulator = {\n add: (args: { path: string; severity: DiagnosticsSeverity; description: string; nextStep?: string }) => void\n readonly findings: DiagnosticsFinding[]\n readonly nextSteps: Set<string>\n readonly backlog: Map<string, DiagnosticsBacklogItem>\n}\n\nconst createAccumulator = (): FindingAccumulator => {\n const findings: DiagnosticsFinding[] = []\n const nextSteps = new Set<string>()\n const backlog = new Map<string, DiagnosticsBacklogItem>()\n\n return {\n findings,\n nextSteps,\n backlog,\n add: ({ path, severity, description, nextStep }): void => {\n findings.push({ path, severity, description })\n if (typeof nextStep === \"string\" && nextStep.length > 0) {\n nextSteps.add(nextStep)\n }\n\n const existing = backlog.get(path)\n const existingActions = new Set(existing?.actions ?? [])\n existingActions.add(description)\n if (typeof nextStep === \"string\" && nextStep.length > 0) {\n existingActions.add(nextStep)\n }\n\n const mergedSeverity = existing !== undefined ? maxSeverity(existing.severity, severity) : severity\n\n const summary =\n existing !== undefined && severityRank[existing.severity] >= severityRank[severity]\n ? existing.summary\n : description\n\n backlog.set(path, {\n id: path,\n severity: mergedSeverity,\n summary,\n actions: Array.from(existingActions),\n })\n },\n }\n}\n\nexport const runDiagnostics = (input: DiagnosticsInput): DiagnosticsReport => {\n const accumulator = createAccumulator()\n const knownIssues = input.knownIssues ?? []\n let parsedPreset: unknown\n\n try {\n parsedPreset = parse(input.presetDocument)\n } catch (error) {\n accumulator.add({\n path: \"presetDocument\",\n severity: \"high\",\n description: `プリセットYAMLの解析に失敗しました: ${(error as Error).message}`,\n nextStep: \"プリセットYAMLを構文チェックし、Functional Coreリライト前に整合性を確保する\",\n })\n return {\n findings: sortBySeverity(accumulator.findings),\n nextSteps: Array.from(accumulator.nextSteps),\n backlog: sortBacklog(accumulator.backlog),\n }\n }\n\n if (parsedPreset === null || typeof parsedPreset !== \"object\") {\n accumulator.add({\n path: \"preset\",\n severity: \"high\",\n description: \"プリセット定義がオブジェクト形式ではありません\",\n nextStep: \"プリセットYAMLをオブジェクト構造に整形し整合性を確保する\",\n })\n } else {\n const presetObject = parsedPreset as Record<string, unknown>\n checkFocusDuplications(presetObject, accumulator)\n collectLowPrioritySignals(presetObject, accumulator)\n }\n\n knownIssues.forEach((issue, index) => {\n const trimmed = issue.trim()\n if (trimmed.length === 0) {\n return\n }\n\n accumulator.add({\n path: `codebase.knownIssues[${index}]`,\n severity: \"medium\",\n description: trimmed,\n nextStep: `tmux依存や副作用をFunctional Core境界で切り離す: ${trimmed}`,\n })\n })\n\n return {\n findings: sortBySeverity(accumulator.findings),\n nextSteps: Array.from(accumulator.nextSteps),\n backlog: sortBacklog(accumulator.backlog),\n }\n}\n\nconst checkFocusDuplications = (preset: Record<string, unknown>, accumulator: FindingAccumulator): void => {\n const layout = preset.layout as unknown\n if (layout === undefined || layout === null) {\n return\n }\n\n const focusCount = countFocusFlags(layout)\n if (focusCount > 1) {\n accumulator.add({\n path: \"preset.layout\",\n severity: \"high\",\n description: \"複数のペインでfocus: trueが指定されています\",\n nextStep: \"focusは単一ペインに限定しPlan生成時に一貫するようFunctional Coreで制御する\",\n })\n }\n}\n\nconst collectLowPrioritySignals = (preset: Record<string, unknown>, accumulator: FindingAccumulator): void => {\n const layout = preset.layout as Record<string, unknown> | undefined | null\n if (layout === undefined || layout === null) {\n accumulator.add({\n path: \"preset.layout\",\n severity: \"low\",\n description: \"layout定義が存在しません(単一ペイン運用が前提)\",\n nextStep: \"単一ペイン前提でもPlan出力に影響しないことをFunctional Coreで確認する\",\n })\n return\n }\n\n if (!Array.isArray(layout.panes)) {\n accumulator.add({\n path: \"preset.layout.panes\",\n severity: \"low\",\n description: \"panes配列が存在しないか配列ではありません\",\n nextStep: \"レイアウト定義の構造を正規化し、Plan生成の入力契約を明示する\",\n })\n }\n}\n\nconst countFocusFlags = (node: unknown): number => {\n if (Array.isArray(node)) {\n return node.reduce((sum, child) => sum + countFocusFlags(child), 0)\n }\n\n if (node === null || typeof node !== \"object\") {\n return 0\n }\n\n const record = node as Record<string, unknown>\n const selfFocus = record.focus === true ? 1 : 0\n const childFocus = Array.isArray(record.panes)\n ? record.panes.reduce((sum, child) => sum + countFocusFlags(child), 0)\n : 0\n\n return selfFocus + childFocus\n}\n\nconst sortBySeverity = (findings: DiagnosticsFinding[]): DiagnosticsFinding[] => {\n return [...findings].sort((a, b) => severityRank[b.severity] - severityRank[a.severity])\n}\n\nconst sortBacklog = (backlog: Map<string, DiagnosticsBacklogItem>): DiagnosticsBacklogItem[] => {\n return [...backlog.values()].sort((a, b) => severityRank[b.severity] - severityRank[a.severity])\n}\n\nconst maxSeverity = (left: DiagnosticsSeverity, right: DiagnosticsSeverity): DiagnosticsSeverity => {\n return severityRank[left] >= severityRank[right] ? left : right\n}\n","import { parse } from \"yaml\"\nimport { createFunctionalError, type FunctionalCoreError } from \"./errors.ts\"\n\nexport type CompilePresetInput = {\n readonly document: string\n readonly source: string\n}\n\nexport type FunctionalTerminalPane = {\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 focus?: boolean\n readonly options?: Readonly<Record<string, unknown>>\n}\n\nexport type FunctionalSplitPane = {\n readonly kind: \"split\"\n readonly orientation: \"horizontal\" | \"vertical\"\n readonly ratio: ReadonlyArray<number>\n readonly panes: ReadonlyArray<FunctionalLayoutNode>\n}\n\nexport type FunctionalLayoutNode = FunctionalTerminalPane | FunctionalSplitPane\n\ntype FunctionalPresetMetadata = {\n readonly source: string\n}\n\nexport type FunctionalPreset = {\n readonly name: string\n readonly version: string\n readonly command?: string\n readonly layout?: FunctionalLayoutNode\n readonly metadata: FunctionalPresetMetadata\n}\n\nexport type CompilePresetSuccess = {\n readonly preset: FunctionalPreset\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: `YAMLの解析に失敗しました: ${(error as Error).message}`,\n details: {\n reason: error instanceof Error ? error.message : String(error),\n },\n })\n }\n\n if (!isRecord(parsed)) {\n throw compileError(\"PRESET_INVALID_DOCUMENT\", {\n source,\n message: \"プリセット定義がオブジェクトではありません\",\n path: \"preset\",\n })\n }\n\n const name = typeof parsed.name === \"string\" && parsed.name.trim().length > 0 ? parsed.name : \"Unnamed preset\"\n\n const layout = parseLayoutNode(parsed.layout, {\n source,\n path: \"preset.layout\",\n })\n\n return {\n preset: {\n name,\n version: \"legacy\",\n command: typeof parsed.command === \"string\" ? parsed.command : undefined,\n layout: layout ?? undefined,\n metadata: { source },\n },\n }\n}\n\nconst parseLayoutNode = (\n node: unknown,\n context: { readonly source: string; readonly path: string },\n): FunctionalLayoutNode | 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: \"レイアウトノードの形式が不正です\",\n path: context.path,\n details: { node },\n })\n }\n\n if (typeof node.type === \"string\" && Array.isArray(node.panes)) {\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: \"レイアウトノードの形式が不正です\",\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): FunctionalSplitPane => {\n const orientation = node.type\n if (orientation !== \"horizontal\" && orientation !== \"vertical\") {\n throw compileError(\"LAYOUT_INVALID_ORIENTATION\", {\n source: context.source,\n message: \"layout.type は horizontal か vertical である必要があります\",\n path: `${context.path}.type`,\n details: { type: orientation },\n })\n }\n\n if (!Array.isArray(node.panes) || node.panes.length === 0) {\n throw compileError(\"LAYOUT_PANES_MISSING\", {\n source: context.source,\n message: \"panes 配列が存在しません\",\n path: `${context.path}.panes`,\n })\n }\n\n if (!Array.isArray(node.ratio) || node.ratio.length === 0) {\n throw compileError(\"LAYOUT_RATIO_MISSING\", {\n source: context.source,\n message: \"ratio 配列が存在しません\",\n path: `${context.path}.ratio`,\n })\n }\n\n if (node.ratio.length !== node.panes.length) {\n throw compileError(\"LAYOUT_RATIO_MISMATCH\", {\n source: context.source,\n message: \"ratio 配列と panes 配列の長さが一致しません\",\n path: context.path,\n details: {\n ratioLength: node.ratio.length,\n panesLength: node.panes.length,\n },\n })\n }\n\n const ratio = node.ratio.map((value, index) => {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n throw compileError(\"RATIO_INVALID_VALUE\", {\n source: context.source,\n message: \"ratio の値が正の数値ではありません\",\n path: `${context.path}.ratio[${index}]`,\n details: { value },\n })\n }\n return value\n })\n\n const panes = node.panes.map((child, index) =>\n parseLayoutNode(child, {\n source: context.source,\n path: `${context.path}.panes[${index}]`,\n }),\n )\n\n return {\n kind: \"split\",\n orientation,\n ratio,\n panes: panes.filter((pane): pane is FunctionalLayoutNode => pane !== null),\n }\n}\n\nconst parseTerminalPane = (node: Record<string, unknown>): FunctionalTerminalPane => {\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 focus = node.focus === true ? true : undefined\n const env = normalizeEnv(node.env)\n\n const knownKeys = new Set([\"name\", \"command\", \"cwd\", \"env\", \"focus\", \"options\", \"title\", \"delay\"])\n const options = collectOptions(node, knownKeys)\n\n return {\n kind: \"terminal\",\n name,\n command,\n cwd,\n env,\n focus,\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 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): FunctionalCoreError => {\n return createFunctionalError(\"compile\", {\n code,\n message: error.message,\n source: error.source,\n path: error.path,\n details: error.details,\n })\n}\n","import type { FunctionalLayoutNode, FunctionalPreset, FunctionalSplitPane, FunctionalTerminalPane } from \"./compile.ts\"\nimport { createFunctionalError, type FunctionalCoreError } from \"./errors.ts\"\n\ntype CreateLayoutPlanInput = {\n readonly preset: FunctionalPreset\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 focus: boolean\n readonly options?: Readonly<Record<string, unknown>>\n}\n\ntype PlanSplit = {\n readonly kind: \"split\"\n readonly id: string\n readonly orientation: \"horizontal\" | \"vertical\"\n readonly ratio: ReadonlyArray<number>\n readonly panes: ReadonlyArray<PlanNode>\n}\n\nexport type PlanNode = PlanTerminal | PlanSplit\n\nexport type LayoutPlan = {\n readonly root: PlanNode\n readonly focusPaneId: string\n}\n\nexport type CreateLayoutPlanSuccess = {\n readonly plan: LayoutPlan\n}\n\nexport const createLayoutPlan = ({ preset }: CreateLayoutPlanInput): CreateLayoutPlanSuccess => {\n if (!preset.layout) {\n const terminal = createTerminalNode({\n id: \"root\",\n terminal: {\n kind: \"terminal\",\n name: preset.name,\n command: preset.command,\n },\n focusOverride: true,\n })\n\n return {\n plan: {\n root: terminal,\n focusPaneId: terminal.id,\n },\n }\n }\n\n const { node, focusPaneIds, terminalPaneIds } = buildLayoutNode(preset.layout, {\n parentId: \"root\",\n path: \"preset.layout\",\n source: preset.metadata.source,\n })\n\n if (focusPaneIds.length > 1) {\n throw planError(\"FOCUS_CONFLICT\", {\n message: \"複数のペインでfocusが指定されています\",\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: \"ターミナルペインが存在しません\",\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: FunctionalLayoutNode,\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: FunctionalSplitPane,\n context: { readonly parentId: string; readonly path: string; readonly source: string },\n): BuildResult => {\n const ratio = normalizeRatio(node.ratio, context)\n\n const panes: PlanNode[] = []\n const focusPaneIds: string[] = []\n const terminalPaneIds: string[] = []\n\n for (let index = 0; index < node.panes.length; index += 1) {\n const childId = `${context.parentId}.${index}`\n const childContext = {\n parentId: childId,\n path: `${context.path}.panes[${index}]`,\n source: context.source,\n }\n\n const childResult = buildLayoutNode(node.panes[index]!, childContext)\n panes.push(childResult.node)\n focusPaneIds.push(...childResult.focusPaneIds)\n terminalPaneIds.push(...childResult.terminalPaneIds)\n }\n\n return {\n node: {\n kind: \"split\",\n id: context.parentId,\n orientation: node.orientation,\n ratio,\n panes,\n },\n focusPaneIds,\n terminalPaneIds,\n }\n}\n\nconst createTerminalNode = ({\n id,\n terminal,\n focusOverride,\n}: {\n readonly id: string\n readonly terminal: FunctionalTerminalPane\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 options: terminal.options,\n focus: focusOverride === true ? true : terminal.focus === true,\n }\n}\n\nconst ensureFocus = (node: PlanNode, focusPaneId: string): PlanNode => {\n if (node.kind === \"terminal\") {\n return {\n ...node,\n focus: node.id === focusPaneId,\n }\n }\n\n return {\n ...node,\n panes: node.panes.map((pane) => ensureFocus(pane, focusPaneId)),\n }\n}\n\nconst normalizeRatio = (\n ratio: ReadonlyArray<number>,\n context: { readonly path: string; readonly source: string },\n): number[] => {\n const total = ratio.reduce((sum, value, index) => {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n throw planError(\"RATIO_INVALID_VALUE\", {\n message: \"ratio の値が非負の数値ではありません\",\n path: `${context.path}.ratio[${index}]`,\n source: context.source,\n details: { value },\n })\n }\n return sum + value\n }, 0)\n\n if (total === 0) {\n return ratio.map(() => 1 / ratio.length)\n }\n\n return ratio.map((value) => value / total)\n}\n\nconst planError = (\n code: string,\n error: {\n readonly message: string\n readonly source?: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n },\n): FunctionalCoreError => {\n return createFunctionalError(\"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.ts\"\n\ntype EmitPlanInput = {\n readonly plan: LayoutPlan\n}\n\ntype CommandStepKind = \"split\" | \"focus\"\n\nexport type CommandStep = {\n readonly id: string\n readonly kind: CommandStepKind\n readonly command: ReadonlyArray<string>\n readonly summary: string\n readonly targetPaneId?: string\n readonly createdPaneId?: string\n}\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 focus: boolean\n readonly name: string\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 command: [\"select-pane\", \"-t\", plan.focusPaneId],\n summary: `select pane ${plan.focusPaneId}`,\n targetPaneId: plan.focusPaneId,\n })\n\n const hash = createPlanHash(plan, steps)\n const initialPaneId = determineInitialPaneId(plan.root)\n const terminals = collectTerminals(plan.root)\n\n return {\n steps,\n summary: {\n stepsCount: steps.length,\n focusPaneId: plan.focusPaneId,\n initialPaneId,\n },\n terminals,\n hash,\n }\n}\n\nconst collectSplitSteps = (node: PlanNode, steps: CommandStep[]): void => {\n if (node.kind === \"terminal\") {\n return\n }\n\n appendSplitSteps(node, steps)\n node.panes.forEach((pane) => collectSplitSteps(pane, steps))\n}\n\nconst appendSplitSteps = (node: SplitNode, steps: CommandStep[]): void => {\n const directionFlag = node.orientation === \"horizontal\" ? \"-h\" : \"-v\"\n\n for (let index = 1; index < node.panes.length; index += 1) {\n const remainingIncludingTarget = node.ratio.slice(index - 1).reduce((sum, value) => sum + value, 0)\n const remainingAfterTarget = node.ratio.slice(index).reduce((sum, value) => sum + value, 0)\n\n const desiredPercentage =\n remainingIncludingTarget === 0 ? 0 : (remainingAfterTarget / remainingIncludingTarget) * 100\n const percentage = Math.max(1, Math.round(desiredPercentage))\n const targetPaneId = node.panes[index - 1]?.id ?? node.id\n const createdPaneId = node.panes[index]?.id\n\n steps.push({\n id: `${node.id}:split:${index}`,\n kind: \"split\",\n command: [\"split-window\", directionFlag, \"-t\", targetPaneId, \"-p\", String(Math.min(percentage, 99))],\n summary: `split ${targetPaneId} (${directionFlag})`,\n targetPaneId,\n createdPaneId,\n })\n }\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 focus: node.focus,\n name: node.name,\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 { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { stringify as toYAML } from \"yaml\"\nimport { createRequire } from \"module\"\nimport { createPresetManager } from \"./layout/preset.ts\"\nimport { resolveWindowMode } from \"./cli/window-mode.ts\"\nimport { createPaneKillPrompter } from \"./cli/user-prompt.ts\"\nimport type { Preset, PresetInfo, WindowMode } from \"./models/types\"\nimport type { CommandExecutor } from \"./types/command-executor.ts\"\nimport type { PresetManager } from \"./types/preset-manager.ts\"\nimport { createRealExecutor, createDryRunExecutor } from \"./executor/index.ts\"\nimport { createTerminalBackend } from \"./executor/backend-factory.ts\"\nimport { resolveTerminalBackendKind } from \"./executor/backend-resolver.ts\"\nimport type { DryRunStep, TerminalBackendKind } from \"./executor/terminal-backend.ts\"\nimport { createLogger, LogLevel, type Logger } from \"./utils/logger.ts\"\nimport {\n runDiagnostics,\n compilePreset as defaultCompilePreset,\n createLayoutPlan as defaultCreateLayoutPlan,\n emitPlan as defaultEmitPlan,\n} from \"./core/index.ts\"\nimport type {\n DiagnosticsReport,\n DiagnosticsSeverity,\n CompilePresetInput,\n PlanEmission,\n FunctionalCoreError,\n CompilePresetSuccess,\n CreateLayoutPlanSuccess,\n} from \"./core/index.ts\"\nimport { isFunctionalCoreError } from \"./core/index.ts\"\n\nconst KNOWN_ISSUES: ReadonlyArray<string> = [\n \"LayoutEngineがtmux依存とI/Oを同一クラスで扱っている\",\n \"dry-run実行と本番適用でPlan構造が共有されていない\",\n \"Loggerが境界層とFunctional Coreの責務を混在させている\",\n]\n\nconst formatSeverityTag = (severity: DiagnosticsSeverity): string => {\n switch (severity) {\n case \"high\":\n return chalk.red(\"[HIGH]\")\n case \"medium\":\n return chalk.yellow(\"[MEDIUM]\")\n case \"low\":\n default:\n return chalk.blue(\"[LOW]\")\n }\n}\n\nexport type FunctionalCoreBridge = {\n readonly compilePreset: (input: CompilePresetInput) => ReturnType<typeof defaultCompilePreset>\n readonly createLayoutPlan: (\n input: Parameters<typeof defaultCreateLayoutPlan>[0],\n ) => ReturnType<typeof defaultCreateLayoutPlan>\n readonly emitPlan: (input: Parameters<typeof defaultEmitPlan>[0]) => ReturnType<typeof defaultEmitPlan>\n}\n\nexport type CLIOptions = {\n readonly presetManager?: PresetManager\n readonly createCommandExecutor?: (options: { verbose: boolean; dryRun: boolean }) => CommandExecutor\n readonly functionalCore?: FunctionalCoreBridge\n}\n\nexport type CLI = {\n run(args?: string[]): Promise<void>\n}\n\nexport const createCli = (options: CLIOptions = {}): CLI => {\n const presetManager = options.presetManager ?? createPresetManager()\n const createCommandExecutor =\n options.createCommandExecutor ??\n ((opts: { verbose: boolean; dryRun: boolean }): CommandExecutor => {\n if (opts.dryRun) {\n return createDryRunExecutor({ verbose: opts.verbose })\n }\n return createRealExecutor({ verbose: opts.verbose })\n })\n\n const functionalCore: FunctionalCoreBridge =\n options.functionalCore ??\n ({\n compilePreset: defaultCompilePreset,\n createLayoutPlan: defaultCreateLayoutPlan,\n emitPlan: defaultEmitPlan,\n } as const)\n\n const program = new Command()\n const require = createRequire(import.meta.url)\n const { version } = require(\"../package.json\") as { version: string }\n let logger: Logger = createLogger()\n\n const renderDiagnosticsReport = (report: DiagnosticsReport): void => {\n console.log(chalk.bold(\"\\nFunctional Core Diagnostics\\n\"))\n\n if (report.backlog.length > 0) {\n console.log(chalk.bold(\"改善バックログ\"))\n report.backlog.forEach((item, index) => {\n const prefix = `${index + 1}. ${formatSeverityTag(item.severity)}`\n console.log(`${prefix} ${item.summary}`)\n item.actions.forEach((action) => {\n console.log(` - ${action}`)\n })\n })\n console.log(\"\")\n }\n\n if (report.findings.length > 0) {\n console.log(chalk.bold(\"診断結果\"))\n report.findings.forEach((finding) => {\n console.log(`${formatSeverityTag(finding.severity)} ${finding.path} :: ${finding.description}`)\n })\n console.log(\"\")\n }\n\n if (report.nextSteps.length > 0) {\n console.log(chalk.bold(\"次のアクション\"))\n report.nextSteps.forEach((step) => {\n console.log(` - ${step}`)\n })\n console.log(\"\")\n }\n }\n\n const renderDryRun = (steps: ReadonlyArray<DryRunStep>): void => {\n console.log(chalk.bold(\"\\nPlanned terminal steps (dry-run)\"))\n steps.forEach((step, index) => {\n console.log(` ${index + 1}. [${step.backend}] ${step.summary}: ${step.command}`)\n })\n }\n\n const buildPresetDocument = (preset: Preset, presetName?: string): string => {\n const document: Record<string, unknown> = {\n name: preset.name ?? presetName ?? \"vde-layout\",\n command: preset.command,\n layout: preset.layout,\n }\n\n if (typeof preset.command !== \"string\" || preset.command.length === 0) {\n delete document.command\n }\n\n if (preset.layout === undefined || preset.layout === null) {\n delete document.layout\n }\n\n return toYAML(document)\n }\n\n const buildPresetSource = (presetName?: string): string => {\n return typeof presetName === \"string\" && presetName.length > 0 ? `preset://${presetName}` : \"preset://default\"\n }\n\n 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\n const handleFunctionalError = (error: FunctionalCoreError): never => {\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 logger.error(lines.join(\"\\n\"))\n process.exit(1)\n }\n\n const handleError = (error: unknown): never => {\n if (error instanceof Error) {\n logger.error(error.message, error)\n } else {\n logger.error(\"An unexpected error occurred\")\n }\n\n process.exit(1)\n }\n\n const handlePipelineFailure = (error: unknown): never => {\n if (isFunctionalCoreError(error)) {\n return handleFunctionalError(error)\n }\n return handleError(error)\n }\n\n const listPresets = async (): Promise<never> => {\n try {\n await presetManager.loadConfig()\n const presets = presetManager.listPresets()\n\n if (presets.length === 0) {\n logger.warn(\"No presets defined\")\n process.exit(0)\n }\n\n console.log(chalk.bold(\"Available presets:\\n\"))\n\n const maxKeyLength = Math.max(...presets.map((p) => p.key.length))\n\n presets.forEach((preset: PresetInfo) => {\n const paddedKey = preset.key.padEnd(maxKeyLength + 2)\n const description = preset.description ?? \"\"\n console.log(` ${chalk.cyan(paddedKey)} ${description}`)\n })\n\n process.exit(0)\n } catch (error) {\n return handleError(error)\n }\n }\n\n const diagnosePreset = async (presetName: string | undefined): Promise<never> => {\n try {\n await presetManager.loadConfig()\n const preset =\n typeof presetName === \"string\" && presetName.length > 0\n ? presetManager.getPreset(presetName)\n : presetManager.getDefaultPreset()\n\n const presetDocument = toYAML(preset ?? {})\n const report = runDiagnostics({\n presetDocument,\n knownIssues: KNOWN_ISSUES,\n })\n\n renderDiagnosticsReport(report)\n process.exit(0)\n } catch (error) {\n return handleError(error)\n }\n }\n\n const executePreset = async (\n presetName: string | undefined,\n options: {\n verbose: boolean\n dryRun: boolean\n currentWindow: boolean\n newWindow: boolean\n backend?: string\n },\n ): Promise<never> => {\n try {\n await presetManager.loadConfig()\n\n const preset =\n typeof presetName === \"string\" && presetName.length > 0\n ? presetManager.getPreset(presetName)\n : presetManager.getDefaultPreset()\n\n const cliWindowMode = determineCliWindowMode({\n currentWindow: options.currentWindow,\n newWindow: options.newWindow,\n })\n const defaults = presetManager.getDefaults()\n const windowModeResolution = resolveWindowMode({\n cli: cliWindowMode,\n preset: preset.windowMode,\n defaults: defaults?.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 env: process.env,\n })\n logger.info(`Terminal backend: ${backendKind}`)\n\n const backend = createTerminalBackend(backendKind, {\n executor,\n logger,\n dryRun: options.dryRun,\n verbose: options.verbose,\n prompt: confirmPaneClosure,\n cwd: process.cwd(),\n })\n\n await backend.verifyEnvironment()\n\n if (options.dryRun === true) {\n console.log(\"[DRY RUN] No actual commands will be executed\")\n }\n\n let compileResult: CompilePresetSuccess\n let planResult: CreateLayoutPlanSuccess\n let emission: PlanEmission\n\n try {\n compileResult = functionalCore.compilePreset({\n document: buildPresetDocument(preset, presetName),\n source: buildPresetSource(presetName),\n })\n planResult = functionalCore.createLayoutPlan({ preset: compileResult.preset })\n emission = functionalCore.emitPlan({ plan: planResult.plan })\n } catch (error) {\n return handlePipelineFailure(error)\n }\n\n if (options.dryRun === true) {\n const dryRunSteps = backend.getDryRunSteps(emission)\n renderDryRun(dryRunSteps)\n } else {\n try {\n const executionResult = await backend.applyPlan({\n emission,\n windowMode,\n windowName: preset.name ?? presetName ?? \"vde-layout\",\n })\n logger.info(`Executed ${executionResult.executedSteps} ${backendKind} steps`)\n } catch (error) {\n return handlePipelineFailure(error)\n }\n }\n\n logger.success(`✓ Applied preset \"${preset.name}\"`)\n process.exit(0)\n } catch (error) {\n return handleError(error)\n }\n }\n\n const setupProgram = (): void => {\n program\n .name(\"vde-layout\")\n .description(\"VDE (Vibrant Development Environment) Layout Manager - tmux pane layout management tool\")\n .version(version, \"-v, --version\", \"Show version\")\n .helpOption(\"-h, --help\", \"Show help\")\n\n program.option(\"--verbose\", \"Show detailed logs\", false)\n program.option(\"-V\", \"Show version (deprecated; use -v)\")\n program.option(\"--dry-run\", \"Display commands without executing\", false)\n program.option(\"--backend <backend>\", \"Select terminal backend (tmux or wezterm)\")\n program.option(\"--config <path>\", \"Path to configuration file\")\n program.option(\"--current-window\", \"Use the current tmux window for layout (kills other panes)\", false)\n program.option(\"--new-window\", \"Always create a new tmux window for layout\", false)\n\n program\n .command(\"list\")\n .description(\"List available presets\")\n .action(async () => {\n await listPresets()\n })\n\n program\n .command(\"diagnose\")\n .description(\"Functional Coreリライトに向けた診断レポートを表示する\")\n .argument(\"[preset]\", 'Preset name (defaults to \"default\" preset when omitted)')\n .action(async (presetName?: string) => {\n await diagnosePreset(presetName)\n })\n\n program\n .argument(\"[preset]\", 'Preset name (defaults to \"default\" preset when omitted)')\n .action(async (presetName?: string) => {\n const opts = program.opts<{\n verbose?: boolean\n dryRun?: boolean\n currentWindow?: boolean\n newWindow?: boolean\n backend?: string\n }>()\n await executePreset(presetName, {\n verbose: opts.verbose === true,\n dryRun: opts.dryRun === true,\n currentWindow: opts.currentWindow === true,\n newWindow: opts.newWindow === true,\n backend: opts.backend,\n })\n })\n }\n\n setupProgram()\n\n const run = async (args: string[] = process.argv.slice(2)): Promise<void> => {\n if (args.includes(\"-V\")) {\n console.log(version)\n return\n }\n\n const requestedVersion = args.some((arg) => arg === \"--version\" || arg === \"-v\")\n const requestedHelp = args.includes(\"--help\") || args.includes(\"-h\")\n try {\n await program.parseAsync(args, { from: \"user\" })\n const opts = program.opts<{\n verbose?: boolean\n config?: string\n V?: boolean\n currentWindow?: boolean\n newWindow?: boolean\n }>()\n\n if (requestedVersion || requestedHelp) {\n return\n }\n\n if (opts.verbose === true) {\n logger = createLogger({ level: LogLevel.INFO })\n } else {\n logger = createLogger()\n }\n\n if (\n typeof opts.config === \"string\" &&\n opts.config.length > 0 &&\n typeof presetManager.setConfigPath === \"function\"\n ) {\n presetManager.setConfigPath(opts.config)\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Process exited\")) {\n throw error\n }\n handleError(error)\n }\n }\n\n return { run }\n}\n","#!/usr/bin/env node\nimport { createCli } from \"./cli.ts\"\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 await cli.run(process.argv.slice(2))\n } catch (error) {\n // Format and display error message appropriately\n if (error instanceof Error) {\n console.error(\"Error:\", error.message)\n\n // Also display stack trace in debug mode\n if (process.env.VDE_DEBUG === \"true\") {\n console.error(error.stack)\n }\n } else {\n console.error(\"An unexpected error occurred:\", String(error))\n }\n\n process.exit(1)\n }\n}\n\n// Execute immediately\nvoid main()\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["formatters: Record<string, (error: VDELayoutError) => string>","SplitPaneSchema: z.ZodType<unknown>","PaneSchema: z.ZodType<unknown>","path","candidates: string[]","mergedConfig: Config","yaml","paths: string[]","existing: string[]","mergedPresets: Config[\"presets\"]","loaderOptions: ConfigLoaderOptions","cachedConfig: Config | null","input","output","parseCommand","toCommandString","parseCommand","toCommandString","mockPaneIds: string[]","executedCommands: string[][]","isInTmuxSession","initialPaneId: string","newWindowCommand: string[]","findNewPaneId","buildDryRunSteps","stdout: string","stdout","parse","parsed: unknown","pane: WeztermListPane","mappedWindows: WeztermListWindow[]","mappedTabs: WeztermListTab[]","mappedPanes: WeztermListPane[]","steps: DryRunStep[]","args","spawnOutput","paneId","runCommand: ExecuteWeztermCommand","paneMap: PaneMap","cachedInitialList: WeztermListResult | undefined","workspaceHint: string | undefined","KNOWN_BACKENDS: TerminalBackendKind[]","severityRank: Record<DiagnosticsSeverity, number>","findings: DiagnosticsFinding[]","path","parsedPreset: unknown","parsed: unknown","panes: PlanNode[]","focusPaneIds: string[]","terminalPaneIds: string[]","steps: CommandStep[]","current: PlanNode","KNOWN_ISSUES: ReadonlyArray<string>","functionalCore: FunctionalCoreBridge","defaultCompilePreset","defaultCreateLayoutPlan","defaultEmitPlan","logger: Logger","document: Record<string, unknown>","toYAML","options","compileResult: CompilePresetSuccess","planResult: CreateLayoutPlanSuccess","emission: PlanEmission"],"sources":["../src/utils/errors.ts","../src/models/schema.ts","../src/config/validator.ts","../src/config/loader.ts","../src/layout/preset.ts","../src/cli/window-mode.ts","../src/cli/user-prompt.ts","../src/utils/logger.ts","../src/executor/real-executor.ts","../src/executor/dry-run-executor.ts","../src/executor/mock-executor.ts","../src/tmux/executor.ts","../src/core/errors.ts","../src/executor/plan-runner.ts","../src/executor/backends/tmux-backend.ts","../src/wezterm/cli.ts","../src/executor/backends/wezterm-backend.ts","../src/executor/backend-factory.ts","../src/executor/backend-resolver.ts","../src/core/diagnostics.ts","../src/core/compile.ts","../src/core/planner.ts","../src/core/emitter.ts","../src/cli.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 TMUX_NOT_RUNNING: \"TMUX_NOT_RUNNING\",\n TMUX_COMMAND_FAILED: \"TMUX_COMMAND_FAILED\",\n NOT_IN_TMUX_SESSION: \"NOT_IN_TMUX_SESSION\",\n NOT_IN_TMUX: \"NOT_IN_TMUX\",\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 WEZTERM_NOT_FOUND: \"WEZTERM_NOT_FOUND\",\n UNSUPPORTED_WEZTERM_VERSION: \"UNSUPPORTED_WEZTERM_VERSION\",\n USER_CANCELLED: \"USER_CANCELLED\",\n} as const\n\nconst createBaseError = (\n name: string,\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n const error = new Error(message) as VDELayoutError\n error.name = name\n ;(error as { code: string }).code = code\n ;(error as { details: Readonly<Record<string, unknown>> }).details = details\n return error\n}\n\nexport const createConfigError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"ConfigError\", message, code, details)\n}\n\nexport const createValidationError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"ValidationError\", message, code, details)\n}\n\nexport const createTmuxError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"TmuxError\", message, code, details)\n}\n\nexport const createEnvironmentError = (\n message: string,\n code: string,\n details: Readonly<Record<string, unknown>> = {},\n): VDELayoutError => {\n return createBaseError(\"EnvironmentError\", message, code, details)\n}\n\nexport const isVDELayoutError = (error: unknown): error is VDELayoutError => {\n if (typeof error !== \"object\" || error === null) {\n return false\n }\n\n if (!(\"code\" in error)) {\n return false\n }\n\n const { code } = error as { code?: unknown }\n if (typeof code !== \"string\") {\n return false\n }\n\n if (!(\"details\" in error)) {\n return false\n }\n\n return true\n}\n\nconst formatters: Record<string, (error: VDELayoutError) => string> = {\n [ErrorCodes.CONFIG_NOT_FOUND]: (error) => {\n const searchPaths = error.details.searchPaths\n if (!Array.isArray(searchPaths)) {\n return \"\"\n }\n\n const lines = [\"\", \"Searched in the following locations:\"]\n searchPaths.forEach((location) => lines.push(` - ${location}`))\n lines.push(\"\", \"To create a configuration file, run:\")\n lines.push(\" mkdir -p ~/.config/vde\")\n lines.push(' echo \"presets: {}\" > ~/.config/vde/layout.yml')\n return lines.join(\"\\n\")\n },\n [ErrorCodes.NOT_IN_TMUX_SESSION]: () => {\n return \"\\nThis command must be run inside a tmux session.\\nStart tmux first with: tmux\\n\"\n },\n [ErrorCodes.TMUX_NOT_INSTALLED]: () => {\n return (\n \"\\ntmux is required but not installed.\\n\" +\n \"Install tmux using your package manager:\\n\" +\n \" - macOS: brew install tmux\\n\" +\n \" - Ubuntu/Debian: sudo apt-get install tmux\\n\" +\n \" - Fedora: sudo dnf install tmux\\n\"\n )\n },\n [ErrorCodes.UNSUPPORTED_TMUX_VERSION]: (error) => {\n const requiredVersion = error.details.requiredVersion\n if (typeof requiredVersion !== \"string\") {\n return \"\"\n }\n return `\\nRequired tmux version: ${requiredVersion} or higher\\n`\n },\n [ErrorCodes.BACKEND_NOT_FOUND]: (error) => {\n const backend = typeof error.details.backend === \"string\" ? error.details.backend : \"terminal backend\"\n const binary = typeof error.details.binary === \"string\" ? error.details.binary : backend\n const suggestion =\n backend === \"wezterm\"\n ? [\n \"\",\n `${backend} is required but not installed.`,\n \"Install wezterm using your package manager:\",\n \" - macOS: brew install --cask wezterm\",\n \" - Ubuntu/Debian: sudo apt-get install wezterm\",\n \" - Fedora: sudo dnf install wezterm\",\n ].join(\"\\n\")\n : \"\"\n return `\\nMissing binary: ${binary}${suggestion}`\n },\n [ErrorCodes.WEZTERM_NOT_FOUND]: () => {\n return (\n \"\\nwezterm command was not found.\\n\" +\n \"Install wezterm using your package manager:\\n\" +\n \" - macOS: brew install --cask wezterm\\n\" +\n \" - Ubuntu/Debian: sudo apt-get install wezterm\\n\" +\n \" - Fedora: sudo dnf install wezterm\\n\"\n )\n },\n [ErrorCodes.UNSUPPORTED_WEZTERM_VERSION]: (error) => {\n const requiredVersion = typeof error.details.requiredVersion === \"string\" ? error.details.requiredVersion : \"\"\n const detected = typeof error.details.detectedVersion === \"string\" ? error.details.detectedVersion : \"\"\n const lines = [\"\", \"Unsupported wezterm version detected.\"]\n if (detected) {\n lines.push(`Detected version: ${detected}`)\n }\n if (requiredVersion) {\n lines.push(`Required version: ${requiredVersion} or higher`)\n }\n return lines.join(\"\\n\")\n },\n}\n\nexport const formatError = (error: Error): string => {\n if (!isVDELayoutError(error)) {\n return `${error.name}: ${error.message}`\n }\n\n let message = `Error: ${error.message}`\n\n const formatter = formatters[error.code]\n if (formatter) {\n message += `\\n${formatter(error)}`\n }\n\n const commandDetail = error.details.command\n if (commandDetail !== undefined) {\n message += `\\nCommand: ${JSON.stringify(commandDetail)}`\n }\n\n const stderrDetail = error.details.stderr\n if (stderrDetail !== undefined) {\n message += `\\nstderr: ${String(stderrDetail)}`\n }\n\n const presetDetail = error.details.preset\n if (presetDetail !== undefined) {\n message += `\\npreset: ${String(presetDetail)}`\n }\n\n const nestedErrors = error.details.errors\n if (Array.isArray(nestedErrors) && nestedErrors.length > 0) {\n message += \"\\nValidation errors:\\n\"\n nestedErrors.forEach((item) => {\n message += ` - ${String(item)}\\n`\n })\n }\n\n return message\n}\n","import { z } from \"zod\"\n\nexport const WindowModeSchema = z.enum([\"new-window\", \"current-window\"])\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 })\n .strict()\n\n// Split container schema (recursive)\nconst SplitPaneSchema: z.ZodType<unknown> = z.lazy(() =>\n z\n .object({\n type: z.enum([\"horizontal\", \"vertical\"]),\n ratio: z.array(z.number().positive()).min(1),\n panes: z.array(PaneSchema).min(1),\n })\n .strict()\n .refine((data) => data.ratio.length === data.panes.length, {\n message: \"Number of elements in ratio array does not match number of elements in panes array\",\n }),\n)\n\n// Recursive Pane schema definition\nexport const PaneSchema: z.ZodType<unknown> = z.lazy(() => z.union([SplitPaneSchema, TerminalPaneSchema]))\n\n// Layout schema definition\nexport const LayoutSchema = z\n .object({\n type: z.enum([\"horizontal\", \"vertical\"]),\n ratio: z.array(z.number().positive()).min(1),\n panes: z.array(PaneSchema).min(1),\n })\n .refine((data) => data.ratio.length === data.panes.length, {\n message: \"Number of elements in ratio array does not match number of elements in panes array\",\n })\n\n// Preset schema definition\nexport const PresetSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n layout: LayoutSchema.optional(),\n command: z.string().optional(),\n windowMode: WindowModeSchema.optional(),\n})\n\n// Config schema definition\nexport const ConfigSchema = z.object({\n defaults: z\n .object({\n windowMode: WindowModeSchema.optional(),\n })\n .optional(),\n presets: z.record(PresetSchema),\n})\n\n// Validation result type\ntype ValidationResult<T> = {\n success: boolean\n data?: T\n error?: string\n}\n\n// Helper function to format Zod errors consistently\nconst formatValidationError = (error: z.ZodError): string => {\n const messages = error.errors.map((e) => {\n const path = e.path.join(\".\")\n const message = e.message\n\n // Customize error message for panes array element count check\n if (path === \"layout.panes\" && message.includes(\"at least 2 element\")) {\n return `${path}: panes array must have at least 2 elements`\n }\n\n return `${path}: ${message}`\n })\n\n return messages.join(\"\\n\")\n}\n\n// Config validation\nexport const validateConfig = (data: unknown): ValidationResult<z.infer<typeof ConfigSchema>> => {\n try {\n const parsed = ConfigSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n\n// Preset validation\nexport const validatePreset = (data: unknown): ValidationResult<z.infer<typeof PresetSchema>> => {\n try {\n const parsed = PresetSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n\n// Pane validation\nexport const validatePane = (data: unknown): ValidationResult<z.infer<typeof PaneSchema>> => {\n try {\n const parsed = PaneSchema.parse(data)\n return { success: true, data: parsed }\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { success: false, error: formatValidationError(error) }\n }\n return { success: false, error: String(error) }\n }\n}\n","import * as YAML from \"yaml\"\nimport { z } from \"zod\"\nimport { ConfigSchema } from \"../models/schema.ts\"\nimport type { Config } from \"../models/types.ts\"\nimport { createValidationError, ErrorCodes, isVDELayoutError } from \"../utils/errors.ts\"\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.ts\"\nimport { createConfigError, ErrorCodes } from \"../utils/errors.ts\"\nimport { validateYAML } from \"./validator.ts\"\n\nexport type ConfigLoaderOptions = {\n readonly configPaths?: string[]\n}\n\nexport type ConfigLoader = {\n readonly loadYAML: () => Promise<string>\n readonly loadConfig: () => Promise<Config>\n readonly findConfigFile: () => Promise<string | null>\n readonly getSearchPaths: () => string[]\n}\n\nexport const createConfigLoader = (options: ConfigLoaderOptions = {}): ConfigLoader => {\n const explicitConfigPaths = options.configPaths\n\n const computeCachedSearchPaths = (): string[] => {\n if (explicitConfigPaths && explicitConfigPaths.length > 0) {\n return [...explicitConfigPaths]\n }\n\n const candidates: string[] = []\n const projectCandidate = findProjectConfigCandidate()\n if (projectCandidate !== null) {\n candidates.push(projectCandidate)\n }\n\n candidates.push(...buildDefaultSearchPaths())\n\n return [...new Set(candidates)]\n }\n\n const loadConfig = async (): Promise<Config> => {\n if (explicitConfigPaths && explicitConfigPaths.length > 0) {\n const filePath = await findFirstExisting(explicitConfigPaths)\n if (filePath === null) {\n throw createConfigError(\"Configuration file not found\", ErrorCodes.CONFIG_NOT_FOUND, {\n searchPaths: explicitConfigPaths,\n })\n }\n\n const content = await safeReadFile(filePath)\n return validateYAML(content)\n }\n\n const searchPaths = computeCachedSearchPaths()\n const existingPaths = await filterExistingPaths(searchPaths)\n\n if (existingPaths.length === 0) {\n throw createConfigError(\"Configuration file not found\", ErrorCodes.CONFIG_NOT_FOUND, {\n searchPaths,\n })\n }\n\n const projectPath = findProjectConfigCandidate()\n const globalPaths = existingPaths.filter((filePath) => filePath !== projectPath)\n\n let mergedConfig: Config = { presets: {} }\n\n for (const globalPath of globalPaths) {\n const content = await safeReadFile(globalPath)\n const config = validateYAML(content)\n mergedConfig = mergeConfigs(mergedConfig, config)\n }\n\n if (projectPath !== null && (await fs.pathExists(projectPath))) {\n const content = await safeReadFile(projectPath)\n const config = validateYAML(content)\n mergedConfig = mergeConfigs(mergedConfig, config)\n }\n\n return applyDefaults(mergedConfig)\n }\n\n return {\n loadYAML: async (): Promise<string> => {\n const config = await loadConfig()\n return yaml.stringify(config)\n },\n loadConfig,\n findConfigFile: async (): Promise<string | null> => {\n const searchPaths =\n explicitConfigPaths && explicitConfigPaths.length > 0 ? [...explicitConfigPaths] : computeCachedSearchPaths()\n\n for (const searchPath of searchPaths) {\n if (await fs.pathExists(searchPath)) {\n return searchPath\n }\n }\n return null\n },\n getSearchPaths: (): string[] => computeCachedSearchPaths(),\n }\n}\n\nconst buildDefaultSearchPaths = (): string[] => {\n const paths: string[] = []\n\n const vdeConfigPath = process.env.VDE_CONFIG_PATH\n if (vdeConfigPath !== undefined) {\n paths.push(path.join(vdeConfigPath, \"layout.yml\"))\n }\n\n const homeDir = process.env.HOME ?? os.homedir()\n const xdgConfigHome = process.env.XDG_CONFIG_HOME ?? path.join(homeDir, \".config\")\n paths.push(path.join(xdgConfigHome, \"vde\", \"layout.yml\"))\n\n return [...new Set(paths)]\n}\n\nconst findProjectConfigCandidate = (): string | null => {\n let currentDir = process.cwd()\n const { root } = path.parse(currentDir)\n\n while (true) {\n const candidate = path.join(currentDir, \".vde\", \"layout.yml\")\n if (fs.existsSync(candidate)) {\n return candidate\n }\n\n if (currentDir === root) {\n break\n }\n\n const parent = path.dirname(currentDir)\n if (parent === currentDir) {\n break\n }\n\n currentDir = parent\n }\n\n return null\n}\n\nconst findFirstExisting = async (paths: ReadonlyArray<string>): Promise<string | null> => {\n for (const candidate of paths) {\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return null\n}\n\nconst filterExistingPaths = async (paths: ReadonlyArray<string>): Promise<string[]> => {\n const existing: string[] = []\n for (const candidate of paths) {\n if (await fs.pathExists(candidate)) {\n existing.push(candidate)\n }\n }\n return existing\n}\n\nconst safeReadFile = async (filePath: string): Promise<string> => {\n try {\n return await fs.readFile(filePath, \"utf8\")\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n throw createConfigError(`Failed to read configuration file`, ErrorCodes.CONFIG_PERMISSION_ERROR, {\n filePath,\n error: errorMessage,\n })\n }\n}\n\nconst mergeConfigs = (base: Config, override: Config): 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 console.warn(\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 console.warn(\n `[vde-layout] defaults.windowMode conflict: \"${baseDefaults.windowMode}\" overridden by \"${overrideDefaults.windowMode}\"`,\n )\n }\n\n const mergedDefaults =\n baseDefaults !== undefined || overrideDefaults !== undefined\n ? {\n ...(baseDefaults ?? {}),\n ...(overrideDefaults ?? {}),\n }\n : undefined\n\n return mergedDefaults === undefined\n ? {\n presets: mergedPresets,\n }\n : {\n defaults: mergedDefaults,\n presets: mergedPresets,\n }\n}\n\nconst applyDefaults = (config: Config): Config => {\n return config\n}\n","import { createConfigLoader, type ConfigLoaderOptions } from \"../config/loader.ts\"\nimport { createConfigError, ErrorCodes } from \"../utils/errors.ts\"\nimport type { Config, Preset, PresetInfo } from \"../models/types.ts\"\nimport type { PresetManager } from \"../types/preset-manager.ts\"\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","import type { WindowMode } from \"../models/types.ts\"\n\nexport type WindowModeSource = {\n readonly cli?: WindowMode\n readonly preset?: WindowMode\n readonly defaults?: WindowMode\n}\n\nexport type WindowModeResolutionSource = \"cli\" | \"preset\" | \"defaults\" | \"fallback\"\n\nexport type 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 { createInterface } from \"node:readline/promises\"\nimport { stdin as input, stdout as output } from \"node:process\"\nimport type { ConfirmPaneClosure, ConfirmPaneClosureContext } from \"../types/confirm-pane.ts\"\nimport type { Logger } from \"../utils/logger.ts\"\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 await rl.close()\n }\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 { execa } from \"execa\"\nimport { createTmuxError, ErrorCodes } from \"../utils/errors.ts\"\nimport type { CommandExecutor } from \"../types/command-executor.ts\"\nimport { createLogger, LogLevel } from \"../utils/logger.ts\"\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 \"../types/command-executor.ts\"\nimport { createLogger, LogLevel } from \"../utils/logger.ts\"\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 \"../types/command-executor.ts\"\nimport type { TmuxExecutorContract } from \"../types/tmux.ts\"\nimport { createEnvironmentError, ErrorCodes } from \"../utils/errors.ts\"\n\nexport type MockExecutor = CommandExecutor &\n TmuxExecutorContract & {\n readonly getExecutedCommands: () => string[][]\n readonly clearExecutedCommands: () => void\n readonly setMockPaneIds: (paneIds: string[]) => void\n readonly getPaneIds: () => string[]\n }\n\nconst parseCommand = (commandOrArgs: string | string[]): string[] => {\n return typeof commandOrArgs === \"string\"\n ? commandOrArgs\n .split(\" \")\n .filter((segment) => segment.length > 0)\n .slice(1)\n : commandOrArgs\n}\n\nconst isInTmuxSession = (): boolean => {\n return Boolean(process.env.TMUX)\n}\n\nconst toCommandString = (args: string[]): string => {\n return [\"tmux\", ...args].join(\" \")\n}\n\nexport const createMockExecutor = (): MockExecutor => {\n let mockPaneCounter = 0\n let mockPaneIds: string[] = [\"%0\"]\n let executedCommands: string[][] = []\n\n const execute = async (commandOrArgs: string | string[]): Promise<string> => {\n const args = parseCommand(commandOrArgs)\n executedCommands.push(args)\n\n if (args[0] === \"new-window\") {\n mockPaneCounter = 0\n mockPaneIds = [\"%0\"]\n return \"%0\"\n }\n\n if (args.includes(\"display-message\") && args.includes(\"#{pane_id}\")) {\n return mockPaneIds[0] ?? \"%0\"\n }\n\n if (args.includes(\"list-panes\") && args.includes(\"#{pane_id}\")) {\n return mockPaneIds.join(\"\\n\")\n }\n\n if (args[0] === \"kill-pane\" && args.includes(\"-a\")) {\n const targetIndex = args.indexOf(\"-t\")\n const targetPane =\n (targetIndex >= 0 && targetIndex + 1 < args.length ? args[targetIndex + 1] : mockPaneIds[0]) ?? \"%0\"\n mockPaneIds = [targetPane]\n const parsedCounter = Number(targetPane.replace(\"%\", \"\"))\n if (!Number.isNaN(parsedCounter)) {\n mockPaneCounter = parsedCounter\n }\n return \"\"\n }\n\n if (args.includes(\"split-window\")) {\n mockPaneCounter += 1\n const newPaneId = `%${mockPaneCounter}`\n mockPaneIds = [...mockPaneIds, newPaneId]\n }\n\n return \"\"\n }\n\n return {\n execute,\n async executeMany(commandsList: string[][]): Promise<void> {\n for (const args of commandsList) {\n await execute(args)\n }\n },\n isDryRun(): boolean {\n return true\n },\n logCommand(): void {\n // noop\n },\n getExecutedCommands(): string[][] {\n return executedCommands\n },\n clearExecutedCommands(): void {\n executedCommands = []\n },\n setMockPaneIds(paneIds: string[]): void {\n mockPaneIds = [...paneIds]\n },\n getPaneIds(): string[] {\n return mockPaneIds\n },\n isInTmuxSession,\n async verifyTmuxEnvironment(): Promise<void> {\n if (!isInTmuxSession()) {\n throw createEnvironmentError(\"Must be run inside a tmux session\", ErrorCodes.NOT_IN_TMUX, {\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.ts\"\nimport type { TmuxExecutorContract } from \"../types/tmux.ts\"\nimport type { CommandExecutor } from \"../types/command-executor.ts\"\nimport { createRealExecutor, createDryRunExecutor, createMockExecutor } from \"../executor/index.ts\"\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, {\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","type FunctionalCoreErrorKind = \"compile\" | \"plan\" | \"emit\" | \"execution\"\n\nexport type FunctionalCoreError = {\n readonly kind: FunctionalCoreErrorKind\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 createFunctionalError = (\n kind: FunctionalCoreErrorKind,\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): FunctionalCoreError => ({\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 isFunctionalCoreError = (value: unknown): value is FunctionalCoreError => {\n if (typeof value !== \"object\" || value === null) {\n return false\n }\n const candidate = value as Partial<FunctionalCoreError>\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 type { CommandExecutor } from \"../types/command-executor.ts\"\nimport type { PlanEmission, CommandStep, EmittedTerminal } from \"../core/emitter.ts\"\nimport type { WindowMode } from \"../models/types.ts\"\nimport { ErrorCodes } from \"../utils/errors.ts\"\nimport { createFunctionalError } from \"../core/errors.ts\"\nimport type { ConfirmPaneClosure } from \"../types/confirm-pane.ts\"\n\nconst DOUBLE_QUOTE = '\"'\nconst ESCAPED_DOUBLE_QUOTE = '\\\\\"'\n\ntype ExecutePlanInput = {\n readonly emission: PlanEmission\n readonly executor: CommandExecutor\n readonly windowName?: string\n readonly windowMode: WindowMode\n readonly onConfirmKill?: ConfirmPaneClosure\n}\n\ntype ExecutePlanSuccess = {\n readonly executedSteps: number\n}\n\nexport const executePlan = async ({\n emission,\n executor,\n windowName,\n windowMode,\n onConfirmKill,\n}: ExecutePlanInput): Promise<ExecutePlanSuccess> => {\n const initialVirtualPaneId = emission.summary.initialPaneId\n if (typeof initialVirtualPaneId !== \"string\" || initialVirtualPaneId.length === 0) {\n raiseExecutionError(\"INVALID_PLAN\", {\n message: \"Plan emission is missing initial pane metadata\",\n path: \"plan.initialPaneId\",\n })\n }\n\n const paneMap = new Map<string, string>()\n\n const isDryRun = executor.isDryRun()\n\n let initialPaneId: string\n\n if (windowMode === \"current-window\") {\n const currentPaneId = await resolveCurrentPaneId({\n executor,\n contextPath: initialVirtualPaneId,\n isDryRun,\n })\n\n const panesInWindow = await listWindowPaneIds(executor, initialVirtualPaneId)\n const panesToClose = panesInWindow.filter((paneId) => paneId !== currentPaneId)\n\n if (panesToClose.length > 0) {\n let confirmed = true\n if (onConfirmKill !== undefined) {\n confirmed = await onConfirmKill({ panesToClose, dryRun: isDryRun })\n }\n\n if (confirmed !== true) {\n throw createFunctionalError(\"execution\", {\n code: ErrorCodes.USER_CANCELLED,\n message: \"Aborted layout application for current window\",\n path: initialVirtualPaneId,\n details: { panes: panesToClose },\n })\n }\n\n await executeCommand(executor, [\"kill-pane\", \"-a\", \"-t\", currentPaneId], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to close existing panes\",\n path: initialVirtualPaneId,\n details: { command: [\"kill-pane\", \"-a\", \"-t\", currentPaneId] },\n })\n }\n\n initialPaneId = normalizePaneId(currentPaneId)\n } else {\n const newWindowCommand: string[] = [\"new-window\", \"-P\", \"-F\", \"#{pane_id}\"]\n if (typeof windowName === \"string\" && windowName.trim().length > 0) {\n newWindowCommand.push(\"-n\", windowName.trim())\n }\n\n initialPaneId = normalizePaneId(\n await executeCommand(executor, newWindowCommand, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to create tmux window\",\n path: initialVirtualPaneId,\n }),\n )\n }\n\n registerPane(paneMap, initialVirtualPaneId, initialPaneId)\n\n let executedSteps = 0\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n await executeSplitStep({ step, executor, paneMap })\n } else if (step.kind === \"focus\") {\n await executeFocusStep({ step, executor, paneMap })\n }\n executedSteps += 1\n }\n\n await executeTerminalCommands({ terminals: emission.terminals, executor, paneMap })\n\n const finalRealFocus = resolvePaneId(paneMap, emission.summary.focusPaneId)\n if (typeof finalRealFocus === \"string\" && finalRealFocus.length > 0) {\n await executeCommand(executor, [\"select-pane\", \"-t\", finalRealFocus], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: \"Failed to restore focus\",\n path: emission.summary.focusPaneId,\n })\n }\n\n return { executedSteps }\n}\n\nconst executeSplitStep = async ({\n step,\n executor,\n paneMap,\n}: {\n readonly step: CommandStep\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n}): Promise<void> => {\n const targetVirtualId = ensureNonEmpty(step.targetPaneId, () =>\n raiseExecutionError(\"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(\"UNKNOWN_PANE\", {\n message: `Unknown target pane: ${targetVirtualId}`,\n path: step.id,\n }),\n )\n\n const panesBefore = await listPaneIds(executor, step)\n const splitCommand = replaceTarget(step.command, targetRealId)\n await executeCommand(executor, splitCommand, {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to execute split step ${step.id}`,\n path: step.id,\n details: { command: splitCommand },\n })\n\n const panesAfter = await listPaneIds(executor, step)\n const newPaneId = ensureNonEmpty(findNewPaneId(panesBefore, panesAfter), () =>\n raiseExecutionError(\"UNKNOWN_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\nconst 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(\"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(\"UNKNOWN_PANE\", {\n message: `Unknown focus pane: ${targetVirtualId}`,\n path: step.id,\n }),\n )\n\n const command = replaceTarget(step.command, 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\nconst executeTerminalCommands = async ({\n terminals,\n executor,\n paneMap,\n}: {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly executor: CommandExecutor\n readonly paneMap: Map<string, string>\n}): Promise<void> => {\n for (const terminal of terminals) {\n const realPaneId = ensureNonEmpty(resolvePaneId(paneMap, terminal.virtualPaneId), () =>\n raiseExecutionError(\"UNKNOWN_PANE\", {\n message: `Unknown terminal pane: ${terminal.virtualPaneId}`,\n path: terminal.virtualPaneId,\n }),\n )\n\n if (typeof terminal.cwd === \"string\" && terminal.cwd.length > 0) {\n const escapedCwd = terminal.cwd.split(DOUBLE_QUOTE).join(ESCAPED_DOUBLE_QUOTE)\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, `cd \"${escapedCwd}\"`, \"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 if (terminal.env !== undefined) {\n for (const [key, value] of Object.entries(terminal.env)) {\n const escaped = String(value).split(DOUBLE_QUOTE).join(ESCAPED_DOUBLE_QUOTE)\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, `export ${key}=\"${escaped}\"`, \"Enter\"], {\n code: ErrorCodes.TMUX_COMMAND_FAILED,\n message: `Failed to set environment variable ${key}`,\n path: terminal.virtualPaneId,\n })\n }\n }\n\n if (typeof terminal.command === \"string\" && terminal.command.length > 0) {\n await executeCommand(executor, [\"send-keys\", \"-t\", realPaneId, terminal.command, \"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\nconst 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 createFunctionalError(\"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 createFunctionalError(\"execution\", {\n code: context.code,\n message: context.message,\n path: context.path,\n details: context.details,\n })\n }\n}\n\nconst 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 createFunctionalError(\"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\nconst 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 replaceTarget = (command: ReadonlyArray<string>, realTarget: string): string[] => {\n const next = [...command]\n const targetIndex = next.findIndex((value, index) => value === \"-t\" && index + 1 < next.length)\n if (targetIndex >= 0) {\n next[targetIndex + 1] = realTarget\n return next\n }\n\n if (next.length > 0) {\n next[next.length - 1] = realTarget\n }\n return next\n}\n\nconst normalizePaneId = (raw: string): string => {\n const trimmed = raw.trim()\n return trimmed.length === 0 ? \"%0\" : trimmed\n}\n\nconst registerPane = (paneMap: Map<string, string>, virtualId: string, realId: string): void => {\n paneMap.set(virtualId, realId)\n}\n\nconst resolvePaneId = (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\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\nconst 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 createFunctionalError(\"execution\", {\n code,\n message: error.message,\n path: error.path,\n details: error.details,\n })\n}\n","import { createTmuxExecutor } from \"../../tmux/executor.ts\"\nimport type { PlanEmission } from \"../../core/emitter.ts\"\nimport { executePlan } from \"../plan-runner.ts\"\nimport type {\n ApplyPlanParameters,\n ApplyPlanResult,\n DryRunStep,\n TerminalBackend,\n TerminalBackendContext,\n} from \"../terminal-backend.ts\"\n\nexport const createTmuxBackend = (context: TerminalBackendContext): TerminalBackend => {\n const tmuxExecutor = createTmuxExecutor({\n executor: context.executor,\n verbose: context.verbose,\n dryRun: context.dryRun,\n })\n\n const buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n return emission.steps.map((step) => ({\n backend: \"tmux\" as const,\n summary: step.summary,\n command: tmuxExecutor.getCommandString([...step.command]),\n }))\n }\n\n const verifyEnvironment = async (): Promise<void> => {\n if (context.dryRun) {\n return\n }\n await tmuxExecutor.verifyTmuxEnvironment()\n }\n\n const applyPlan = async ({ emission, windowMode, windowName }: ApplyPlanParameters): Promise<ApplyPlanResult> => {\n const executionResult = await executePlan({\n emission,\n executor: tmuxExecutor.getExecutor(),\n windowMode,\n windowName,\n onConfirmKill: context.prompt,\n })\n\n return {\n executedSteps: executionResult.executedSteps,\n focusPaneId: emission.summary.focusPaneId,\n }\n }\n\n return {\n verifyEnvironment,\n applyPlan,\n getDryRunSteps: buildDryRunSteps,\n }\n}\n","import { execa } from \"execa\"\nimport { createEnvironmentError, ErrorCodes } from \"../utils/errors.ts\"\nimport { createFunctionalError } from \"../core/errors.ts\"\n\nconst WEZTERM_BINARY = \"wezterm\"\nconst MINIMUM_VERSION = \"20220624-141144-bd1b7c5d\"\nconst VERSION_REGEX = /(\\d{8})-(\\d{6})-([0-9a-fA-F]+)/i\n\ntype ExecaLikeError = Error & {\n readonly exitCode?: number\n readonly code?: string\n readonly stderr?: string\n readonly stdout?: string\n}\n\nexport type WeztermListPane = {\n readonly paneId: string\n readonly isActive: boolean\n}\n\nexport type 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\nexport const verifyWeztermAvailability = async (): Promise<{ version: string }> => {\n let stdout: string\n try {\n const result = await execa(WEZTERM_BINARY, [\"--version\"])\n stdout = result.stdout\n } catch (error) {\n const execaError = error as ExecaLikeError\n if (execaError.code === \"ENOENT\") {\n throw createEnvironmentError(\"wezterm is not installed\", ErrorCodes.BACKEND_NOT_FOUND, {\n backend: \"wezterm\",\n binary: WEZTERM_BINARY,\n })\n }\n throw createEnvironmentError(\"Failed to execute wezterm --version\", ErrorCodes.WEZTERM_NOT_FOUND, {\n backend: \"wezterm\",\n binary: WEZTERM_BINARY,\n stderr: execaError.stderr,\n })\n }\n\n const detectedVersion = extractVersion(stdout)\n if (detectedVersion === undefined) {\n throw createEnvironmentError(\"Unable to determine wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n requiredVersion: MINIMUM_VERSION,\n detectedVersion: stdout.trim(),\n })\n }\n\n if (!isVersionSupported(detectedVersion, MINIMUM_VERSION)) {\n throw createEnvironmentError(\"Unsupported wezterm version\", ErrorCodes.UNSUPPORTED_WEZTERM_VERSION, {\n requiredVersion: MINIMUM_VERSION,\n detectedVersion,\n })\n }\n\n return { version: detectedVersion }\n}\n\nexport type RunWeztermErrorContext = {\n readonly message: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n}\n\nexport const runWeztermCli = async (args: string[], errorContext: RunWeztermErrorContext): Promise<string> => {\n try {\n const result = await execa(WEZTERM_BINARY, [\"cli\", ...args])\n return result.stdout\n } catch (error) {\n const execaError = error as ExecaLikeError\n throw createFunctionalError(\"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 = parseListResult(stdout)\n if (result === undefined) {\n throw createFunctionalError(\"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\nconst toIdString = (value: unknown): string | undefined => {\n if (typeof value === \"string\") {\n return value\n }\n if (typeof value === \"number\") {\n return value.toString()\n }\n return undefined\n}\n\nconst isNonEmptyString = (value: string | undefined): value is string => {\n return typeof value === \"string\" && value.length > 0\n}\n\nconst toWorkspaceString = (value: unknown): string | undefined => {\n if (typeof value === \"string\" && value.length > 0) {\n return value\n }\n return undefined\n}\n\ntype RawListPane = {\n readonly pane_id?: number | string\n readonly is_active?: unknown\n}\n\ntype RawListTab = {\n readonly tab_id?: number | string\n readonly is_active?: unknown\n readonly panes?: RawListPane[]\n}\n\ntype RawListWindow = {\n readonly window_id?: number | string\n readonly is_active?: unknown\n readonly workspace?: unknown\n readonly tabs?: RawListTab[]\n}\n\ntype RawListEntry = {\n readonly window_id?: number | string\n readonly tab_id?: number | string\n readonly pane_id?: number | string\n readonly workspace?: unknown\n readonly is_active?: unknown\n}\n\ntype RawListResult = {\n readonly windows?: RawListWindow[]\n}\n\nconst parseListResult = (stdout: string): WeztermListResult | undefined => {\n try {\n const parsed: unknown = JSON.parse(stdout)\n\n if (Array.isArray(parsed)) {\n const windowMap = new Map<\n string,\n {\n windowId: string\n isActive: boolean\n workspace?: string\n tabs: Map<\n string,\n {\n tabId: string\n isActive: boolean\n panes: WeztermListPane[]\n }\n >\n }\n >()\n\n for (const entry of parsed) {\n if (typeof entry !== \"object\" || entry === null) {\n continue\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 continue\n }\n const windowId = windowIdRaw\n const tabId = tabIdRaw\n const paneId = paneIdRaw\n const workspace = toWorkspaceString(listEntry.workspace)\n\n let windowRecord = windowMap.get(windowId)\n if (!windowRecord) {\n windowRecord = {\n windowId,\n isActive: false,\n workspace,\n tabs: new Map(),\n }\n windowMap.set(windowId, windowRecord)\n } else if (workspace !== undefined && windowRecord.workspace === undefined) {\n windowRecord.workspace = workspace\n }\n\n let tabRecord = windowRecord.tabs.get(tabId)\n if (!tabRecord) {\n tabRecord = {\n tabId,\n isActive: false,\n panes: [],\n }\n windowRecord.tabs.set(tabId, tabRecord)\n }\n\n const pane: WeztermListPane = {\n paneId,\n isActive: listEntry.is_active === true,\n }\n\n windowRecord.isActive ||= listEntry.is_active === true\n tabRecord.isActive ||= listEntry.is_active === true\n tabRecord.panes.push(pane)\n }\n\n const windows = Array.from(windowMap.values()).map(\n (windowRecord): WeztermListWindow => ({\n windowId: windowRecord.windowId,\n isActive: windowRecord.isActive,\n workspace: windowRecord.workspace,\n tabs: Array.from(windowRecord.tabs.values()).map(\n (tabRecord): WeztermListTab => ({\n tabId: tabRecord.tabId,\n isActive: tabRecord.isActive,\n panes: tabRecord.panes.map(\n (pane): WeztermListPane => ({\n paneId: pane.paneId,\n isActive: pane.isActive,\n }),\n ),\n }),\n ),\n }),\n )\n\n return {\n windows,\n }\n }\n\n if (typeof parsed === \"object\" && parsed !== null) {\n const candidate = parsed as Partial<RawListResult>\n const windows = Array.isArray(candidate.windows) ? candidate.windows : []\n const mappedWindows: WeztermListWindow[] = []\n\n for (const window of windows) {\n if (typeof window !== \"object\" || window === null) {\n continue\n }\n const rawWindow = window as RawListWindow\n const windowIdRaw = toIdString(rawWindow.window_id)\n if (!isNonEmptyString(windowIdRaw)) {\n continue\n }\n const windowId = windowIdRaw\n const workspace = toWorkspaceString(rawWindow.workspace)\n\n const mappedTabs: WeztermListTab[] = []\n const tabs = Array.isArray(rawWindow.tabs) ? rawWindow.tabs : []\n for (const tab of tabs) {\n if (typeof tab !== \"object\" || tab === null) {\n continue\n }\n const rawTab = tab as RawListTab\n const tabIdRaw = toIdString(rawTab.tab_id)\n if (!isNonEmptyString(tabIdRaw)) {\n continue\n }\n const tabId = tabIdRaw\n\n const paneRecords = Array.isArray(rawTab.panes) ? rawTab.panes : []\n const mappedPanes: WeztermListPane[] = []\n for (const pane of paneRecords) {\n if (typeof pane !== \"object\" || pane === null) {\n continue\n }\n const rawPane = pane as RawListPane\n const paneIdRaw = toIdString(rawPane.pane_id)\n if (!isNonEmptyString(paneIdRaw)) {\n continue\n }\n const paneId = paneIdRaw\n\n mappedPanes.push({\n paneId,\n isActive: rawPane.is_active === true,\n })\n }\n\n mappedTabs.push({\n tabId,\n isActive: rawTab.is_active === true,\n panes: mappedPanes,\n })\n }\n\n mappedWindows.push({\n windowId,\n isActive: rawWindow.is_active === true,\n workspace,\n tabs: mappedTabs,\n })\n }\n\n return { windows: mappedWindows }\n }\n\n return undefined\n } catch {\n return undefined\n }\n}\n","import type { PlanEmission, CommandStep, EmittedTerminal } from \"../../core/emitter.ts\"\nimport { createFunctionalError } from \"../../core/errors.ts\"\nimport { ErrorCodes } from \"../../utils/errors.ts\"\nimport type {\n ApplyPlanParameters,\n ApplyPlanResult,\n DryRunStep,\n TerminalBackend,\n TerminalBackendContext,\n} from \"../terminal-backend.ts\"\nimport {\n killWeztermPane,\n listWeztermWindows,\n runWeztermCli,\n verifyWeztermAvailability,\n type RunWeztermErrorContext,\n type WeztermListResult,\n} from \"../../wezterm/cli.ts\"\n\ntype PaneMap = Map<string, string>\n\ntype ExecuteWeztermCommand = (args: ReadonlyArray<string>, errorContext: RunWeztermErrorContext) => Promise<string>\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 ensureVirtualPaneId = (emission: PlanEmission): string => {\n const { initialPaneId } = emission.summary\n if (typeof initialPaneId !== \"string\" || initialPaneId.length === 0) {\n throw createFunctionalError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: \"Plan emission is missing initial pane metadata\",\n path: \"plan.initialPaneId\",\n })\n }\n return initialPaneId\n}\n\nconst 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}\nconst resolveRealPaneId = (paneMap: PaneMap, virtualId: string, context: { readonly stepId: string }): string => {\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 throw createFunctionalError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: `Unknown wezterm pane mapping for ${virtualId}`,\n path: context.stepId,\n })\n}\n\nconst buildDryRunSteps = (emission: PlanEmission): DryRunStep[] => {\n const steps: DryRunStep[] = []\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n const target = step.targetPaneId ?? \"<unknown>\"\n const args = buildSplitArguments({\n targetPaneId: target,\n percent: extractPercent(step.command),\n horizontal: isHorizontalSplit(step.command),\n })\n steps.push({\n backend: \"wezterm\",\n summary: step.summary,\n command: `wezterm cli ${args.join(\" \")}`,\n })\n continue\n }\n\n if (step.kind === \"focus\") {\n const target = step.targetPaneId ?? \"<unknown>\"\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 steps.push({\n backend: \"wezterm\",\n summary: step.summary,\n command: `wezterm cli # ${step.command.join(\" \")}`,\n })\n }\n\n for (const terminal of emission.terminals) {\n const paneId = terminal.virtualPaneId\n if (typeof terminal.cwd === \"string\" && terminal.cwd.length > 0) {\n const cwdCommand = `cd \"${terminal.cwd.split('\"').join('\\\\\"')}\"`\n steps.push({\n backend: \"wezterm\",\n summary: `set cwd for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- '${cwdCommand.replace(/'/g, \"\\\\'\")}'`,\n })\n }\n\n if (terminal.env !== undefined) {\n for (const [key, value] of Object.entries(terminal.env)) {\n const envCommand = `export ${key}=\"${String(value).split('\"').join('\\\\\"')}\"`\n steps.push({\n backend: \"wezterm\",\n summary: `set env ${key} for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- '${envCommand.replace(/'/g, \"\\\\'\")}'`,\n })\n }\n }\n\n if (typeof terminal.command === \"string\" && terminal.command.length > 0) {\n steps.push({\n backend: \"wezterm\",\n summary: `run command for ${paneId}`,\n command: `wezterm cli send-text --pane-id ${paneId} --no-paste -- '${terminal.command.replace(/'/g, \"\\\\'\")}'`,\n })\n }\n }\n\n return steps\n}\n\nconst resolveCurrentWindow = async (context: {\n readonly list: WeztermListResult\n readonly prompt?: TerminalBackendContext[\"prompt\"]\n readonly dryRun: boolean\n readonly logCommand: (args: ReadonlyArray<string>) => void\n}): Promise<CurrentWindowResolution> => {\n const activeWindow = context.list.windows.find((window) => window.isActive) ?? context.list.windows[0]\n\n if (!activeWindow) {\n throw createFunctionalError(\"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 = activeWindow.tabs.find((tab) => tab.isActive) ?? activeWindow.tabs[0]\n\n if (!activeTab) {\n throw createFunctionalError(\"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 = activeTab.panes.find((pane) => pane.isActive) ?? activeTab.panes[0]\n\n if (!activePane) {\n throw createFunctionalError(\"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 createFunctionalError(\"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\nconst 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\nconst delay = (ms: number): Promise<void> => {\n return new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n}\n\nconst waitForPaneRegistration = async ({\n paneId,\n listWindows,\n windowHint,\n}: {\n readonly paneId: string\n readonly listWindows: () => Promise<WeztermListResult>\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 delay(PANE_REGISTRATION_DELAY_MS)\n }\n }\n\n throw createFunctionalError(\"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 resolveInitialPane = async ({\n windowMode,\n prompt,\n dryRun,\n listWindows,\n runCommand,\n logCommand,\n initialCwd,\n workspaceHint,\n initialList,\n}: {\n readonly windowMode: ApplyPlanParameters[\"windowMode\"]\n readonly prompt?: TerminalBackendContext[\"prompt\"]\n readonly dryRun: boolean\n readonly listWindows: () => Promise<WeztermListResult>\n readonly runCommand: ExecuteWeztermCommand\n readonly logCommand: (args: ReadonlyArray<string>) => void\n readonly initialCwd?: string\n readonly workspaceHint?: string\n readonly initialList?: WeztermListResult\n}): Promise<InitialPaneResolution> => {\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 })\n }\n\n const existingSnapshot = initialList ?? (await listWindows())\n const scopedExisting = filterWindowsByWorkspace(existingSnapshot, workspaceHint)\n const activeWindow = 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 createFunctionalError(\"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 createFunctionalError(\"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\nconst collectPaneIdsForWindow = (list: WeztermListResult, windowId: string): Set<string> => {\n const targetWindow = list.windows.find((window) => window.windowId === windowId)\n if (!targetWindow) {\n throw createFunctionalError(\"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 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\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 isHorizontalSplit = (command: ReadonlyArray<string>): boolean => {\n return command.includes(\"-h\")\n}\n\nconst extractPercent = (command: ReadonlyArray<string>): string => {\n const index = command.findIndex((segment) => segment === \"-p\")\n if (index >= 0 && index + 1 < command.length) {\n const value = command[index + 1]\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim()\n }\n }\n return \"50\"\n}\n\nconst buildSplitArguments = (params: {\n readonly targetPaneId: string\n readonly percent: string\n readonly horizontal: boolean\n}): string[] => {\n const directionFlag = params.horizontal ? \"--right\" : \"--bottom\"\n return [\"split-pane\", directionFlag, \"--percent\", params.percent, \"--pane-id\", params.targetPaneId]\n}\n\nconst 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 createFunctionalError(\"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\nconst escapeDoubleQuotes = (value: string): string => {\n return value.split('\"').join('\\\\\"')\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\nconst applyTerminalCommands = async ({\n terminals,\n paneMap,\n runCommand,\n}: {\n readonly terminals: ReadonlyArray<EmittedTerminal>\n readonly paneMap: PaneMap\n readonly runCommand: ExecuteWeztermCommand\n}): Promise<void> => {\n for (const terminal of terminals) {\n const realPaneId = resolveRealPaneId(paneMap, terminal.virtualPaneId, { stepId: terminal.virtualPaneId })\n\n if (typeof terminal.cwd === \"string\" && terminal.cwd.length > 0) {\n const escapedCwd = escapeDoubleQuotes(terminal.cwd)\n await sendTextToPane({\n paneId: realPaneId,\n text: `cd \"${escapedCwd}\"`,\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 if (terminal.env !== undefined) {\n for (const [key, value] of Object.entries(terminal.env)) {\n const escapedValue = escapeDoubleQuotes(String(value))\n await sendTextToPane({\n paneId: realPaneId,\n text: `export ${key}=\"${escapedValue}\"`,\n runCommand,\n context: {\n message: `Failed to set environment variable ${key}`,\n path: terminal.virtualPaneId,\n },\n })\n }\n }\n\n if (typeof terminal.command === \"string\" && terminal.command.length > 0) {\n await sendTextToPane({\n paneId: realPaneId,\n text: terminal.command,\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\nconst applySplitStep = async ({\n step,\n paneMap,\n windowId,\n runCommand,\n listWindows,\n logPaneMapping,\n}: {\n readonly step: CommandStep\n readonly paneMap: PaneMap\n readonly windowId: string\n readonly runCommand: ExecuteWeztermCommand\n readonly listWindows: () => Promise<WeztermListResult>\n readonly logPaneMapping: (virtualId: string, realId: string) => void\n}): Promise<void> => {\n const targetVirtualId = step.targetPaneId\n if (typeof targetVirtualId !== \"string\" || targetVirtualId.length === 0) {\n throw createFunctionalError(\"execution\", {\n code: ErrorCodes.INVALID_PANE,\n message: \"Split step missing target pane metadata\",\n path: step.id,\n })\n }\n\n const targetRealId = resolveRealPaneId(paneMap, targetVirtualId, { stepId: step.id })\n\n const beforeList = await listWindows()\n const beforePaneIds = collectPaneIdsForWindow(beforeList, windowId)\n\n const args = buildSplitArguments({\n targetPaneId: targetRealId,\n percent: extractPercent(step.command),\n horizontal: isHorizontalSplit(step.command),\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 createFunctionalError(\"execution\", {\n code: ErrorCodes.TERMINAL_COMMAND_FAILED,\n message: \"Unable to determine newly created wezterm pane\",\n path: step.id,\n })\n }\n\n if (typeof step.createdPaneId === \"string\" && step.createdPaneId.length > 0) {\n registerPaneWithAncestors(paneMap, step.createdPaneId, newPaneId)\n logPaneMapping(step.createdPaneId, newPaneId)\n }\n}\n\nexport const createWeztermBackend = (context: TerminalBackendContext): TerminalBackend => {\n const formatCommand = (args: ReadonlyArray<string>): string => {\n return `wezterm cli ${args.join(\" \")}`\n }\n\n const logCommand = (args: ReadonlyArray<string>): void => {\n const message = `[wezterm] ${formatCommand(args)}`\n if (context.verbose) {\n context.logger.info(message)\n } else {\n context.logger.debug(message)\n }\n }\n\n const logPaneMapping = (virtualId: string, realId: string): void => {\n const message = `[wezterm] pane ${virtualId} -> ${realId}`\n if (context.verbose) {\n context.logger.info(message)\n } else {\n context.logger.debug(message)\n }\n }\n\n const runCommand: ExecuteWeztermCommand = async (args, errorContext) => {\n const commandArgs = [...args]\n logCommand(commandArgs)\n return runWeztermCli(commandArgs, errorContext)\n }\n\n const listWindows = async (): Promise<WeztermListResult> => {\n logCommand([\"list\", \"--format\", \"json\"])\n return listWeztermWindows()\n }\n\n const verifyEnvironment = async (): Promise<void> => {\n if (context.dryRun) {\n return\n }\n await verifyWeztermAvailability()\n }\n\n const applyPlan = async ({ emission, windowMode }: ApplyPlanParameters): Promise<ApplyPlanResult> => {\n const initialVirtualPaneId = ensureVirtualPaneId(emission)\n const paneMap: PaneMap = new Map()\n const initialTerminal = emission.terminals.find((terminal) => terminal.virtualPaneId === initialVirtualPaneId)\n const initialCwd =\n typeof initialTerminal?.cwd === \"string\" && initialTerminal.cwd.length > 0 ? initialTerminal.cwd : context.cwd\n\n let cachedInitialList: WeztermListResult | undefined\n let workspaceHint: string | undefined\n if (typeof context.paneId === \"string\" && context.paneId.length > 0) {\n try {\n cachedInitialList = await listWindows()\n workspaceHint = findWorkspaceForPane(cachedInitialList, context.paneId)\n } catch {\n cachedInitialList = undefined\n workspaceHint = undefined\n }\n }\n\n const { paneId: initialPaneId, windowId } = await resolveInitialPane({\n windowMode,\n prompt: context.prompt,\n dryRun: context.dryRun,\n listWindows,\n runCommand,\n logCommand,\n initialCwd,\n workspaceHint,\n initialList: cachedInitialList,\n })\n registerPaneWithAncestors(paneMap, initialVirtualPaneId, initialPaneId)\n logPaneMapping(initialVirtualPaneId, initialPaneId)\n\n let executedSteps = 0\n\n for (const step of emission.steps) {\n if (step.kind === \"split\") {\n await applySplitStep({\n step,\n paneMap,\n windowId,\n runCommand,\n listWindows,\n logPaneMapping,\n })\n executedSteps += 1\n } else if (step.kind === \"focus\") {\n await applyFocusStep({\n step,\n paneMap,\n runCommand,\n })\n executedSteps += 1\n }\n }\n\n await applyTerminalCommands({\n terminals: emission.terminals,\n paneMap,\n runCommand,\n })\n\n const focusVirtual = emission.summary.focusPaneId\n const focusPaneId = typeof focusVirtual === \"string\" ? paneMap.get(focusVirtual) : undefined\n\n return {\n executedSteps,\n focusPaneId,\n }\n }\n\n return {\n verifyEnvironment,\n applyPlan,\n getDryRunSteps: buildDryRunSteps,\n }\n}\n","import type { TerminalBackend, TerminalBackendContext, TerminalBackendKind } from \"./terminal-backend.ts\"\nimport { createTmuxBackend } from \"./backends/tmux-backend.ts\"\nimport { createWeztermBackend } from \"./backends/wezterm-backend.ts\"\n\nexport const createTerminalBackend = (kind: TerminalBackendKind, context: TerminalBackendContext): TerminalBackend => {\n if (kind === \"tmux\") {\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.ts\"\n\ntype ResolveBackendOptions = {\n readonly cliFlag?: TerminalBackendKind\n readonly env: NodeJS.ProcessEnv\n}\n\nconst KNOWN_BACKENDS: TerminalBackendKind[] = [\"tmux\", \"wezterm\"]\n\nexport const resolveTerminalBackendKind = ({ cliFlag, env }: ResolveBackendOptions): TerminalBackendKind => {\n if (cliFlag !== undefined) {\n if (!KNOWN_BACKENDS.includes(cliFlag)) {\n throw new Error(`Unknown backend \"${cliFlag}\"`)\n }\n return cliFlag\n }\n\n if (typeof env.TMUX === \"string\" && env.TMUX.trim().length > 0) {\n return \"tmux\"\n }\n\n return \"tmux\"\n}\n","import { parse } from \"yaml\"\n\nexport type DiagnosticsSeverity = \"high\" | \"medium\" | \"low\"\n\ntype DiagnosticsFinding = {\n readonly path: string\n readonly severity: DiagnosticsSeverity\n readonly description: string\n}\n\ntype DiagnosticsBacklogItem = {\n readonly id: string\n readonly severity: DiagnosticsSeverity\n readonly summary: string\n readonly actions: ReadonlyArray<string>\n}\n\nexport type DiagnosticsReport = {\n readonly findings: ReadonlyArray<DiagnosticsFinding>\n readonly nextSteps: ReadonlyArray<string>\n readonly backlog: ReadonlyArray<DiagnosticsBacklogItem>\n}\n\ntype DiagnosticsInput = {\n readonly presetDocument: string\n readonly knownIssues?: ReadonlyArray<string>\n}\n\nconst severityRank: Record<DiagnosticsSeverity, number> = {\n high: 3,\n medium: 2,\n low: 1,\n}\n\ntype FindingAccumulator = {\n add: (args: { path: string; severity: DiagnosticsSeverity; description: string; nextStep?: string }) => void\n readonly findings: DiagnosticsFinding[]\n readonly nextSteps: Set<string>\n readonly backlog: Map<string, DiagnosticsBacklogItem>\n}\n\nconst createAccumulator = (): FindingAccumulator => {\n const findings: DiagnosticsFinding[] = []\n const nextSteps = new Set<string>()\n const backlog = new Map<string, DiagnosticsBacklogItem>()\n\n return {\n findings,\n nextSteps,\n backlog,\n add: ({ path, severity, description, nextStep }): void => {\n findings.push({ path, severity, description })\n if (typeof nextStep === \"string\" && nextStep.length > 0) {\n nextSteps.add(nextStep)\n }\n\n const existing = backlog.get(path)\n const existingActions = new Set(existing?.actions ?? [])\n existingActions.add(description)\n if (typeof nextStep === \"string\" && nextStep.length > 0) {\n existingActions.add(nextStep)\n }\n\n const mergedSeverity = existing !== undefined ? maxSeverity(existing.severity, severity) : severity\n\n const summary =\n existing !== undefined && severityRank[existing.severity] >= severityRank[severity]\n ? existing.summary\n : description\n\n backlog.set(path, {\n id: path,\n severity: mergedSeverity,\n summary,\n actions: Array.from(existingActions),\n })\n },\n }\n}\n\nexport const runDiagnostics = (input: DiagnosticsInput): DiagnosticsReport => {\n const accumulator = createAccumulator()\n const knownIssues = input.knownIssues ?? []\n let parsedPreset: unknown\n\n try {\n parsedPreset = parse(input.presetDocument)\n } catch (error) {\n accumulator.add({\n path: \"presetDocument\",\n severity: \"high\",\n description: `プリセットYAMLの解析に失敗しました: ${(error as Error).message}`,\n nextStep: \"プリセットYAMLを構文チェックし、Functional Coreリライト前に整合性を確保する\",\n })\n return {\n findings: sortBySeverity(accumulator.findings),\n nextSteps: Array.from(accumulator.nextSteps),\n backlog: sortBacklog(accumulator.backlog),\n }\n }\n\n if (parsedPreset === null || typeof parsedPreset !== \"object\") {\n accumulator.add({\n path: \"preset\",\n severity: \"high\",\n description: \"プリセット定義がオブジェクト形式ではありません\",\n nextStep: \"プリセットYAMLをオブジェクト構造に整形し整合性を確保する\",\n })\n } else {\n const presetObject = parsedPreset as Record<string, unknown>\n checkFocusDuplications(presetObject, accumulator)\n collectLowPrioritySignals(presetObject, accumulator)\n }\n\n knownIssues.forEach((issue, index) => {\n const trimmed = issue.trim()\n if (trimmed.length === 0) {\n return\n }\n\n accumulator.add({\n path: `codebase.knownIssues[${index}]`,\n severity: \"medium\",\n description: trimmed,\n nextStep: `tmux依存や副作用をFunctional Core境界で切り離す: ${trimmed}`,\n })\n })\n\n return {\n findings: sortBySeverity(accumulator.findings),\n nextSteps: Array.from(accumulator.nextSteps),\n backlog: sortBacklog(accumulator.backlog),\n }\n}\n\nconst checkFocusDuplications = (preset: Record<string, unknown>, accumulator: FindingAccumulator): void => {\n const layout = preset.layout as unknown\n if (layout === undefined || layout === null) {\n return\n }\n\n const focusCount = countFocusFlags(layout)\n if (focusCount > 1) {\n accumulator.add({\n path: \"preset.layout\",\n severity: \"high\",\n description: \"複数のペインでfocus: trueが指定されています\",\n nextStep: \"focusは単一ペインに限定しPlan生成時に一貫するようFunctional Coreで制御する\",\n })\n }\n}\n\nconst collectLowPrioritySignals = (preset: Record<string, unknown>, accumulator: FindingAccumulator): void => {\n const layout = preset.layout as Record<string, unknown> | undefined | null\n if (layout === undefined || layout === null) {\n accumulator.add({\n path: \"preset.layout\",\n severity: \"low\",\n description: \"layout定義が存在しません(単一ペイン運用が前提)\",\n nextStep: \"単一ペイン前提でもPlan出力に影響しないことをFunctional Coreで確認する\",\n })\n return\n }\n\n if (!Array.isArray(layout.panes)) {\n accumulator.add({\n path: \"preset.layout.panes\",\n severity: \"low\",\n description: \"panes配列が存在しないか配列ではありません\",\n nextStep: \"レイアウト定義の構造を正規化し、Plan生成の入力契約を明示する\",\n })\n }\n}\n\nconst countFocusFlags = (node: unknown): number => {\n if (Array.isArray(node)) {\n return node.reduce((sum, child) => sum + countFocusFlags(child), 0)\n }\n\n if (node === null || typeof node !== \"object\") {\n return 0\n }\n\n const record = node as Record<string, unknown>\n const selfFocus = record.focus === true ? 1 : 0\n const childFocus = Array.isArray(record.panes)\n ? record.panes.reduce((sum, child) => sum + countFocusFlags(child), 0)\n : 0\n\n return selfFocus + childFocus\n}\n\nconst sortBySeverity = (findings: DiagnosticsFinding[]): DiagnosticsFinding[] => {\n return [...findings].sort((a, b) => severityRank[b.severity] - severityRank[a.severity])\n}\n\nconst sortBacklog = (backlog: Map<string, DiagnosticsBacklogItem>): DiagnosticsBacklogItem[] => {\n return [...backlog.values()].sort((a, b) => severityRank[b.severity] - severityRank[a.severity])\n}\n\nconst maxSeverity = (left: DiagnosticsSeverity, right: DiagnosticsSeverity): DiagnosticsSeverity => {\n return severityRank[left] >= severityRank[right] ? left : right\n}\n","import { parse } from \"yaml\"\nimport { createFunctionalError, type FunctionalCoreError } from \"./errors.ts\"\n\nexport type CompilePresetInput = {\n readonly document: string\n readonly source: string\n}\n\nexport type FunctionalTerminalPane = {\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 focus?: boolean\n readonly options?: Readonly<Record<string, unknown>>\n}\n\nexport type FunctionalSplitPane = {\n readonly kind: \"split\"\n readonly orientation: \"horizontal\" | \"vertical\"\n readonly ratio: ReadonlyArray<number>\n readonly panes: ReadonlyArray<FunctionalLayoutNode>\n}\n\nexport type FunctionalLayoutNode = FunctionalTerminalPane | FunctionalSplitPane\n\ntype FunctionalPresetMetadata = {\n readonly source: string\n}\n\nexport type FunctionalPreset = {\n readonly name: string\n readonly version: string\n readonly command?: string\n readonly layout?: FunctionalLayoutNode\n readonly metadata: FunctionalPresetMetadata\n}\n\nexport type CompilePresetSuccess = {\n readonly preset: FunctionalPreset\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: `YAMLの解析に失敗しました: ${(error as Error).message}`,\n details: {\n reason: error instanceof Error ? error.message : String(error),\n },\n })\n }\n\n if (!isRecord(parsed)) {\n throw compileError(\"PRESET_INVALID_DOCUMENT\", {\n source,\n message: \"プリセット定義がオブジェクトではありません\",\n path: \"preset\",\n })\n }\n\n const name = typeof parsed.name === \"string\" && parsed.name.trim().length > 0 ? parsed.name : \"Unnamed preset\"\n\n const layout = parseLayoutNode(parsed.layout, {\n source,\n path: \"preset.layout\",\n })\n\n return {\n preset: {\n name,\n version: \"legacy\",\n command: typeof parsed.command === \"string\" ? parsed.command : undefined,\n layout: layout ?? undefined,\n metadata: { source },\n },\n }\n}\n\nconst parseLayoutNode = (\n node: unknown,\n context: { readonly source: string; readonly path: string },\n): FunctionalLayoutNode | 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: \"レイアウトノードの形式が不正です\",\n path: context.path,\n details: { node },\n })\n }\n\n if (typeof node.type === \"string\" && Array.isArray(node.panes)) {\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: \"レイアウトノードの形式が不正です\",\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): FunctionalSplitPane => {\n const orientation = node.type\n if (orientation !== \"horizontal\" && orientation !== \"vertical\") {\n throw compileError(\"LAYOUT_INVALID_ORIENTATION\", {\n source: context.source,\n message: \"layout.type は horizontal か vertical である必要があります\",\n path: `${context.path}.type`,\n details: { type: orientation },\n })\n }\n\n if (!Array.isArray(node.panes) || node.panes.length === 0) {\n throw compileError(\"LAYOUT_PANES_MISSING\", {\n source: context.source,\n message: \"panes 配列が存在しません\",\n path: `${context.path}.panes`,\n })\n }\n\n if (!Array.isArray(node.ratio) || node.ratio.length === 0) {\n throw compileError(\"LAYOUT_RATIO_MISSING\", {\n source: context.source,\n message: \"ratio 配列が存在しません\",\n path: `${context.path}.ratio`,\n })\n }\n\n if (node.ratio.length !== node.panes.length) {\n throw compileError(\"LAYOUT_RATIO_MISMATCH\", {\n source: context.source,\n message: \"ratio 配列と panes 配列の長さが一致しません\",\n path: context.path,\n details: {\n ratioLength: node.ratio.length,\n panesLength: node.panes.length,\n },\n })\n }\n\n const ratio = node.ratio.map((value, index) => {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n throw compileError(\"RATIO_INVALID_VALUE\", {\n source: context.source,\n message: \"ratio の値が正の数値ではありません\",\n path: `${context.path}.ratio[${index}]`,\n details: { value },\n })\n }\n return value\n })\n\n const panes = node.panes.map((child, index) =>\n parseLayoutNode(child, {\n source: context.source,\n path: `${context.path}.panes[${index}]`,\n }),\n )\n\n return {\n kind: \"split\",\n orientation,\n ratio,\n panes: panes.filter((pane): pane is FunctionalLayoutNode => pane !== null),\n }\n}\n\nconst parseTerminalPane = (node: Record<string, unknown>): FunctionalTerminalPane => {\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 focus = node.focus === true ? true : undefined\n const env = normalizeEnv(node.env)\n\n const knownKeys = new Set([\"name\", \"command\", \"cwd\", \"env\", \"focus\", \"options\", \"title\", \"delay\"])\n const options = collectOptions(node, knownKeys)\n\n return {\n kind: \"terminal\",\n name,\n command,\n cwd,\n env,\n focus,\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 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): FunctionalCoreError => {\n return createFunctionalError(\"compile\", {\n code,\n message: error.message,\n source: error.source,\n path: error.path,\n details: error.details,\n })\n}\n","import type { FunctionalLayoutNode, FunctionalPreset, FunctionalSplitPane, FunctionalTerminalPane } from \"./compile.ts\"\nimport { createFunctionalError, type FunctionalCoreError } from \"./errors.ts\"\n\ntype CreateLayoutPlanInput = {\n readonly preset: FunctionalPreset\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 focus: boolean\n readonly options?: Readonly<Record<string, unknown>>\n}\n\ntype PlanSplit = {\n readonly kind: \"split\"\n readonly id: string\n readonly orientation: \"horizontal\" | \"vertical\"\n readonly ratio: ReadonlyArray<number>\n readonly panes: ReadonlyArray<PlanNode>\n}\n\nexport type PlanNode = PlanTerminal | PlanSplit\n\nexport type LayoutPlan = {\n readonly root: PlanNode\n readonly focusPaneId: string\n}\n\nexport type CreateLayoutPlanSuccess = {\n readonly plan: LayoutPlan\n}\n\nexport const createLayoutPlan = ({ preset }: CreateLayoutPlanInput): CreateLayoutPlanSuccess => {\n if (!preset.layout) {\n const terminal = createTerminalNode({\n id: \"root\",\n terminal: {\n kind: \"terminal\",\n name: preset.name,\n command: preset.command,\n },\n focusOverride: true,\n })\n\n return {\n plan: {\n root: terminal,\n focusPaneId: terminal.id,\n },\n }\n }\n\n const { node, focusPaneIds, terminalPaneIds } = buildLayoutNode(preset.layout, {\n parentId: \"root\",\n path: \"preset.layout\",\n source: preset.metadata.source,\n })\n\n if (focusPaneIds.length > 1) {\n throw planError(\"FOCUS_CONFLICT\", {\n message: \"複数のペインでfocusが指定されています\",\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: \"ターミナルペインが存在しません\",\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: FunctionalLayoutNode,\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: FunctionalSplitPane,\n context: { readonly parentId: string; readonly path: string; readonly source: string },\n): BuildResult => {\n const ratio = normalizeRatio(node.ratio, context)\n\n const panes: PlanNode[] = []\n const focusPaneIds: string[] = []\n const terminalPaneIds: string[] = []\n\n for (let index = 0; index < node.panes.length; index += 1) {\n const childId = `${context.parentId}.${index}`\n const childContext = {\n parentId: childId,\n path: `${context.path}.panes[${index}]`,\n source: context.source,\n }\n\n const childResult = buildLayoutNode(node.panes[index]!, childContext)\n panes.push(childResult.node)\n focusPaneIds.push(...childResult.focusPaneIds)\n terminalPaneIds.push(...childResult.terminalPaneIds)\n }\n\n return {\n node: {\n kind: \"split\",\n id: context.parentId,\n orientation: node.orientation,\n ratio,\n panes,\n },\n focusPaneIds,\n terminalPaneIds,\n }\n}\n\nconst createTerminalNode = ({\n id,\n terminal,\n focusOverride,\n}: {\n readonly id: string\n readonly terminal: FunctionalTerminalPane\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 options: terminal.options,\n focus: focusOverride === true ? true : terminal.focus === true,\n }\n}\n\nconst ensureFocus = (node: PlanNode, focusPaneId: string): PlanNode => {\n if (node.kind === \"terminal\") {\n return {\n ...node,\n focus: node.id === focusPaneId,\n }\n }\n\n return {\n ...node,\n panes: node.panes.map((pane) => ensureFocus(pane, focusPaneId)),\n }\n}\n\nconst normalizeRatio = (\n ratio: ReadonlyArray<number>,\n context: { readonly path: string; readonly source: string },\n): number[] => {\n const total = ratio.reduce((sum, value, index) => {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n throw planError(\"RATIO_INVALID_VALUE\", {\n message: \"ratio の値が非負の数値ではありません\",\n path: `${context.path}.ratio[${index}]`,\n source: context.source,\n details: { value },\n })\n }\n return sum + value\n }, 0)\n\n if (total === 0) {\n return ratio.map(() => 1 / ratio.length)\n }\n\n return ratio.map((value) => value / total)\n}\n\nconst planError = (\n code: string,\n error: {\n readonly message: string\n readonly source?: string\n readonly path?: string\n readonly details?: Readonly<Record<string, unknown>>\n },\n): FunctionalCoreError => {\n return createFunctionalError(\"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.ts\"\n\ntype EmitPlanInput = {\n readonly plan: LayoutPlan\n}\n\ntype CommandStepKind = \"split\" | \"focus\"\n\nexport type CommandStep = {\n readonly id: string\n readonly kind: CommandStepKind\n readonly command: ReadonlyArray<string>\n readonly summary: string\n readonly targetPaneId?: string\n readonly createdPaneId?: string\n}\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 focus: boolean\n readonly name: string\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 command: [\"select-pane\", \"-t\", plan.focusPaneId],\n summary: `select pane ${plan.focusPaneId}`,\n targetPaneId: plan.focusPaneId,\n })\n\n const hash = createPlanHash(plan, steps)\n const initialPaneId = determineInitialPaneId(plan.root)\n const terminals = collectTerminals(plan.root)\n\n return {\n steps,\n summary: {\n stepsCount: steps.length,\n focusPaneId: plan.focusPaneId,\n initialPaneId,\n },\n terminals,\n hash,\n }\n}\n\nconst collectSplitSteps = (node: PlanNode, steps: CommandStep[]): void => {\n if (node.kind === \"terminal\") {\n return\n }\n\n appendSplitSteps(node, steps)\n node.panes.forEach((pane) => collectSplitSteps(pane, steps))\n}\n\nconst appendSplitSteps = (node: SplitNode, steps: CommandStep[]): void => {\n const directionFlag = node.orientation === \"horizontal\" ? \"-h\" : \"-v\"\n\n for (let index = 1; index < node.panes.length; index += 1) {\n const remainingIncludingTarget = node.ratio.slice(index - 1).reduce((sum, value) => sum + value, 0)\n const remainingAfterTarget = node.ratio.slice(index).reduce((sum, value) => sum + value, 0)\n\n const desiredPercentage =\n remainingIncludingTarget === 0 ? 0 : (remainingAfterTarget / remainingIncludingTarget) * 100\n const percentage = Math.max(1, Math.round(desiredPercentage))\n const targetPaneId = node.panes[index - 1]?.id ?? node.id\n const createdPaneId = node.panes[index]?.id\n\n steps.push({\n id: `${node.id}:split:${index}`,\n kind: \"split\",\n command: [\"split-window\", directionFlag, \"-t\", targetPaneId, \"-p\", String(Math.min(percentage, 99))],\n summary: `split ${targetPaneId} (${directionFlag})`,\n targetPaneId,\n createdPaneId,\n })\n }\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 focus: node.focus,\n name: node.name,\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 { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { stringify as toYAML } from \"yaml\"\nimport { createRequire } from \"module\"\nimport { createPresetManager } from \"./layout/preset.ts\"\nimport { resolveWindowMode } from \"./cli/window-mode.ts\"\nimport { createPaneKillPrompter } from \"./cli/user-prompt.ts\"\nimport type { Preset, PresetInfo, WindowMode } from \"./models/types\"\nimport type { CommandExecutor } from \"./types/command-executor.ts\"\nimport type { PresetManager } from \"./types/preset-manager.ts\"\nimport { createRealExecutor, createDryRunExecutor } from \"./executor/index.ts\"\nimport { createTerminalBackend } from \"./executor/backend-factory.ts\"\nimport { resolveTerminalBackendKind } from \"./executor/backend-resolver.ts\"\nimport type { DryRunStep, TerminalBackendKind } from \"./executor/terminal-backend.ts\"\nimport { createLogger, LogLevel, type Logger } from \"./utils/logger.ts\"\nimport {\n runDiagnostics,\n compilePreset as defaultCompilePreset,\n createLayoutPlan as defaultCreateLayoutPlan,\n emitPlan as defaultEmitPlan,\n} from \"./core/index.ts\"\nimport type {\n DiagnosticsReport,\n DiagnosticsSeverity,\n CompilePresetInput,\n PlanEmission,\n FunctionalCoreError,\n CompilePresetSuccess,\n CreateLayoutPlanSuccess,\n} from \"./core/index.ts\"\nimport { isFunctionalCoreError } from \"./core/index.ts\"\n\nconst KNOWN_ISSUES: ReadonlyArray<string> = [\n \"LayoutEngineがtmux依存とI/Oを同一クラスで扱っている\",\n \"dry-run実行と本番適用でPlan構造が共有されていない\",\n \"Loggerが境界層とFunctional Coreの責務を混在させている\",\n]\n\nconst formatSeverityTag = (severity: DiagnosticsSeverity): string => {\n switch (severity) {\n case \"high\":\n return chalk.red(\"[HIGH]\")\n case \"medium\":\n return chalk.yellow(\"[MEDIUM]\")\n case \"low\":\n default:\n return chalk.blue(\"[LOW]\")\n }\n}\n\nexport type FunctionalCoreBridge = {\n readonly compilePreset: (input: CompilePresetInput) => ReturnType<typeof defaultCompilePreset>\n readonly createLayoutPlan: (\n input: Parameters<typeof defaultCreateLayoutPlan>[0],\n ) => ReturnType<typeof defaultCreateLayoutPlan>\n readonly emitPlan: (input: Parameters<typeof defaultEmitPlan>[0]) => ReturnType<typeof defaultEmitPlan>\n}\n\nexport type CLIOptions = {\n readonly presetManager?: PresetManager\n readonly createCommandExecutor?: (options: { verbose: boolean; dryRun: boolean }) => CommandExecutor\n readonly functionalCore?: FunctionalCoreBridge\n}\n\nexport type CLI = {\n run(args?: string[]): Promise<void>\n}\n\nexport const createCli = (options: CLIOptions = {}): CLI => {\n const presetManager = options.presetManager ?? createPresetManager()\n const createCommandExecutor =\n options.createCommandExecutor ??\n ((opts: { verbose: boolean; dryRun: boolean }): CommandExecutor => {\n if (opts.dryRun) {\n return createDryRunExecutor({ verbose: opts.verbose })\n }\n return createRealExecutor({ verbose: opts.verbose })\n })\n\n const functionalCore: FunctionalCoreBridge =\n options.functionalCore ??\n ({\n compilePreset: defaultCompilePreset,\n createLayoutPlan: defaultCreateLayoutPlan,\n emitPlan: defaultEmitPlan,\n } as const)\n\n const program = new Command()\n const require = createRequire(import.meta.url)\n const { version } = require(\"../package.json\") as { version: string }\n let logger: Logger = createLogger()\n\n const renderDiagnosticsReport = (report: DiagnosticsReport): void => {\n console.log(chalk.bold(\"\\nFunctional Core Diagnostics\\n\"))\n\n if (report.backlog.length > 0) {\n console.log(chalk.bold(\"改善バックログ\"))\n report.backlog.forEach((item, index) => {\n const prefix = `${index + 1}. ${formatSeverityTag(item.severity)}`\n console.log(`${prefix} ${item.summary}`)\n item.actions.forEach((action) => {\n console.log(` - ${action}`)\n })\n })\n console.log(\"\")\n }\n\n if (report.findings.length > 0) {\n console.log(chalk.bold(\"診断結果\"))\n report.findings.forEach((finding) => {\n console.log(`${formatSeverityTag(finding.severity)} ${finding.path} :: ${finding.description}`)\n })\n console.log(\"\")\n }\n\n if (report.nextSteps.length > 0) {\n console.log(chalk.bold(\"次のアクション\"))\n report.nextSteps.forEach((step) => {\n console.log(` - ${step}`)\n })\n console.log(\"\")\n }\n }\n\n const renderDryRun = (steps: ReadonlyArray<DryRunStep>): void => {\n console.log(chalk.bold(\"\\nPlanned terminal steps (dry-run)\"))\n steps.forEach((step, index) => {\n console.log(` ${index + 1}. [${step.backend}] ${step.summary}: ${step.command}`)\n })\n }\n\n const buildPresetDocument = (preset: Preset, presetName?: string): string => {\n const document: Record<string, unknown> = {\n name: preset.name ?? presetName ?? \"vde-layout\",\n command: preset.command,\n layout: preset.layout,\n }\n\n if (typeof preset.command !== \"string\" || preset.command.length === 0) {\n delete document.command\n }\n\n if (preset.layout === undefined || preset.layout === null) {\n delete document.layout\n }\n\n return toYAML(document)\n }\n\n const buildPresetSource = (presetName?: string): string => {\n return typeof presetName === \"string\" && presetName.length > 0 ? `preset://${presetName}` : \"preset://default\"\n }\n\n 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\n const handleFunctionalError = (error: FunctionalCoreError): never => {\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 logger.error(lines.join(\"\\n\"))\n process.exit(1)\n }\n\n const handleError = (error: unknown): never => {\n if (error instanceof Error) {\n logger.error(error.message, error)\n } else {\n logger.error(\"An unexpected error occurred\")\n }\n\n process.exit(1)\n }\n\n const handlePipelineFailure = (error: unknown): never => {\n if (isFunctionalCoreError(error)) {\n return handleFunctionalError(error)\n }\n return handleError(error)\n }\n\n const listPresets = async (): Promise<never> => {\n try {\n await presetManager.loadConfig()\n const presets = presetManager.listPresets()\n\n if (presets.length === 0) {\n logger.warn(\"No presets defined\")\n process.exit(0)\n }\n\n console.log(chalk.bold(\"Available presets:\\n\"))\n\n const maxKeyLength = Math.max(...presets.map((p) => p.key.length))\n\n presets.forEach((preset: PresetInfo) => {\n const paddedKey = preset.key.padEnd(maxKeyLength + 2)\n const description = preset.description ?? \"\"\n console.log(` ${chalk.cyan(paddedKey)} ${description}`)\n })\n\n process.exit(0)\n } catch (error) {\n return handleError(error)\n }\n }\n\n const diagnosePreset = async (presetName: string | undefined): Promise<never> => {\n try {\n await presetManager.loadConfig()\n const preset =\n typeof presetName === \"string\" && presetName.length > 0\n ? presetManager.getPreset(presetName)\n : presetManager.getDefaultPreset()\n\n const presetDocument = toYAML(preset ?? {})\n const report = runDiagnostics({\n presetDocument,\n knownIssues: KNOWN_ISSUES,\n })\n\n renderDiagnosticsReport(report)\n process.exit(0)\n } catch (error) {\n return handleError(error)\n }\n }\n\n const executePreset = async (\n presetName: string | undefined,\n options: {\n verbose: boolean\n dryRun: boolean\n currentWindow: boolean\n newWindow: boolean\n backend?: string\n },\n ): Promise<never> => {\n try {\n await presetManager.loadConfig()\n\n const preset =\n typeof presetName === \"string\" && presetName.length > 0\n ? presetManager.getPreset(presetName)\n : presetManager.getDefaultPreset()\n\n const cliWindowMode = determineCliWindowMode({\n currentWindow: options.currentWindow,\n newWindow: options.newWindow,\n })\n const defaults = presetManager.getDefaults()\n const windowModeResolution = resolveWindowMode({\n cli: cliWindowMode,\n preset: preset.windowMode,\n defaults: defaults?.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 env: process.env,\n })\n logger.info(`Terminal backend: ${backendKind}`)\n\n const backend = createTerminalBackend(backendKind, {\n executor,\n logger,\n dryRun: options.dryRun,\n verbose: options.verbose,\n prompt: confirmPaneClosure,\n cwd: process.cwd(),\n paneId: process.env.WEZTERM_PANE,\n })\n\n await backend.verifyEnvironment()\n\n if (options.dryRun === true) {\n console.log(\"[DRY RUN] No actual commands will be executed\")\n }\n\n let compileResult: CompilePresetSuccess\n let planResult: CreateLayoutPlanSuccess\n let emission: PlanEmission\n\n try {\n compileResult = functionalCore.compilePreset({\n document: buildPresetDocument(preset, presetName),\n source: buildPresetSource(presetName),\n })\n planResult = functionalCore.createLayoutPlan({ preset: compileResult.preset })\n emission = functionalCore.emitPlan({ plan: planResult.plan })\n } catch (error) {\n return handlePipelineFailure(error)\n }\n\n if (options.dryRun === true) {\n const dryRunSteps = backend.getDryRunSteps(emission)\n renderDryRun(dryRunSteps)\n } else {\n try {\n const executionResult = await backend.applyPlan({\n emission,\n windowMode,\n windowName: preset.name ?? presetName ?? \"vde-layout\",\n })\n logger.info(`Executed ${executionResult.executedSteps} ${backendKind} steps`)\n } catch (error) {\n return handlePipelineFailure(error)\n }\n }\n\n logger.success(`✓ Applied preset \"${preset.name}\"`)\n process.exit(0)\n } catch (error) {\n return handleError(error)\n }\n }\n\n const setupProgram = (): void => {\n program\n .name(\"vde-layout\")\n .description(\"VDE (Vibrant Development Environment) Layout Manager - tmux pane layout management tool\")\n .version(version, \"-v, --version\", \"Show version\")\n .helpOption(\"-h, --help\", \"Show help\")\n\n program.option(\"--verbose\", \"Show detailed logs\", false)\n program.option(\"-V\", \"Show version (deprecated; use -v)\")\n program.option(\"--dry-run\", \"Display commands without executing\", false)\n program.option(\"--backend <backend>\", \"Select terminal backend (tmux or wezterm)\")\n program.option(\"--config <path>\", \"Path to configuration file\")\n program.option(\"--current-window\", \"Use the current tmux window for layout (kills other panes)\", false)\n program.option(\"--new-window\", \"Always create a new tmux window for layout\", false)\n\n program\n .command(\"list\")\n .description(\"List available presets\")\n .action(async () => {\n await listPresets()\n })\n\n program\n .command(\"diagnose\")\n .description(\"Functional Coreリライトに向けた診断レポートを表示する\")\n .argument(\"[preset]\", 'Preset name (defaults to \"default\" preset when omitted)')\n .action(async (presetName?: string) => {\n await diagnosePreset(presetName)\n })\n\n program\n .argument(\"[preset]\", 'Preset name (defaults to \"default\" preset when omitted)')\n .action(async (presetName?: string) => {\n const opts = program.opts<{\n verbose?: boolean\n dryRun?: boolean\n currentWindow?: boolean\n newWindow?: boolean\n backend?: string\n }>()\n await executePreset(presetName, {\n verbose: opts.verbose === true,\n dryRun: opts.dryRun === true,\n currentWindow: opts.currentWindow === true,\n newWindow: opts.newWindow === true,\n backend: opts.backend,\n })\n })\n }\n\n setupProgram()\n\n const run = async (args: string[] = process.argv.slice(2)): Promise<void> => {\n if (args.includes(\"-V\")) {\n console.log(version)\n return\n }\n\n const requestedVersion = args.some((arg) => arg === \"--version\" || arg === \"-v\")\n const requestedHelp = args.includes(\"--help\") || args.includes(\"-h\")\n try {\n await program.parseAsync(args, { from: \"user\" })\n const opts = program.opts<{\n verbose?: boolean\n config?: string\n V?: boolean\n currentWindow?: boolean\n newWindow?: boolean\n }>()\n\n if (requestedVersion || requestedHelp) {\n return\n }\n\n if (opts.verbose === true) {\n logger = createLogger({ level: LogLevel.INFO })\n } else {\n logger = createLogger()\n }\n\n if (\n typeof opts.config === \"string\" &&\n opts.config.length > 0 &&\n typeof presetManager.setConfigPath === \"function\"\n ) {\n presetManager.setConfigPath(opts.config)\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Process exited\")) {\n throw error\n }\n handleError(error)\n }\n }\n\n return { run }\n}\n","#!/usr/bin/env node\nimport { createCli } from \"./cli.ts\"\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 await cli.run(process.argv.slice(2))\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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vde-layout",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Terminal multiplexer layout management tool for VDE (Vibe Coding Development Environment)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",