{
  "version": 3,
  "sources": ["../src/file-context.ts", "../src/external-editor.ts", "../src/file-context-explorer.ts", "../src/content-search-session.ts", "../src/content-search.ts", "../src/content-search-ui.ts", "../src/file-browser.ts", "../src/file-browser-ui.ts", "../src/file-context-preview-ui.ts", "../src/file-search.ts", "../src/file-context-settings.ts", "../src/file-context-menu.ts", "../src/git-context.ts"],
  "sourcesContent": ["import { createHash } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport { lstat, open, readdir, realpath } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { editProjectFileInExternalEditor } from \"./external-editor.js\";\nimport { FileQuoteExplorer, type FileQuoteExplorerResult } from \"./file-context-explorer.js\";\nimport { type FileContextMenuQuote, showFileContextMenu } from \"./file-context-menu.js\";\nimport {\n  awaitFileContextSettingsWrites,\n  fileContextSettingsPath,\n  type LoadedFileContextSettings,\n  loadFileContextSettings,\n  updateFileContextSettings,\n} from \"./file-context-settings.js\";\nimport { createGitContext } from \"./git-context.js\";\n\nconst WIDGET_KEY = \"file-context\";\nconst DEFAULT_MAX_FILES = 5_000;\nconst DEFAULT_MAX_BYTES = 1_000_000;\nconst MAX_QUOTE_BYTES = 50_000;\nconst MAX_QUOTE_LINES = 500;\nconst MAX_PENDING_QUOTES = 8;\nconst MAX_PENDING_QUOTE_BYTES = 100_000;\nconst IGNORED_DIRECTORIES = new Set([\n  \".git\",\n  \".hg\",\n  \".svn\",\n  \".next\",\n  \"build\",\n  \"coverage\",\n  \"dist\",\n  \"node_modules\",\n  \"target\",\n]);\n\nexport interface FileQuoteGitProvenance {\n  head: string;\n  branch?: string;\n  status?: string;\n  revision?: string;\n  blob?: string;\n  contentSha256: string;\n  source?: \"worktree\" | \"revision\" | \"git_diff\";\n  base?: string;\n}\n\nexport type FileQuoteGitProvenanceInput = Omit<FileQuoteGitProvenance, \"contentSha256\">;\n\nexport interface FileQuote {\n  path: string;\n  startLine: number;\n  endLine: number;\n  text: string;\n  git?: FileQuoteGitProvenance;\n}\n\nexport interface LoadedProjectTextFile {\n  path: string;\n  lines: string[];\n}\n\ninterface DiscoveryOptions {\n  maxFiles?: number;\n  signal?: AbortSignal;\n}\n\ninterface LoadOptions {\n  maxBytes?: number;\n  beforeOpen?: () => Promise<void>;\n  signal?: AbortSignal;\n}\n\ninterface ActiveExplorer {\n  controller: AbortController;\n  component?: FileQuoteExplorer;\n}\n\ninterface PendingQuote {\n  id: string;\n  quote: FileQuote;\n}\n\ninterface ExplorerRunOptions {\n  menuOwned?: boolean;\n  signal?: AbortSignal;\n}\n\ntype ExplorerRunResult = \"stay\" | \"close\";\ntype ExplorerDiscovery = [string[], Awaited<ReturnType<typeof createGitContext>>];\n\nexport async function discoverProjectFiles(root: string, options: DiscoveryOptions = {}): Promise<string[]> {\n  const maxFiles = Math.max(1, options.maxFiles ?? DEFAULT_MAX_FILES);\n  const files: string[] = [];\n  options.signal?.throwIfAborted();\n\n  const canonicalRoot = await realpath(root);\n  const directories: Array<{ directory: string; prefix: string }> = [{ directory: canonicalRoot, prefix: \"\" }];\n  options.signal?.throwIfAborted();\n\n  for (let index = 0; index < directories.length && files.length < maxFiles; index += 1) {\n    options.signal?.throwIfAborted();\n    const current = directories[index];\n    if (!current) break;\n    const { directory, prefix } = current;\n    const entries = (await readdir(directory, { withFileTypes: true })).sort((left, right) =>\n      compareStrings(left.name, right.name),\n    );\n    options.signal?.throwIfAborted();\n    for (const entry of entries) {\n      options.signal?.throwIfAborted();\n      if (IGNORED_DIRECTORIES.has(entry.name) || entry.isSymbolicLink()) continue;\n      const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;\n      const absolutePath = resolve(directory, entry.name);\n      if (entry.isDirectory()) {\n        directories.push({ directory: absolutePath, prefix: relativePath });\n      } else if (entry.isFile()) {\n        files.push(relativePath);\n        if (files.length >= maxFiles) break;\n      }\n    }\n  }\n  options.signal?.throwIfAborted();\n  return files.sort(compareStrings);\n}\n\nexport async function loadProjectTextFile(\n  root: string,\n  projectPath: string,\n  options: LoadOptions = {},\n): Promise<LoadedProjectTextFile> {\n  options.signal?.throwIfAborted();\n  if (!projectPath || isAbsolute(projectPath)) throw new Error(\"File path is outside the project\");\n  const canonicalRoot = await realpath(root);\n  options.signal?.throwIfAborted();\n  const candidate = resolve(canonicalRoot, projectPath);\n  if (!isInside(canonicalRoot, candidate)) throw new Error(\"File path is outside the project\");\n\n  let canonicalFile: string;\n  try {\n    canonicalFile = await realpath(candidate);\n  } catch (error: unknown) {\n    throw new Error(`Cannot open ${projectPath}: ${formatError(error)}`);\n  }\n  options.signal?.throwIfAborted();\n  if (!isInside(canonicalRoot, canonicalFile)) throw new Error(\"File path is outside the project\");\n  const info = await lstat(canonicalFile);\n  options.signal?.throwIfAborted();\n  if (!info.isFile()) throw new Error(`${projectPath} is not a regular file`);\n\n  const maxBytes = Math.max(1, options.maxBytes ?? DEFAULT_MAX_BYTES);\n  if (info.size > maxBytes) throw new Error(`${projectPath} exceeds ${maxBytes} bytes`);\n  await options.beforeOpen?.();\n  options.signal?.throwIfAborted();\n  let file: Awaited<ReturnType<typeof open>>;\n  try {\n    file = await open(canonicalFile, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));\n  } catch (error: unknown) {\n    throw new Error(`Cannot safely open ${projectPath}: ${formatError(error)}`);\n  }\n  try {\n    options.signal?.throwIfAborted();\n    const openedInfo = await file.stat();\n    options.signal?.throwIfAborted();\n    if (!openedInfo.isFile()) throw new Error(`${projectPath} is not a regular file`);\n    if (openedInfo.dev !== info.dev || openedInfo.ino !== info.ino) {\n      throw new Error(`${projectPath} changed while it was being opened safely`);\n    }\n    if (openedInfo.size > maxBytes) throw new Error(`${projectPath} exceeds ${maxBytes} bytes`);\n    const buffer = Buffer.alloc(maxBytes + 1);\n    let offset = 0;\n    while (offset < buffer.length) {\n      options.signal?.throwIfAborted();\n      const { bytesRead } = await file.read(buffer, offset, buffer.length - offset, offset);\n      options.signal?.throwIfAborted();\n      if (bytesRead === 0) break;\n      offset += bytesRead;\n    }\n    if (offset > maxBytes) throw new Error(`${projectPath} exceeds ${maxBytes} bytes`);\n    const contents = buffer.subarray(0, offset);\n    if (contents.includes(0)) throw new Error(`${projectPath} appears to be binary`);\n    return {\n      path: projectPath.replaceAll(\"\\\\\", \"/\"),\n      lines: normalizeTextLines(contents.toString(\"utf8\")),\n    };\n  } finally {\n    await file.close();\n  }\n}\n\nexport function createFileQuote(\n  path: string,\n  lines: readonly string[],\n  anchorIndex: number,\n  cursorIndex: number,\n  git?: FileQuoteGitProvenanceInput,\n): FileQuote {\n  if (lines.length === 0) throw new Error(\"Cannot quote an empty file\");\n  const startIndex = Math.max(0, Math.min(anchorIndex, cursorIndex, lines.length - 1));\n  const endIndex = Math.max(0, Math.min(Math.max(anchorIndex, cursorIndex), lines.length - 1));\n  const text = lines.slice(startIndex, endIndex + 1).join(\"\\n\");\n  return createFileQuoteSnapshot(path, startIndex + 1, endIndex + 1, text, git);\n}\n\nexport function createFileQuoteSnapshot(\n  path: string,\n  startLine: number,\n  endLine: number,\n  text: string,\n  git?: FileQuoteGitProvenanceInput,\n): FileQuote {\n  if (!Number.isSafeInteger(startLine) || !Number.isSafeInteger(endLine) || startLine < 1) {\n    throw new Error(\"Quote lines must be positive integers\");\n  }\n  if (endLine < startLine) throw new Error(\"Quote end line precedes its start line\");\n  if (text.split(\"\\n\").length > MAX_QUOTE_LINES) {\n    throw new Error(`Quote exceeds ${MAX_QUOTE_LINES} lines`);\n  }\n  if (Buffer.byteLength(text, \"utf8\") > MAX_QUOTE_BYTES) {\n    throw new Error(`Quote exceeds ${MAX_QUOTE_BYTES} bytes`);\n  }\n  return {\n    path,\n    startLine,\n    endLine,\n    text,\n    ...(git\n      ? {\n          git: {\n            head: git.head,\n            ...(git.branch !== undefined ? { branch: git.branch } : {}),\n            ...(git.status !== undefined ? { status: git.status } : {}),\n            ...(git.revision !== undefined ? { revision: git.revision } : {}),\n            ...(git.blob !== undefined ? { blob: git.blob } : {}),\n            contentSha256: createHash(\"sha256\").update(text, \"utf8\").digest(\"hex\"),\n            ...(git.source !== undefined ? { source: git.source } : {}),\n            ...(git.base !== undefined ? { base: git.base } : {}),\n          },\n        }\n      : {}),\n  };\n}\n\nexport function appendPendingQuote(current: readonly FileQuote[], quote: FileQuote): FileQuote[] {\n  if (current.length >= MAX_PENDING_QUOTES) {\n    throw new Error(`File Context supports at most ${MAX_PENDING_QUOTES} pending quotes`);\n  }\n  const totalBytes = [...current, quote].reduce((total, item) => total + Buffer.byteLength(item.text, \"utf8\"), 0);\n  if (totalBytes > MAX_PENDING_QUOTE_BYTES) {\n    throw new Error(`Pending quotes exceed ${MAX_PENDING_QUOTE_BYTES} bytes`);\n  }\n  return [...current, quote];\n}\n\nexport function formatPromptWithQuote(prompt: string, quote: FileQuote): string {\n  return formatPromptWithQuotes(prompt, [quote]);\n}\n\nexport function formatPromptWithQuotes(prompt: string, quotes: readonly FileQuote[]): string {\n  if (quotes.length === 0) return prompt;\n  return `${formatQuoteContext(quotes)}\\n\\n${prompt}`;\n}\n\nexport function formatQuoteContext(quotes: readonly FileQuote[]): string {\n  const blocks = quotes.map((quote) => {\n    const path = escapeXml(quote.path);\n    const text = escapeXml(quote.text);\n    const attributes = [\n      `path=\"${path}\"`,\n      `lines=\"${quote.startLine}-${quote.endLine}\"`,\n      ...formatGitAttributes(quote.git),\n    ].join(\" \");\n    return `<user_file_quote ${attributes}>\\n${text}\\n</user_file_quote>`;\n  });\n  const description =\n    quotes.length === 1\n      ? \"The user intentionally selected the file excerpt above.\"\n      : \"The user intentionally selected the file excerpts above.\";\n  return `${blocks.join(\"\\n\\n\")}\\n\\n${description}`;\n}\n\ninterface FileQuoteExtensionDependencies {\n  settingsPath?: string;\n  loadSettings?: () => Promise<LoadedFileContextSettings>;\n  updateSettings?: typeof updateFileContextSettings;\n  discoverFiles?: typeof discoverProjectFiles;\n  createGit?: typeof createGitContext;\n}\n\nexport async function registerFileQuoteExtension(\n  pi: ExtensionAPI,\n  dependencies: FileQuoteExtensionDependencies = {},\n): Promise<void> {\n  const settingsPath = dependencies.settingsPath ?? fileContextSettingsPath();\n  const loadSettings = dependencies.loadSettings ?? (() => loadFileContextSettings(settingsPath));\n  const updateSettings = dependencies.updateSettings ?? updateFileContextSettings;\n  let loadedSettings = await loadSettings();\n  const discoverFiles = dependencies.discoverFiles ?? discoverProjectFiles;\n  const createGit = dependencies.createGit ?? createGitContext;\n  let pendingQuotes: PendingQuote[] = [];\n  let nextPendingQuoteId = 1;\n  let activeSessionManager: unknown;\n  let sessionGeneration = 0;\n  let sessionController = new AbortController();\n  const activeExplorers = new Set<ActiveExplorer>();\n  let activeExplorerLaunch: { promise: Promise<void> } | undefined;\n  let activeMenuLaunch: { promise: Promise<void> } | undefined;\n\n  const updatePendingWidget = (ctx: ExtensionContext) => {\n    if (!ctx.hasUI) return;\n    if (pendingQuotes.length === 0) {\n      ctx.ui.setWidget(WIDGET_KEY, undefined);\n      return;\n    }\n    const totalBytes = pendingQuotes.reduce((total, item) => total + Buffer.byteLength(item.quote.text, \"utf8\"), 0);\n    ctx.ui.setWidget(WIDGET_KEY, [\n      ctx.ui.theme.fg(\n        \"accent\",\n        `Next prompt context \u00B7 ${pendingQuotes.length} ${pendingQuotes.length === 1 ? \"snippet\" : \"snippets\"} \u00B7 ~${estimateTokens(totalBytes)} tokens \u00B7 /file-context to review`,\n      ),\n      ...pendingQuotes.map(({ quote }, index) =>\n        ctx.ui.theme.fg(\n          \"muted\",\n          `${index + 1}. ${escapeTerminalControls(quote.path)} \u00B7 lines ${quote.startLine}-${quote.endLine} \u00B7 ~${estimateTokens(Buffer.byteLength(quote.text, \"utf8\"))} tokens`,\n        ),\n      ),\n    ]);\n  };\n\n  const clearPending = (ctx: ExtensionContext) => {\n    pendingQuotes = [];\n    nextPendingQuoteId = 1;\n    updatePendingWidget(ctx);\n  };\n\n  const validatePending = (quote: FileQuote) => {\n    appendPendingQuote(\n      pendingQuotes.map((item) => item.quote),\n      quote,\n    );\n  };\n\n  const appendPending = (quote: FileQuote, ctx: ExtensionContext) => {\n    validatePending(quote);\n    pendingQuotes = [...pendingQuotes, { id: `quote-${nextPendingQuoteId}`, quote }];\n    nextPendingQuoteId += 1;\n    updatePendingWidget(ctx);\n  };\n\n  const isCurrentSession = (owner: unknown, generation: number) =>\n    owner === activeSessionManager && generation === sessionGeneration;\n\n  const menuQuote = ({ id, quote }: PendingQuote): FileContextMenuQuote => ({\n    id,\n    path: quote.path,\n    startLine: quote.startLine,\n    endLine: quote.endLine,\n    text: quote.text,\n  });\n\n  const cancelExplorers = () => {\n    activeExplorerLaunch = undefined;\n    for (const explorer of activeExplorers) {\n      explorer.controller.abort(new DOMException(\"File Context explorer closed\", \"AbortError\"));\n      explorer.component?.dispose();\n    }\n    activeExplorers.clear();\n  };\n\n  const runExplorer = async (ctx: ExtensionContext, options: ExplorerRunOptions = {}): Promise<ExplorerRunResult> => {\n    if (ctx.mode !== \"tui\") {\n      rejectCommand(ctx, \"File Context requires Pi's interactive TUI.\");\n      return \"close\";\n    }\n    const owner = ctx.sessionManager;\n    const generation = sessionGeneration;\n    const activeExplorer: ActiveExplorer = { controller: new AbortController() };\n    const { controller } = activeExplorer;\n    const flowSignal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;\n    activeExplorers.add(activeExplorer);\n    try {\n      const { runCustomInteraction, runTask } = await import(\"@narumitw/pi-tui-kit\");\n      if (!isCurrentSession(owner, generation) || flowSignal.aborted) return \"close\";\n      const task = await runTask(ctx, {\n        label: \"Scanning project files\u2026\",\n        signal: flowSignal,\n        isCurrent: () => isCurrentSession(owner, generation) && !flowSignal.aborted,\n        task: ({ signal }) => Promise.all([discoverFiles(ctx.cwd, { signal }), createGit(ctx.cwd, signal)]),\n        onError: (_taskContext, error) => {\n          ctx.ui.notify(\n            `File Context could not scan project files: ${escapeTerminalControls(formatError(error))}. Open File Context to retry.`,\n            \"error\",\n          );\n        },\n      });\n      if (task.kind === \"cancelled\" || task.kind === \"error\") {\n        return options.menuOwned ? \"stay\" : \"close\";\n      }\n      if (task.kind === \"stale\") return \"close\";\n      const discovery: ExplorerDiscovery = task.value;\n      if (!isCurrentSession(owner, generation) || flowSignal.aborted) return \"close\";\n      const [files, gitContext] = discovery;\n      if (files.length === 0) {\n        ctx.ui.notify(\"File Context found no project files. Choose Add context snippet to retry.\", \"warning\");\n        return options.menuOwned ? \"stay\" : \"close\";\n      }\n      const interaction = await runCustomInteraction<FileQuoteExplorerResult | undefined, ExtensionContext>(ctx, {\n        signal: flowSignal,\n        isCurrent: () => isCurrentSession(owner, generation),\n        onError: () => {},\n        create: ({ tui, theme, keybindings, signal: interactionSignal, complete }) => {\n          const component = new FileQuoteExplorer({\n            tui,\n            theme,\n            keybindings,\n            files,\n            cwd: ctx.cwd,\n            loadFile: (path, signal) =>\n              loadProjectTextFile(ctx.cwd, path, {\n                signal: signal ? AbortSignal.any([signal, interactionSignal]) : interactionSignal,\n              }),\n            editFile: (path, signal) =>\n              editProjectFileInExternalEditor({\n                root: ctx.cwd,\n                projectPath: path,\n                tui,\n                projectTrusted: ctx.isProjectTrusted(),\n                signal: signal ? AbortSignal.any([signal, interactionSignal]) : interactionSignal,\n                isCurrent: () => isCurrentSession(owner, generation) && !interactionSignal.aborted,\n              }),\n            gitContext,\n            rootNavigation: options.menuOwned,\n            getSelectedContextState: () => ({\n              count: pendingQuotes.length,\n              totalBytes: pendingQuotes.reduce((total, item) => total + Buffer.byteLength(item.quote.text, \"utf8\"), 0),\n              maximumCount: MAX_PENDING_QUOTES,\n              maximumBytes: MAX_PENDING_QUOTE_BYTES,\n              maximumSnippetLines: MAX_QUOTE_LINES,\n              maximumSnippetBytes: MAX_QUOTE_BYTES,\n            }),\n            validateQuote: validatePending,\n            onAddAndContinue: (quote) => {\n              if (!isCurrentSession(owner, generation) || interactionSignal.aborted) {\n                throw new DOMException(\"File Context session replaced\", \"AbortError\");\n              }\n              appendPending(quote, ctx);\n              try {\n                ctx.ui.notify(\n                  `Added to next prompt context: ${escapeTerminalControls(quote.path)} \u00B7 lines ${quote.startLine}-${quote.endLine}.`,\n                  \"info\",\n                );\n              } catch {\n                // The widget already reflects the selected snapshot.\n              }\n            },\n            done: complete,\n          });\n          activeExplorer.component = component;\n          return component;\n        },\n      });\n      if (interaction.kind === \"error\") throw interaction.error;\n      const result = interaction.kind === \"completed\" ? interaction.value : undefined;\n      if (!isCurrentSession(owner, generation) || flowSignal.aborted) return \"close\";\n      if (result?.kind === \"quote\") {\n        appendPending(result.quote, ctx);\n        return \"close\";\n      }\n      if (result?.kind === \"reference\") {\n        ctx.ui.pasteToEditor(formatFileReference(result.path));\n        return \"close\";\n      }\n      return result?.kind === \"back\" ? \"stay\" : \"close\";\n    } catch (error: unknown) {\n      if (!isCurrentSession(owner, generation) || flowSignal.aborted || isAbortError(error)) {\n        return \"close\";\n      }\n      try {\n        ctx.ui.notify(\n          `File Context failed: ${escapeTerminalControls(formatError(error))}. Open File Context to retry.`,\n          \"error\",\n        );\n      } catch {\n        // The session may have been replaced while the picker was open.\n      }\n      return options.menuOwned ? \"stay\" : \"close\";\n    } finally {\n      activeExplorers.delete(activeExplorer);\n    }\n  };\n\n  const openExplorer = (ctx: ExtensionContext): Promise<void> => {\n    if (activeExplorerLaunch) return activeExplorerLaunch.promise;\n    if (activeMenuLaunch) return activeMenuLaunch.promise;\n    const launch = { promise: runExplorer(ctx).then(() => undefined) };\n    activeExplorerLaunch = launch;\n    const clearLaunch = () => {\n      if (activeExplorerLaunch === launch) activeExplorerLaunch = undefined;\n    };\n    void launch.promise.then(clearLaunch, clearLaunch);\n    return launch.promise;\n  };\n\n  // Pi snapshots extension shortcuts when the TUI binds them, so settings changes reload Pi.\n  const registeredOpenShortcut = loadedSettings.settings.openShortcut;\n  if (registeredOpenShortcut) {\n    pi.registerShortcut(registeredOpenShortcut, {\n      description: \"Open File Context\",\n      handler: openExplorer,\n    });\n  }\n\n  const openMenu = (ctx: ExtensionCommandContext, start: \"main\" | \"remove\" = \"main\"): Promise<void> => {\n    if (ctx.mode !== \"tui\") {\n      rejectCommand(ctx, \"File Context requires Pi's interactive TUI.\");\n      return Promise.resolve();\n    }\n    if (activeMenuLaunch) return activeMenuLaunch.promise;\n    if (activeExplorerLaunch) return activeExplorerLaunch.promise;\n    if (start === \"remove\" && pendingQuotes.length === 0) {\n      ctx.ui.notify(\"File Context has no context selected for the next prompt.\", \"warning\");\n      return Promise.resolve();\n    }\n    const owner = ctx.sessionManager;\n    const generation = sessionGeneration;\n    const ownerController = sessionController;\n    const isCurrent = () =>\n      isCurrentSession(owner, generation) && ownerController === sessionController && !ownerController.signal.aborted;\n    const promise = showFileContextMenu(ctx, {\n      start,\n      signal: ownerController.signal,\n      isCurrent,\n      getState: () => {\n        if (!isCurrent()) throw new DOMException(\"File Context session replaced\", \"AbortError\");\n        const quotes = pendingQuotes.map(menuQuote);\n        return {\n          quotes,\n          shortcut: loadedSettings.settings.openShortcut,\n          maximumQuotes: MAX_PENDING_QUOTES,\n          maximumBytes: MAX_PENDING_QUOTE_BYTES,\n          totalBytes: quotes.reduce((total, quote) => total + Buffer.byteLength(quote.text, \"utf8\"), 0),\n          settingsPath,\n          settingsInvalidReason: loadedSettings.invalidReason,\n        };\n      },\n      addQuote: (signal) => runExplorer(ctx, { menuOwned: true, signal }),\n      saveShortcut: async (shortcut, signal) => {\n        if (!isCurrent() || signal.aborted) {\n          throw new DOMException(\"File Context session replaced\", \"AbortError\");\n        }\n        const saved = await updateSettings(shortcut, { settingsPath, signal });\n        if (!isCurrent() || signal.aborted) return;\n        loadedSettings = { settings: saved };\n      },\n      removeQuote: (id, signal) => {\n        if (!isCurrent() || signal.aborted) return { kind: \"missing\" };\n        const index = pendingQuotes.findIndex((item) => item.id === id);\n        const selected = pendingQuotes[index];\n        if (!selected) return { kind: \"missing\" };\n        pendingQuotes = pendingQuotes.filter((_item, itemIndex) => itemIndex !== index);\n        updatePendingWidget(ctx);\n        return {\n          kind: \"removed\",\n          quote: menuQuote(selected),\n          remaining: pendingQuotes.length,\n        };\n      },\n    }).then(() => undefined);\n    const launch = { promise };\n    activeMenuLaunch = launch;\n    const clearLaunch = () => {\n      if (activeMenuLaunch === launch) activeMenuLaunch = undefined;\n    };\n    void promise.then(clearLaunch, clearLaunch);\n    return promise;\n  };\n\n  const handleFileContextCommand = async (args: string, ctx: ExtensionCommandContext) => {\n    const normalized = args.trim().toLowerCase();\n    if (!normalized) {\n      await openMenu(ctx);\n      return;\n    }\n    if (normalized === \"browse\") {\n      await openExplorer(ctx);\n      return;\n    }\n    if (normalized === \"remove\") {\n      await openMenu(ctx, \"remove\");\n      return;\n    }\n    rejectCommand(ctx, \"Usage: /file-context [browse|remove]\");\n  };\n  pi.registerCommand(\"file-context\", {\n    description: \"Open the File Context menu\",\n    getArgumentCompletions: (prefix) => {\n      const normalized = prefix.trimStart().toLowerCase();\n      const completions = [\n        { value: \"browse\", label: \"browse\", description: \"Open the file browser directly\" },\n        { value: \"remove\", label: \"remove\", description: \"Review selected context directly\" },\n      ].filter(({ value }) => value.startsWith(normalized));\n      return completions.length > 0 ? completions : null;\n    },\n    handler: handleFileContextCommand,\n  });\n  pi.on(\"session_start\", async (_event, ctx) => {\n    sessionController.abort(new DOMException(\"File Context session replaced\", \"AbortError\"));\n    sessionController = new AbortController();\n    const ownerController = sessionController;\n    activeMenuLaunch = undefined;\n    cancelExplorers();\n    activeSessionManager = ctx.sessionManager;\n    const generation = ++sessionGeneration;\n    clearPending(ctx);\n    const refreshedSettings = await loadSettings();\n    if (\n      !isCurrentSession(ctx.sessionManager, generation) ||\n      ownerController !== sessionController ||\n      ownerController.signal.aborted\n    ) {\n      return;\n    }\n    loadedSettings = refreshedSettings;\n    if (loadedSettings.warning && ctx.hasUI) {\n      ctx.ui.notify(escapeTerminalControls(loadedSettings.warning), \"warning\");\n    }\n  });\n\n  pi.on(\"before_agent_start\", (_event, ctx) => {\n    if (ctx.sessionManager !== activeSessionManager || pendingQuotes.length === 0) return;\n    const quotes = pendingQuotes.map((item) => item.quote);\n    clearPending(ctx);\n    return {\n      message: {\n        customType: \"file-context-quotes\",\n        content: formatQuoteContext(quotes),\n        display: false,\n      },\n    };\n  });\n\n  pi.on(\"session_shutdown\", async (_event, ctx) => {\n    if (ctx.sessionManager !== activeSessionManager) return;\n    sessionController.abort(new DOMException(\"File Context session shut down\", \"AbortError\"));\n    activeMenuLaunch = undefined;\n    cancelExplorers();\n    clearPending(ctx);\n    await awaitFileContextSettingsWrites(settingsPath);\n  });\n}\n\nexport default async function fileQuoteExtension(pi: ExtensionAPI): Promise<void> {\n  await registerFileQuoteExtension(pi);\n}\n\nfunction normalizeTextLines(contents: string): string[] {\n  if (contents === \"\") return [];\n  const lines = contents.replaceAll(\"\\r\\n\", \"\\n\").replaceAll(\"\\r\", \"\\n\").split(\"\\n\");\n  if (lines.at(-1) === \"\") lines.pop();\n  return lines;\n}\n\nfunction formatFileReference(path: string): string {\n  const escaped = path.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n  return /\\s|[\"\\\\]/.test(path) ? `@\"${escaped}\" ` : `@${path} `;\n}\n\nfunction compareStrings(left: string, right: string): number {\n  return left < right ? -1 : left > right ? 1 : 0;\n}\n\nfunction estimateTokens(bytes: number): number {\n  return Math.max(1, Math.ceil(bytes / 4));\n}\n\nfunction isInside(root: string, candidate: string): boolean {\n  const result = relative(root, candidate);\n  return result === \"\" || (!result.startsWith(`..${sep}`) && result !== \"..\" && !isAbsolute(result));\n}\n\nfunction formatGitAttributes(git: FileQuoteGitProvenance | undefined): string[] {\n  if (!git) return [];\n  return [\n    [\"git_head\", git.head],\n    [\"git_branch\", git.branch],\n    [\"git_status\", git.status],\n    [\"git_revision\", git.revision],\n    [\"git_blob\", git.blob],\n    [\"content_sha256\", git.contentSha256],\n    [\"source\", git.source],\n    [\"git_base\", git.base],\n  ].flatMap(([name, value]) => (value ? [`${name}=\"${escapeXml(value)}\"`] : []));\n}\n\nfunction escapeXml(value: string): string {\n  return value\n    .replaceAll(\"&\", \"&amp;\")\n    .replaceAll(\"<\", \"&lt;\")\n    .replaceAll(\">\", \"&gt;\")\n    .replaceAll('\"', \"&quot;\")\n    .replaceAll(\"'\", \"&apos;\");\n}\n\nfunction escapeTerminalControls(text: string): string {\n  return [...text]\n    .map((character) => {\n      const code = character.charCodeAt(0);\n      return code <= 31 || (code >= 127 && code <= 159) ? `\\\\x${code.toString(16).padStart(2, \"0\")}` : character;\n    })\n    .join(\"\");\n}\n\nfunction rejectCommand(ctx: ExtensionContext, message: string): void {\n  if (ctx.hasUI) {\n    ctx.ui.notify(message, \"warning\");\n    return;\n  }\n  throw new Error(message);\n}\n\nfunction isAbortError(error: unknown): boolean {\n  return error instanceof Error && error.name === \"AbortError\";\n}\n\nfunction formatError(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n", "import { type ChildProcess, spawn } from \"node:child_process\";\nimport { lstat, realpath } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { getAgentDir, SettingsManager, withFileMutationQueue } from \"@earendil-works/pi-coding-agent\";\nimport type { TUI } from \"@earendil-works/pi-tui\";\n\nexport interface ExternalEditorProcess {\n  readonly killed: boolean;\n  kill(): boolean;\n  once(event: \"close\", listener: (code: number | null) => void): this;\n  once(event: \"error\", listener: (error: Error) => void): this;\n}\n\nexport type SpawnExternalEditorProcess = (command: string, args: readonly string[]) => ExternalEditorProcess;\n\nexport interface EditProjectFileInExternalEditorOptions {\n  root: string;\n  projectPath: string;\n  tui: TUI;\n  projectTrusted: boolean;\n  signal?: AbortSignal;\n  isCurrent?: () => boolean;\n  agentDir?: string;\n  command?: string;\n  spawnProcess?: SpawnExternalEditorProcess;\n}\n\nexport async function editProjectFileInExternalEditor(options: EditProjectFileInExternalEditorOptions): Promise<void> {\n  options.signal?.throwIfAborted();\n  const target = await resolveEditableProjectFile(options.root, options.projectPath, options.signal);\n  options.signal?.throwIfAborted();\n  const command =\n    options.command ??\n    SettingsManager.create(options.root, options.agentDir ?? getAgentDir(), {\n      projectTrusted: options.projectTrusted,\n    }).getExternalEditorCommand();\n  const [editor, ...editorArgs] = command.trim().split(/\\s+/u);\n  if (!editor) throw new Error(\"External editor command is empty\");\n  assertEditorTargetSafeForPlatform(target);\n\n  await withFileMutationQueue(target, async () => {\n    options.signal?.throwIfAborted();\n    let stopped = false;\n    try {\n      options.tui.stop();\n      stopped = true;\n      process.stdout.write(\"Launching external editor. Pi will resume when the editor exits.\\n\");\n      await runExternalEditorProcess(editor, [...editorArgs, target], options.signal, options.spawnProcess);\n      options.signal?.throwIfAborted();\n    } finally {\n      if (stopped && !options.signal?.aborted && (options.isCurrent === undefined || options.isCurrent())) {\n        options.tui.start();\n        options.tui.requestRender(true);\n      }\n    }\n  });\n}\n\nexport async function resolveEditableProjectFile(\n  root: string,\n  projectPath: string,\n  signal?: AbortSignal,\n): Promise<string> {\n  signal?.throwIfAborted();\n  if (!projectPath || isAbsolute(projectPath) || projectPath.includes(\"\\0\")) {\n    throw new Error(\"File path is outside the project\");\n  }\n  const canonicalRoot = await realpath(root);\n  signal?.throwIfAborted();\n  const candidate = resolve(canonicalRoot, projectPath);\n  if (!isInside(canonicalRoot, candidate)) throw new Error(\"File path is outside the project\");\n  const candidateInfo = await lstat(candidate);\n  signal?.throwIfAborted();\n  if (candidateInfo.isSymbolicLink()) throw new Error(`${projectPath} is a symbolic link`);\n  const canonicalFile = await realpath(candidate);\n  signal?.throwIfAborted();\n  if (!isInside(canonicalRoot, canonicalFile)) throw new Error(\"File path is outside the project\");\n  const info = await lstat(canonicalFile);\n  signal?.throwIfAborted();\n  if (!info.isFile()) throw new Error(`${projectPath} is not a regular file`);\n  return canonicalFile;\n}\n\nasync function runExternalEditorProcess(\n  command: string,\n  args: readonly string[],\n  signal: AbortSignal | undefined,\n  spawnProcess: SpawnExternalEditorProcess = defaultSpawnExternalEditorProcess,\n): Promise<void> {\n  signal?.throwIfAborted();\n  const child = spawnProcess(command, args);\n  await new Promise<void>((resolvePromise, reject) => {\n    let settled = false;\n    let aborted = signal?.aborted ?? false;\n    const finish = (error?: Error) => {\n      if (settled) return;\n      settled = true;\n      signal?.removeEventListener(\"abort\", abort);\n      if (error) reject(error);\n      else resolvePromise();\n    };\n    const abort = () => {\n      aborted = true;\n      if (!child.killed) child.kill();\n    };\n    child.once(\"error\", (error) => finish(aborted ? abortError() : error));\n    child.once(\"close\", (code) => {\n      if (aborted) {\n        finish(abortError());\n        return;\n      }\n      if (code === 0) {\n        finish();\n        return;\n      }\n      finish(new Error(`External editor exited with code ${code ?? \"unknown\"}`));\n    });\n    signal?.addEventListener(\"abort\", abort, { once: true });\n    if (signal?.aborted) abort();\n  });\n}\n\nexport function assertEditorTargetSafeForPlatform(target: string, platform: NodeJS.Platform = process.platform): void {\n  if (platform === \"win32\" && /[\\r\\n\"&|<>^()%!]/u.test(target)) {\n    throw new Error(\"File path contains characters unsafe for the Windows external-editor shell\");\n  }\n}\n\nfunction defaultSpawnExternalEditorProcess(command: string, args: readonly string[]): ChildProcess {\n  return spawn(command, [...args], {\n    stdio: \"inherit\",\n    shell: process.platform === \"win32\",\n  });\n}\n\nfunction isInside(root: string, candidate: string): boolean {\n  const result = relative(root, candidate);\n  return result === \"\" || (!result.startsWith(`..${sep}`) && result !== \"..\" && !isAbsolute(result));\n}\n\nfunction abortError(): DOMException {\n  return new DOMException(\"External editor cancelled\", \"AbortError\");\n}\n", "import type { KeybindingsManager, Theme } from \"@earendil-works/pi-coding-agent\";\nimport {\n  type Component,\n  type Focusable,\n  Input,\n  Key,\n  matchesKey,\n  type TUI,\n  truncateToWidth,\n  visibleWidth,\n} from \"@earendil-works/pi-tui\";\nimport type { ContentSearchMatch } from \"./content-search.js\";\nimport { ContentSearchSession } from \"./content-search-session.js\";\nimport {\n  safeTerminalText as escapeTerminalControls,\n  type ProjectBrowserItem,\n  ProjectFileBrowser,\n  parentProjectDirectory,\n} from \"./file-browser.js\";\nimport { renderFileBrowser } from \"./file-browser-ui.js\";\nimport {\n  createFileQuote,\n  createFileQuoteSnapshot,\n  type FileQuote,\n  type LoadedProjectTextFile,\n} from \"./file-context.js\";\nimport { renderFilePreview, renderFilePreviewHelp, type SelectedContextState } from \"./file-context-preview-ui.js\";\nimport { ProjectFileSearch } from \"./file-search.js\";\nimport type { GitBlameInfo, GitContext, GitFileContext, GitHistoryEntry, GitRevisionFile } from \"./git-context.js\";\n\nconst RESERVED_APP_ROWS = 3;\nconst EXPLORER_CHROME_ROWS = 4;\nconst HISTORY_CHROME_ROWS = 3;\nconst DIFF_CHROME_ROWS = 3;\n\nexport type FileQuoteExplorerResult =\n  | { kind: \"quote\"; quote: FileQuote }\n  | { kind: \"reference\"; path: string }\n  | { kind: \"back\" }\n  | { kind: \"close\" };\n\ninterface FileQuoteExplorerOptions {\n  tui: TUI;\n  theme: Theme;\n  keybindings: KeybindingsManager;\n  files: readonly string[];\n  cwd?: string;\n  loadFile: (path: string, signal?: AbortSignal) => Promise<LoadedProjectTextFile>;\n  editFile?: (path: string, signal?: AbortSignal) => Promise<void>;\n  gitContext?: GitContext;\n  rootNavigation?: boolean;\n  getSelectedContextState?: () => SelectedContextState;\n  validateQuote?: (quote: FileQuote) => void;\n  onAddAndContinue?: (quote: FileQuote) => void;\n  done: (result: FileQuoteExplorerResult | undefined) => void;\n}\n\n/**\n * Keeps the explorer's coupled mode transitions and request generations in one controller so every\n * cancellation path invalidates the same state instead of coordinating lifecycle across components.\n */\nexport class FileQuoteExplorer implements Component, Focusable {\n  private readonly search = new Input();\n  private readonly contentSearch: ContentSearchSession;\n  private readonly revisionInput = new Input();\n  private readonly fileSearch: ProjectFileSearch;\n  private readonly fileBrowser: ProjectFileBrowser;\n  private fileItems: ProjectBrowserItem[];\n  private currentDirectory = \"\";\n  private readonly directoryPositions = new Map<string, { index: number; offset: number }>();\n  private selectedFileIndex = 0;\n  private fileScrollOffset = 0;\n  private mode: \"files\" | \"contents\" | \"preview\" | \"preview-help\" | \"history\" | \"revision\" | \"diff\" = \"files\";\n  private previewReturnMode: \"files\" | \"contents\" = \"files\";\n  private activeContentMatch: ContentSearchMatch | undefined;\n  private loadedFile: LoadedProjectTextFile | undefined;\n  private loadedGit: GitFileContext | undefined;\n  private previewCursor = 0;\n  private previewAnchor: number | undefined;\n  private previewScrollOffset = 0;\n  private hunkIndex = -1;\n  private blame: GitBlameInfo | undefined;\n  private history: GitHistoryEntry[] = [];\n  private historyIndex = 0;\n  private loadedRevision: GitRevisionFile | undefined;\n  private diffHunkIndex = 0;\n  private diffScrollOffset = 0;\n  private detailRequest = 0;\n  private detailController: AbortController | undefined;\n  private openRequest = 0;\n  private openController: AbortController | undefined;\n  private editRequest = 0;\n  private editController: AbortController | undefined;\n  private loading = false;\n  private error: string | undefined;\n  private finished = false;\n  private disposed = false;\n  private isFocused = false;\n\n  constructor(private readonly options: FileQuoteExplorerOptions) {\n    this.fileSearch = new ProjectFileSearch(options.files);\n    this.fileBrowser = new ProjectFileBrowser(options.files);\n    this.fileItems = this.fileBrowser.list(\"\");\n    this.contentSearch = new ContentSearchSession({\n      tui: options.tui,\n      theme: options.theme,\n      keybindings: options.keybindings,\n      files: options.files,\n      cwd: options.cwd,\n      loadFile: options.loadFile,\n      onPreview: (match) => {\n        void this.openFile(match.path, {\n          returnMode: \"contents\",\n          cursorIndex: match.lineNumber - 1,\n          match,\n        });\n      },\n      onReference: (path) => this.finish({ kind: \"reference\", path }),\n      onSwitchFiles: () => this.showFileSearch(),\n      onCancel: () => this.finish(this.rootExit(\"back\")),\n    });\n  }\n\n  get focused(): boolean {\n    return this.isFocused;\n  }\n\n  set focused(value: boolean) {\n    this.isFocused = value;\n    this.search.focused = value && this.mode === \"files\";\n    this.contentSearch.focused = value && this.mode === \"contents\";\n    this.revisionInput.focused = value && this.mode === \"revision\";\n  }\n\n  render(width: number): string[] {\n    const safeWidth = Math.max(1, width);\n    if (this.mode === \"files\") return this.renderFileList(safeWidth);\n    if (this.mode === \"contents\") return this.renderContentSearch(safeWidth);\n    if (this.mode === \"history\") return this.renderHistory(safeWidth);\n    if (this.mode === \"revision\") return this.renderRevisionInput(safeWidth);\n    if (this.mode === \"diff\") return this.renderDiff(safeWidth);\n    if (this.mode === \"preview-help\") return this.renderPreviewHelp(safeWidth);\n    return this.renderPreview(safeWidth);\n  }\n\n  handleInput(data: string): void {\n    if (this.finished || this.disposed) return;\n    if (matchesKey(data, Key.ctrl(\"c\"))) {\n      this.finish(this.rootExit(\"close\"));\n      return;\n    }\n    if (this.mode === \"files\") this.handleFileInput(data);\n    else if (this.mode === \"contents\") this.handleContentInput(data);\n    else if (this.mode === \"history\") this.handleHistoryInput(data);\n    else if (this.mode === \"revision\") this.handleRevisionInput(data);\n    else if (this.mode === \"diff\") this.handleDiffInput(data);\n    else if (this.mode === \"preview-help\") this.handlePreviewHelpInput(data);\n    else this.handlePreviewInput(data);\n    if (!this.finished) this.options.tui.requestRender();\n  }\n\n  invalidate(): void {\n    this.search.invalidate();\n    this.contentSearch.invalidate();\n    this.revisionInput.invalidate();\n  }\n\n  dispose(): void {\n    if (this.disposed) return;\n    this.disposed = true;\n    this.contentSearch.dispose();\n    this.cancelOpenRequest();\n    this.cancelDetailRequest();\n    this.cancelEditRequest();\n    if (!this.finished) {\n      this.finished = true;\n      this.options.done(undefined);\n    }\n  }\n\n  private renderFileList(width: number): string[] {\n    const availableRows = Math.max(1, this.options.tui.terminal.rows - RESERVED_APP_ROWS);\n    const listHeight = Math.max(1, availableRows - EXPLORER_CHROME_ROWS);\n    this.keepFileVisible(listHeight);\n    const project = this.options.gitContext?.project;\n    const repositoryLabel = project\n      ? ` \u00B7 ${escapeTerminalControls(project.branch)}@${project.head.slice(0, 12)}${project.dirty ? \" \u00B7 dirty\" : \"\"}`\n      : \"\";\n    const queryLabel = this.options.theme.fg(\"muted\", \"Search: \");\n    const queryWidth = Math.max(1, width - visibleWidth(queryLabel));\n    const searchLine = `${queryLabel}${this.search.render(queryWidth)[0] ?? \"\"}`;\n    return fitRows(\n      renderFileBrowser({\n        theme: this.options.theme,\n        keybindings: this.options.keybindings,\n        width,\n        height: listHeight,\n        items: this.fileItems,\n        selectedIndex: this.selectedFileIndex,\n        scrollOffset: this.fileScrollOffset,\n        currentDirectory: this.currentDirectory,\n        searchLine,\n        searchActive: this.isFileSearchActive(),\n        repositoryLabel,\n        statuses: this.options.gitContext?.statuses,\n        loading: this.loading,\n        error: this.error,\n      }),\n      availableRows,\n    );\n  }\n\n  private renderContentSearch(width: number): string[] {\n    const availableRows = Math.max(1, this.options.tui.terminal.rows - RESERVED_APP_ROWS);\n    return this.contentSearch.render(width, availableRows, this.loading, this.error);\n  }\n\n  private renderPreview(width: number): string[] {\n    const availableRows = Math.max(1, this.options.tui.terminal.rows - RESERVED_APP_ROWS);\n    if (!this.loadedFile) return [this.options.theme.fg(\"warning\", \"Loading preview\u2026\")];\n    return renderFilePreview({\n      theme: this.options.theme,\n      keybindings: this.options.keybindings,\n      width,\n      availableRows,\n      file: this.loadedFile,\n      fileGit: this.loadedGit,\n      project: this.options.gitContext?.project,\n      revision: this.loadedRevision,\n      contentMatch: this.activeContentMatch,\n      blame: this.blame,\n      cursor: this.previewCursor,\n      anchor: this.previewAnchor,\n      scrollOffset: this.previewScrollOffset,\n      error: this.error,\n      selectedContext: this.options.getSelectedContextState?.(),\n      canContinue: this.options.onAddAndContinue !== undefined,\n      canEdit: this.options.editFile !== undefined && this.loadedRevision === undefined,\n    });\n  }\n\n  private renderPreviewHelp(width: number): string[] {\n    const availableRows = Math.max(1, this.options.tui.terminal.rows - RESERVED_APP_ROWS);\n    return renderFilePreviewHelp(\n      this.options.theme,\n      this.options.keybindings,\n      width,\n      availableRows,\n      this.options.editFile !== undefined && this.loadedRevision === undefined,\n    );\n  }\n\n  private renderRevisionInput(width: number): string[] {\n    const availableRows = Math.max(1, this.options.tui.terminal.rows - RESERVED_APP_ROWS);\n    const title = this.options.theme.fg(\n      \"accent\",\n      this.options.theme.bold(`Open Git revision \u00B7 ${escapeTerminalControls(this.loadedFile?.path ?? \"\")}`),\n    );\n    const label = this.options.theme.fg(\"muted\", \"Revision: \");\n    const inputWidth = Math.max(1, width - visibleWidth(label));\n    const input = `${label}${this.revisionInput.render(inputWidth)[0] ?? \"\"}`;\n    const state = this.error\n      ? this.options.theme.fg(\"error\", escapeTerminalControls(this.error))\n      : this.loading\n        ? this.options.theme.fg(\"warning\", \"Loading revision\u2026\")\n        : this.options.theme.fg(\"muted\", \"Enter open commit/branch/tag \u00B7 Esc preview\");\n    return fitRows(\n      [truncateToWidth(title, width, \"\"), truncateToWidth(input, width, \"\"), truncateToWidth(state, width, \"\")],\n      availableRows,\n    );\n  }\n\n  private renderDiff(width: number): string[] {\n    const availableRows = Math.max(1, this.options.tui.terminal.rows - RESERVED_APP_ROWS);\n    const contentHeight = Math.max(1, availableRows - DIFF_CHROME_ROWS);\n    const hunk = this.loadedGit?.hunks[this.diffHunkIndex];\n    const path = escapeTerminalControls(this.loadedFile?.path ?? \"\");\n    const title = this.options.theme.fg(\"accent\", this.options.theme.bold(`Git diff \u00B7 ${path} \u00B7 HEAD \u2192 worktree`));\n    const hunkLines = hunk?.lines ?? [\"No changed hunks\"];\n    const maxScroll = Math.max(0, hunkLines.length - contentHeight);\n    this.diffScrollOffset = Math.min(this.diffScrollOffset, maxScroll);\n    const lines = hunkLines\n      .slice(this.diffScrollOffset, this.diffScrollOffset + contentHeight)\n      .map((line) =>\n        truncateToWidth(\n          line.startsWith(\"+\")\n            ? this.options.theme.fg(\"success\", escapeTerminalControls(line))\n            : line.startsWith(\"-\")\n              ? this.options.theme.fg(\"error\", escapeTerminalControls(line))\n              : escapeTerminalControls(line),\n          width,\n          \"\",\n        ),\n      );\n    const text = hunk?.lines.join(\"\\n\") ?? \"\";\n    const tokens = Math.max(1, Math.ceil(Buffer.byteLength(text, \"utf8\") / 4));\n    const footer = this.error\n      ? this.options.theme.fg(\"error\", escapeTerminalControls(this.error))\n      : `~${tokens} tokens \u00B7 Enter attach diff \u00B7 Hunk ${hunk ? this.diffHunkIndex + 1 : 0}/${this.loadedGit?.hunks.length ?? 0} \u00B7 rows ${hunkLines.length === 0 ? 0 : this.diffScrollOffset + 1}-${Math.min(hunkLines.length, this.diffScrollOffset + contentHeight)}/${hunkLines.length} \u00B7 \u2191\u2193 scroll \u00B7 [] navigate \u00B7 Esc preview`;\n    return fitRows(\n      [truncateToWidth(title, width, \"\"), ...lines, truncateToWidth(this.options.theme.fg(\"muted\", footer), width, \"\")],\n      availableRows,\n    );\n  }\n\n  private renderHistory(width: number): string[] {\n    const availableRows = Math.max(1, this.options.tui.terminal.rows - RESERVED_APP_ROWS);\n    const listHeight = Math.max(1, availableRows - HISTORY_CHROME_ROWS);\n    const loadedFile = this.loadedFile;\n    const title = this.options.theme.fg(\n      \"accent\",\n      this.options.theme.bold(`File history \u00B7 ${escapeTerminalControls(loadedFile?.path ?? \"\")}`),\n    );\n    const start = Math.max(0, this.historyIndex - listHeight + 1);\n    const entries = this.history.slice(start, start + listHeight).map((entry, visibleIndex) => {\n      const index = start + visibleIndex;\n      const prefix = index === this.historyIndex ? \"> \" : \"  \";\n      const date = formatHistoryDate(entry.authorTime);\n      const line = `${prefix}${entry.commit.slice(0, 12)} \u00B7 ${date} \u00B7 ${escapeTerminalControls(entry.author)} \u00B7 ${escapeTerminalControls(entry.summary)}`;\n      return truncateToWidth(\n        index === this.historyIndex ? this.options.theme.bg(\"selectedBg\", this.options.theme.fg(\"text\", line)) : line,\n        width,\n        \"\",\n      );\n    });\n    if (entries.length === 0) {\n      entries.push(truncateToWidth(this.options.theme.fg(\"muted\", \"  No file history\"), width, \"\"));\n    }\n    const footer = this.error ? escapeTerminalControls(this.error) : \"\u2191\u2193 navigate \u00B7 Enter open revision \u00B7 Esc preview\";\n    return fitRows(\n      [\n        truncateToWidth(title, width, \"\"),\n        ...entries,\n        truncateToWidth(this.options.theme.fg(\"muted\", footer), width, \"\"),\n      ],\n      availableRows,\n    );\n  }\n\n  private handleFileInput(data: string): void {\n    if (this.options.keybindings.matches(data, \"tui.select.cancel\")) {\n      this.cancelFileList();\n      return;\n    }\n    if (matchesKey(data, Key.ctrl(\"f\"))) {\n      this.showContentSearch();\n      return;\n    }\n    if (matchesKey(data, Key.escape)) {\n      this.cancelFileList();\n      return;\n    }\n    if (this.loading) return;\n    if (this.options.keybindings.matches(data, \"tui.select.up\")) {\n      this.selectedFileIndex = Math.max(0, this.selectedFileIndex - 1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.down\")) {\n      this.selectedFileIndex = Math.min(Math.max(0, this.fileItems.length - 1), this.selectedFileIndex + 1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.pageUp\")) {\n      this.selectedFileIndex = Math.max(0, this.selectedFileIndex - 10);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.pageDown\")) {\n      this.selectedFileIndex = Math.min(Math.max(0, this.fileItems.length - 1), this.selectedFileIndex + 10);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.confirm\")) {\n      this.openSelectedFileItem();\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.input.tab\")) {\n      const item = this.fileItems[this.selectedFileIndex];\n      if (item?.kind === \"file\") this.finish({ kind: \"reference\", path: item.path });\n      return;\n    }\n    if (\n      !this.isFileSearchActive() &&\n      this.currentDirectory &&\n      (matchesKey(data, Key.left) || matchesKey(data, Key.backspace))\n    ) {\n      this.showParentDirectory();\n      return;\n    }\n    if (!this.isFileSearchActive() && matchesKey(data, Key.right)) {\n      const item = this.fileItems[this.selectedFileIndex];\n      if (item?.kind === \"directory\") this.showDirectory(item.path);\n      return;\n    }\n\n    const previousQuery = this.search.getValue();\n    this.search.handleInput(data);\n    const query = this.search.getValue();\n    if (query !== previousQuery) {\n      this.refreshFileItems(query);\n      this.selectedFileIndex = 0;\n      this.fileScrollOffset = 0;\n      this.error = undefined;\n    }\n  }\n\n  private handleContentInput(data: string): void {\n    this.cancelOpenRequest();\n    this.error = undefined;\n    this.contentSearch.handleInput(data);\n  }\n\n  private handlePreviewInput(data: string): void {\n    const loadedFile = this.loadedFile;\n    if (!loadedFile) return;\n    const lines = loadedFile.lines;\n    if (this.options.keybindings.matches(data, \"app.editor.external\")) {\n      if (this.loadedRevision) {\n        this.error = \"Historical revisions are read-only; return to the worktree preview to edit\";\n      } else if (this.options.editFile && !this.loading) {\n        void this.editCurrentFile();\n      } else if (!this.options.editFile) {\n        this.error = \"External editing is unavailable\";\n      }\n      return;\n    }\n    if (matchesKey(data, Key.escape)) {\n      this.returnToOrigin();\n      return;\n    }\n    if (data === \"?\") {\n      this.cancelDetailRequest();\n      this.mode = \"preview-help\";\n      this.search.focused = false;\n      this.contentSearch.focused = false;\n      return;\n    }\n    if (data === \"a\" && this.options.onAddAndContinue) {\n      try {\n        const quote = this.createSelectedQuote();\n        this.options.onAddAndContinue(quote);\n        this.returnToOrigin();\n      } catch (error: unknown) {\n        this.error = formatError(error);\n      }\n      return;\n    }\n    if (data === \" \") {\n      this.previewAnchor = this.previewAnchor === undefined ? this.previewCursor : undefined;\n      this.error = undefined;\n      return;\n    }\n    if (data === \"b\") {\n      void this.loadBlame();\n      return;\n    }\n    if (data === \"h\") {\n      void this.loadHistory();\n      return;\n    }\n    if (data === \"r\") {\n      this.mode = \"revision\";\n      this.revisionInput.setValue(\"\");\n      this.revisionInput.focused = this.isFocused;\n      this.error = undefined;\n      return;\n    }\n    if (data === \"d\") {\n      if (this.loadedRevision) {\n        this.error = \"Diff context is available from the worktree preview\";\n        return;\n      }\n      if ((this.loadedGit?.hunks.length ?? 0) === 0) {\n        this.error = \"No changed hunks for this file\";\n        return;\n      }\n      this.diffHunkIndex = Math.max(0, this.hunkIndex);\n      this.diffScrollOffset = 0;\n      this.mode = \"diff\";\n      this.error = undefined;\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.up\")) {\n      this.movePreviewCursor(Math.max(0, this.previewCursor - 1));\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.down\")) {\n      this.movePreviewCursor(Math.min(Math.max(0, lines.length - 1), this.previewCursor + 1));\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.pageUp\")) {\n      this.movePreviewCursor(Math.max(0, this.previewCursor - 10));\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.pageDown\")) {\n      this.movePreviewCursor(Math.min(Math.max(0, lines.length - 1), this.previewCursor + 10));\n      return;\n    }\n    if (data === \"]\" || data === \"[\") {\n      this.navigateHunk(data === \"]\" ? 1 : -1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.confirm\")) {\n      try {\n        const quote = this.createSelectedQuote();\n        this.options.validateQuote?.(quote);\n        this.finish({ kind: \"quote\", quote });\n      } catch (error: unknown) {\n        this.error = formatError(error);\n      }\n    }\n  }\n\n  private handlePreviewHelpInput(data: string): void {\n    if (matchesKey(data, Key.escape)) this.mode = \"preview\";\n  }\n\n  private handleHistoryInput(data: string): void {\n    if (matchesKey(data, Key.escape)) {\n      this.cancelDetailRequest();\n      this.mode = \"preview\";\n      this.error = undefined;\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.up\")) {\n      this.historyIndex = Math.max(0, this.historyIndex - 1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.down\")) {\n      this.historyIndex = Math.min(Math.max(0, this.history.length - 1), this.historyIndex + 1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.confirm\")) {\n      const entry = this.history[this.historyIndex];\n      if (entry) void this.loadRevision(entry.commit, entry.path);\n    }\n  }\n\n  private handleRevisionInput(data: string): void {\n    if (matchesKey(data, Key.escape)) {\n      this.cancelDetailRequest();\n      this.mode = \"preview\";\n      this.revisionInput.focused = false;\n      this.error = undefined;\n      return;\n    }\n    if (this.loading) return;\n    if (this.options.keybindings.matches(data, \"tui.select.confirm\")) {\n      void this.loadRevision(this.revisionInput.getValue());\n      return;\n    }\n    this.revisionInput.handleInput(data);\n  }\n\n  private handleDiffInput(data: string): void {\n    if (matchesKey(data, Key.escape)) {\n      this.mode = \"preview\";\n      this.error = undefined;\n      return;\n    }\n    const hunks = this.loadedGit?.hunks ?? [];\n    const hunkLines = hunks[this.diffHunkIndex]?.lines ?? [];\n    if (this.options.keybindings.matches(data, \"tui.select.up\")) {\n      this.diffScrollOffset = Math.max(0, this.diffScrollOffset - 1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.down\")) {\n      this.diffScrollOffset = Math.min(Math.max(0, hunkLines.length - 1), this.diffScrollOffset + 1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.pageUp\")) {\n      this.diffScrollOffset = Math.max(0, this.diffScrollOffset - 10);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.pageDown\")) {\n      this.diffScrollOffset = Math.min(Math.max(0, hunkLines.length - 1), this.diffScrollOffset + 10);\n      return;\n    }\n    if (data === \"]\" || data === \"[\") {\n      if (hunks.length > 0) {\n        const direction = data === \"]\" ? 1 : -1;\n        this.diffHunkIndex = (this.diffHunkIndex + direction + hunks.length) % hunks.length;\n        this.diffScrollOffset = 0;\n      }\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.confirm\")) {\n      const hunk = hunks[this.diffHunkIndex];\n      const loadedFile = this.loadedFile;\n      const project = this.options.gitContext?.project;\n      if (!hunk || !loadedFile || !project) return;\n      try {\n        const startLine = Math.max(1, hunk.newStart);\n        const endLine = Math.max(startLine, hunk.newStart + hunk.newCount - 1);\n        const quote = createFileQuoteSnapshot(loadedFile.path, startLine, endLine, hunk.lines.join(\"\\n\"), {\n          head: project.head,\n          branch: project.branch,\n          status: this.loadedGit?.status?.label ?? \"modified\",\n          blob: this.loadedGit?.blob,\n          source: \"git_diff\",\n          base: \"HEAD\",\n        });\n        this.options.validateQuote?.(quote);\n        this.finish({ kind: \"quote\", quote });\n      } catch (error: unknown) {\n        this.error = formatError(error);\n      }\n    }\n  }\n\n  private async editCurrentFile(): Promise<void> {\n    const path = this.loadedFile?.path;\n    const editFile = this.options.editFile;\n    if (!path || !editFile || this.loadedRevision) return;\n    this.cancelOpenRequest();\n    this.cancelDetailRequest();\n    this.cancelEditRequest();\n    const request = this.editRequest;\n    const controller = new AbortController();\n    this.editController = controller;\n    this.loading = true;\n    this.error = undefined;\n    this.options.tui.requestRender();\n    try {\n      await editFile(path, controller.signal);\n      if (!this.isCurrentEditRequest(request, controller, path)) return;\n      const gitContext = this.options.gitContext;\n      const [loadedFile, loadedGit] = await Promise.all([\n        this.options.loadFile(path, controller.signal),\n        gitContext\n          ? (gitContext.refreshFileContext?.(path, controller.signal) ??\n            gitContext.getFileContext(path, controller.signal))\n          : undefined,\n      ]);\n      if (!this.isCurrentEditRequest(request, controller, path)) return;\n      const maximumIndex = Math.max(0, loadedFile.lines.length - 1);\n      this.loadedFile = loadedFile;\n      this.loadedGit = loadedGit;\n      this.previewCursor = Math.min(this.previewCursor, maximumIndex);\n      if (this.previewAnchor !== undefined) {\n        this.previewAnchor = Math.min(this.previewAnchor, maximumIndex);\n      }\n      this.previewScrollOffset = Math.min(this.previewScrollOffset, maximumIndex);\n      this.activeContentMatch = undefined;\n      this.hunkIndex = -1;\n      this.blame = undefined;\n      this.history = [];\n      this.error = undefined;\n    } catch (error: unknown) {\n      if (this.isCurrentEditRequest(request, controller, path) && !isAbortError(error)) {\n        this.error = formatError(error);\n      }\n    } finally {\n      if (request === this.editRequest && this.editController === controller) {\n        this.loading = false;\n        this.editController = undefined;\n      }\n      if (!this.finished && !this.disposed) this.options.tui.requestRender(true);\n    }\n  }\n\n  private async loadRevision(revision: string, historicalPath?: string): Promise<void> {\n    const path = this.loadedFile?.path;\n    const gitContext = this.options.gitContext;\n    if (!path || !gitContext) {\n      this.error = \"Git revision browsing is unavailable\";\n      return;\n    }\n    const { request, signal } = this.beginDetailRequest();\n    this.error = undefined;\n    this.options.tui.requestRender();\n    try {\n      const loadedRevision = await gitContext.loadRevision(path, revision, historicalPath, signal);\n      if (this.finished || request !== this.detailRequest) return;\n      this.loadedRevision = loadedRevision;\n      this.loadedFile = { path: loadedRevision.path, lines: loadedRevision.lines };\n      this.activeContentMatch = undefined;\n      this.previewCursor = 0;\n      this.previewAnchor = undefined;\n      this.previewScrollOffset = 0;\n      this.blame = undefined;\n      this.mode = \"preview\";\n      this.revisionInput.focused = false;\n    } catch (error: unknown) {\n      if (request === this.detailRequest && !isAbortError(error)) this.error = formatError(error);\n    } finally {\n      this.finishDetailRequest(request);\n    }\n  }\n\n  private async loadBlame(): Promise<void> {\n    const path = this.loadedFile?.path;\n    const gitContext = this.options.gitContext;\n    if (!path || !gitContext) {\n      this.error = \"Git blame is unavailable\";\n      return;\n    }\n    const { request, signal } = this.beginDetailRequest();\n    const requestedLine = this.previewCursor + 1;\n    this.error = undefined;\n    this.options.tui.requestRender();\n    try {\n      const blame = await gitContext.getBlame(path, requestedLine, this.loadedRevision?.commit, signal);\n      if (\n        this.finished ||\n        request !== this.detailRequest ||\n        this.mode !== \"preview\" ||\n        requestedLine !== this.previewCursor + 1\n      ) {\n        return;\n      }\n      this.blame = blame;\n      if (!blame) this.error = \"No blame information for this line\";\n    } catch (error: unknown) {\n      if (request === this.detailRequest && !isAbortError(error)) this.error = formatError(error);\n    } finally {\n      this.finishDetailRequest(request);\n    }\n  }\n\n  private async loadHistory(): Promise<void> {\n    const path = this.loadedFile?.path;\n    const gitContext = this.options.gitContext;\n    if (!path || !gitContext) {\n      this.error = \"Git history is unavailable\";\n      return;\n    }\n    const { request, signal } = this.beginDetailRequest();\n    this.error = undefined;\n    this.options.tui.requestRender();\n    try {\n      const history = await gitContext.getHistory(path, signal);\n      if (this.finished || request !== this.detailRequest || this.mode !== \"preview\") return;\n      this.history = history;\n      this.historyIndex = 0;\n      this.mode = \"history\";\n    } catch (error: unknown) {\n      if (request === this.detailRequest && !isAbortError(error)) this.error = formatError(error);\n    } finally {\n      this.finishDetailRequest(request);\n    }\n  }\n\n  private async openFile(\n    path: string,\n    options: {\n      returnMode?: \"files\" | \"contents\";\n      cursorIndex?: number;\n      match?: ContentSearchMatch;\n    } = {},\n  ): Promise<void> {\n    this.cancelOpenRequest();\n    const request = this.openRequest;\n    const controller = new AbortController();\n    this.openController = controller;\n    this.loading = true;\n    this.error = undefined;\n    this.options.tui.requestRender();\n    try {\n      const [loadedFile, loadedGit] = await Promise.all([\n        this.options.loadFile(path, controller.signal),\n        this.options.gitContext?.getFileContext(path, controller.signal),\n      ]);\n      if (!this.isCurrentOpenRequest(request, controller)) return;\n      this.loadedFile = loadedFile;\n      this.loadedGit = loadedGit;\n      this.loadedRevision = undefined;\n      this.mode = \"preview\";\n      this.previewReturnMode = options.returnMode ?? \"files\";\n      this.activeContentMatch = options.match;\n      this.previewCursor = Math.max(0, Math.min(Math.max(0, loadedFile.lines.length - 1), options.cursorIndex ?? 0));\n      this.previewAnchor = undefined;\n      this.previewScrollOffset = Math.max(0, this.previewCursor - 1);\n      this.hunkIndex = -1;\n      this.blame = undefined;\n      this.history = [];\n      this.detailRequest += 1;\n      this.error = undefined;\n      this.search.focused = false;\n      this.contentSearch.focused = false;\n    } catch (error: unknown) {\n      if (this.isCurrentOpenRequest(request, controller) && !isAbortError(error)) {\n        this.error = formatError(error);\n      }\n    } finally {\n      if (request === this.openRequest) {\n        this.loading = false;\n        this.openController = undefined;\n      }\n      if (!this.finished && !this.disposed) this.options.tui.requestRender();\n    }\n  }\n\n  private navigateHunk(direction: 1 | -1): void {\n    const hunks = this.loadedGit?.hunks ?? [];\n    const lineCount = this.loadedFile?.lines.length ?? 0;\n    if (hunks.length === 0 || lineCount === 0) {\n      this.error = \"No changed hunks for this file\";\n      return;\n    }\n    this.hunkIndex =\n      this.hunkIndex < 0\n        ? direction > 0\n          ? 0\n          : hunks.length - 1\n        : (this.hunkIndex + direction + hunks.length) % hunks.length;\n    const hunk = hunks[this.hunkIndex];\n    const selectedLines = hunk.changedLines.length > 0 ? hunk.changedLines : [hunk.newStart];\n    const start = Math.max(0, Math.min(...selectedLines) - 1);\n    const end = Math.max(start, Math.min(lineCount - 1, Math.max(...selectedLines) - 1));\n    this.previewAnchor = start;\n    this.movePreviewCursor(end);\n    this.error = undefined;\n  }\n\n  private showContentSearch(): void {\n    this.cancelOpenRequest();\n    this.mode = \"contents\";\n    this.search.focused = false;\n    this.contentSearch.activate();\n    this.contentSearch.focused = this.isFocused;\n    this.error = undefined;\n  }\n\n  private showFileSearch(): void {\n    this.contentSearch.deactivate();\n    this.cancelOpenRequest();\n    this.mode = \"files\";\n    this.search.focused = this.isFocused;\n    this.error = undefined;\n  }\n\n  private openSelectedFileItem(): void {\n    const item = this.fileItems[this.selectedFileIndex];\n    if (item?.kind === \"directory\") {\n      this.showDirectory(item.path);\n      return;\n    }\n    if (item?.kind === \"file\") void this.openFile(item.path);\n  }\n\n  private showDirectory(directory: string): void {\n    this.directoryPositions.set(this.currentDirectory, {\n      index: this.selectedFileIndex,\n      offset: this.fileScrollOffset,\n    });\n    this.currentDirectory = directory;\n    this.refreshFileItems(\"\");\n    const position = this.directoryPositions.get(directory);\n    this.selectedFileIndex = Math.min(position?.index ?? 0, Math.max(0, this.fileItems.length - 1));\n    this.fileScrollOffset = Math.min(position?.offset ?? 0, this.selectedFileIndex);\n    this.error = undefined;\n  }\n\n  private showParentDirectory(): void {\n    this.cancelOpenRequest();\n    this.currentDirectory = parentProjectDirectory(this.currentDirectory);\n    this.refreshFileItems(\"\");\n    const position = this.directoryPositions.get(this.currentDirectory);\n    this.selectedFileIndex = Math.min(position?.index ?? 0, Math.max(0, this.fileItems.length - 1));\n    this.fileScrollOffset = Math.min(position?.offset ?? 0, this.selectedFileIndex);\n    this.error = undefined;\n  }\n\n  private refreshFileItems(query: string): void {\n    this.fileItems = this.isFileSearchActive(query)\n      ? this.fileBrowser.searchResults(this.fileSearch.search(query))\n      : this.fileBrowser.list(this.currentDirectory);\n  }\n\n  private isFileSearchActive(query = this.search.getValue()): boolean {\n    return escapeTerminalControls(query).trim().length > 0;\n  }\n\n  private cancelFileList(): void {\n    if (this.currentDirectory && !this.isFileSearchActive()) {\n      this.showParentDirectory();\n      return;\n    }\n    this.finish(this.rootExit(\"back\"));\n  }\n\n  private cancelOpenRequest(): void {\n    this.openRequest += 1;\n    this.openController?.abort();\n    this.openController = undefined;\n    this.loading = false;\n  }\n\n  private isCurrentOpenRequest(request: number, controller: AbortController): boolean {\n    return (\n      !this.finished &&\n      !this.disposed &&\n      request === this.openRequest &&\n      this.openController === controller &&\n      !controller.signal.aborted\n    );\n  }\n\n  private isCurrentEditRequest(request: number, controller: AbortController, path: string): boolean {\n    return (\n      !this.finished &&\n      !this.disposed &&\n      this.mode === \"preview\" &&\n      this.loadedRevision === undefined &&\n      this.loadedFile?.path === path &&\n      request === this.editRequest &&\n      this.editController === controller &&\n      !controller.signal.aborted\n    );\n  }\n\n  private beginDetailRequest(): { request: number; signal: AbortSignal } {\n    this.cancelDetailRequest();\n    const request = this.detailRequest;\n    const controller = new AbortController();\n    this.detailController = controller;\n    this.loading = true;\n    return { request, signal: controller.signal };\n  }\n\n  private finishDetailRequest(request: number): void {\n    if (request === this.detailRequest) {\n      this.loading = false;\n      this.detailController = undefined;\n    }\n    if (!this.finished && !this.disposed) this.options.tui.requestRender();\n  }\n\n  private cancelDetailRequest(): void {\n    this.detailRequest += 1;\n    this.detailController?.abort();\n    this.detailController = undefined;\n    this.loading = false;\n  }\n\n  private cancelEditRequest(): void {\n    this.editRequest += 1;\n    this.editController?.abort();\n    this.editController = undefined;\n    this.loading = false;\n  }\n\n  private movePreviewCursor(next: number): void {\n    if (next === this.previewCursor) return;\n    this.cancelDetailRequest();\n    this.previewCursor = next;\n    this.blame = undefined;\n    this.error = undefined;\n  }\n\n  private createSelectedQuote(): FileQuote {\n    const loadedFile = this.loadedFile;\n    if (!loadedFile) throw new Error(\"No file is open\");\n    const anchor = this.previewAnchor ?? this.previewCursor;\n    const project = this.options.gitContext?.project;\n    const revision = this.loadedRevision;\n    return createFileQuote(\n      loadedFile.path,\n      loadedFile.lines,\n      anchor,\n      this.previewCursor,\n      project\n        ? {\n            head: project.head,\n            branch: project.branch,\n            status: revision ? \"historical\" : (this.loadedGit?.status?.label ?? \"clean\"),\n            revision: revision?.revision,\n            blob: revision?.blob ?? this.loadedGit?.blob,\n            source: revision ? \"revision\" : \"worktree\",\n            base: revision ? undefined : \"HEAD\",\n          }\n        : undefined,\n    );\n  }\n\n  private returnToOrigin(): void {\n    this.cancelDetailRequest();\n    this.cancelOpenRequest();\n    this.cancelEditRequest();\n    this.mode = this.previewReturnMode;\n    this.loadedFile = undefined;\n    this.loadedGit = undefined;\n    this.loadedRevision = undefined;\n    this.previewAnchor = undefined;\n    this.blame = undefined;\n    this.error = undefined;\n    this.search.focused = this.isFocused && this.mode === \"files\";\n    this.contentSearch.focused = this.isFocused && this.mode === \"contents\";\n  }\n\n  private finish(result: FileQuoteExplorerResult | undefined): void {\n    this.finished = true;\n    this.contentSearch.dispose();\n    this.cancelOpenRequest();\n    this.cancelDetailRequest();\n    this.cancelEditRequest();\n    this.options.done(result);\n  }\n\n  private rootExit(kind: \"back\" | \"close\"): FileQuoteExplorerResult | undefined {\n    return this.options.rootNavigation ? { kind } : undefined;\n  }\n\n  private keepFileVisible(height: number): void {\n    if (this.selectedFileIndex < this.fileScrollOffset) this.fileScrollOffset = this.selectedFileIndex;\n    if (this.selectedFileIndex >= this.fileScrollOffset + height) {\n      this.fileScrollOffset = this.selectedFileIndex - height + 1;\n    }\n  }\n}\n\nfunction fitRows(lines: string[], height: number): string[] {\n  if (lines.length <= height) return lines;\n  if (height <= 1) return lines.slice(0, 1);\n  return [...lines.slice(0, height - 1), lines.at(-1) ?? \"\"];\n}\n\nfunction formatHistoryDate(authorTime: number): string {\n  const date = new Date(authorTime * 1_000);\n  return Number.isFinite(date.getTime()) ? date.toISOString().slice(0, 10) : \"unknown-date\";\n}\n\nfunction isAbortError(error: unknown): boolean {\n  return error instanceof Error && error.name === \"AbortError\";\n}\n\nfunction formatError(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n", "import type { KeybindingsManager, Theme } from \"@earendil-works/pi-coding-agent\";\nimport { Input, Key, matchesKey, type TUI, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { type ContentSearchMatch, searchProjectContents } from \"./content-search.js\";\nimport { contentSearchCardCapacity, renderContentSearchScreen } from \"./content-search-ui.js\";\nimport type { LoadedProjectTextFile } from \"./file-context.js\";\n\ninterface ContentSearchSessionOptions {\n  tui: TUI;\n  theme: Theme;\n  keybindings: KeybindingsManager;\n  files: readonly string[];\n  cwd?: string;\n  loadFile: (path: string, signal?: AbortSignal) => Promise<LoadedProjectTextFile>;\n  onPreview: (match: ContentSearchMatch) => void;\n  onReference: (path: string) => void;\n  onSwitchFiles: () => void;\n  onCancel: () => void;\n}\n\nexport class ContentSearchSession {\n  private readonly input = new Input();\n  private matches: ContentSearchMatch[] = [];\n  private selectedIndex = 0;\n  private scrollOffset = 0;\n  private caseSensitive = false;\n  private fuzzy = false;\n  private truncated = false;\n  private skippedFiles = 0;\n  private loading = false;\n  private request = 0;\n  private controller: AbortController | undefined;\n  private error: string | undefined;\n  private disposed = false;\n\n  constructor(private readonly options: ContentSearchSessionOptions) {}\n\n  set focused(value: boolean) {\n    this.input.focused = value;\n  }\n\n  activate(): void {\n    this.disposed = false;\n    if (this.input.getValue().trim()) this.startSearch();\n  }\n\n  deactivate(): void {\n    this.focused = false;\n    this.cancelSearch();\n  }\n\n  render(width: number, availableRows: number, opening: boolean, externalError?: string): string[] {\n    const capacity = contentSearchCardCapacity(availableRows);\n    this.keepSelectionVisible(capacity);\n    const queryLabel = this.options.theme.fg(\"muted\", \"Search: \");\n    const queryWidth = Math.max(1, width - visibleWidth(queryLabel));\n    const queryLine = `${queryLabel}${this.input.render(queryWidth)[0] ?? \"\"}`;\n    return renderContentSearchScreen({\n      theme: this.options.theme,\n      width,\n      availableRows,\n      queryLine,\n      query: this.input.getValue(),\n      cwd: this.options.cwd,\n      matches: this.matches,\n      selectedIndex: this.selectedIndex,\n      scrollOffset: this.scrollOffset,\n      caseSensitive: this.caseSensitive,\n      fuzzy: this.fuzzy,\n      loading: this.loading,\n      opening,\n      truncated: this.truncated,\n      skippedFiles: this.skippedFiles,\n      error: externalError ?? this.error,\n    });\n  }\n\n  handleInput(data: string): void {\n    if (this.disposed) return;\n    if (matchesKey(data, Key.ctrl(\"f\"))) {\n      this.options.onSwitchFiles();\n      return;\n    }\n    if (matchesKey(data, Key.escape)) {\n      this.options.onCancel();\n      return;\n    }\n    if (matchesKey(data, Key.alt(\"c\"))) {\n      this.caseSensitive = !this.caseSensitive;\n      this.startSearch();\n      return;\n    }\n    if (matchesKey(data, Key.alt(\"f\"))) {\n      this.fuzzy = !this.fuzzy;\n      this.startSearch();\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.up\")) {\n      this.selectedIndex = Math.max(0, this.selectedIndex - 1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.down\")) {\n      this.selectedIndex = Math.min(Math.max(0, this.matches.length - 1), this.selectedIndex + 1);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.pageUp\")) {\n      this.selectedIndex = Math.max(0, this.selectedIndex - 10);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.pageDown\")) {\n      this.selectedIndex = Math.min(Math.max(0, this.matches.length - 1), this.selectedIndex + 10);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.select.confirm\")) {\n      const match = this.matches[this.selectedIndex];\n      if (match) this.options.onPreview(match);\n      return;\n    }\n    if (this.options.keybindings.matches(data, \"tui.input.tab\")) {\n      const match = this.matches[this.selectedIndex];\n      if (match) this.options.onReference(match.path);\n      return;\n    }\n\n    const previousQuery = this.input.getValue();\n    this.input.handleInput(data);\n    if (this.input.getValue() !== previousQuery) this.startSearch();\n  }\n\n  invalidate(): void {\n    this.input.invalidate();\n  }\n\n  dispose(): void {\n    if (this.disposed) return;\n    this.disposed = true;\n    this.cancelSearch();\n  }\n\n  private startSearch(): void {\n    this.cancelSearch();\n    const query = this.input.getValue();\n    this.matches = [];\n    this.selectedIndex = 0;\n    this.scrollOffset = 0;\n    this.truncated = false;\n    this.skippedFiles = 0;\n    this.error = undefined;\n    if (!query.trim()) return;\n\n    const request = this.request;\n    const controller = new AbortController();\n    this.controller = controller;\n    this.loading = true;\n    void searchProjectContents(this.options.files, this.options.loadFile, query, {\n      caseSensitive: this.caseSensitive,\n      fuzzy: this.fuzzy,\n      signal: controller.signal,\n    })\n      .then((result) => {\n        if (!this.isCurrent(request, controller)) return;\n        this.matches = result.matches;\n        this.truncated = result.truncated;\n        this.skippedFiles = result.skippedFiles;\n      })\n      .catch((error: unknown) => {\n        if (this.isCurrent(request, controller) && !isAbortError(error)) {\n          this.error = formatError(error);\n        }\n      })\n      .finally(() => {\n        if (request === this.request) {\n          this.loading = false;\n          this.controller = undefined;\n        }\n        if (!this.disposed) this.options.tui.requestRender();\n      });\n  }\n\n  private cancelSearch(): void {\n    this.request += 1;\n    this.controller?.abort();\n    this.controller = undefined;\n    this.loading = false;\n  }\n\n  private isCurrent(request: number, controller: AbortController): boolean {\n    return !this.disposed && request === this.request && this.controller === controller && !controller.signal.aborted;\n  }\n\n  private keepSelectionVisible(capacity: number): void {\n    if (this.selectedIndex < this.scrollOffset) this.scrollOffset = this.selectedIndex;\n    if (this.selectedIndex >= this.scrollOffset + capacity) {\n      this.scrollOffset = this.selectedIndex - capacity + 1;\n    }\n  }\n}\n\nfunction isAbortError(error: unknown): boolean {\n  return error instanceof Error && error.name === \"AbortError\";\n}\n\nfunction formatError(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n", "const MAX_CONTENT_QUERY_LENGTH = 256;\nconst DEFAULT_MAX_RESULTS = 100;\n\nexport interface ContentMatchRange {\n  start: number;\n  end: number;\n}\n\nexport interface ContentSearchMatch {\n  path: string;\n  lineNumber: number;\n  line: string;\n  ranges: ContentMatchRange[];\n  fuzzy: boolean;\n}\n\nexport interface ContentSearchResult {\n  matches: ContentSearchMatch[];\n  truncated: boolean;\n  skippedFiles: number;\n}\n\nexport interface ContentSearchOptions {\n  caseSensitive?: boolean;\n  fuzzy?: boolean;\n  maxResults?: number;\n  signal?: AbortSignal;\n}\n\ninterface SearchableTextFile {\n  path: string;\n  lines: readonly string[];\n}\n\ntype IndexedCharacter = { start: number; end: number; comparable: string };\n\ntype LoadSearchableFile = (path: string, signal?: AbortSignal) => Promise<SearchableTextFile>;\n\nexport async function searchProjectContents(\n  files: readonly string[],\n  loadFile: LoadSearchableFile,\n  query: string,\n  options: ContentSearchOptions = {},\n): Promise<ContentSearchResult> {\n  const signal = options.signal;\n  signal?.throwIfAborted();\n  if (!query.trim() || query.length > MAX_CONTENT_QUERY_LENGTH) {\n    return { matches: [], truncated: false, skippedFiles: 0 };\n  }\n\n  const maxResults = Math.max(1, options.maxResults ?? DEFAULT_MAX_RESULTS);\n  const caseSensitive = options.caseSensitive ?? false;\n  const literalExpression = new RegExp(escapeRegExp(query), caseSensitive ? \"g\" : \"gi\");\n  const fuzzyQuery = options.fuzzy ? indexedCharacters(query, caseSensitive) : [];\n  const matches: ContentSearchMatch[] = [];\n  let truncated = false;\n  let skippedFiles = 0;\n\n  for (const path of files) {\n    signal?.throwIfAborted();\n    let file: SearchableTextFile;\n    try {\n      file = await loadFile(path, signal);\n    } catch (error: unknown) {\n      if (isAbortError(error) || signal?.aborted) throw error;\n      skippedFiles += 1;\n      continue;\n    }\n    signal?.throwIfAborted();\n\n    for (let lineIndex = 0; lineIndex < file.lines.length; lineIndex += 1) {\n      const line = file.lines[lineIndex] ?? \"\";\n      const literalRanges = findLiteralRanges(line, literalExpression);\n      if (literalRanges.length > 0) {\n        if (matches.length < maxResults) {\n          matches.push({\n            path: file.path,\n            lineNumber: lineIndex + 1,\n            line,\n            ranges: literalRanges,\n            fuzzy: false,\n          });\n        } else {\n          truncated = true;\n        }\n        continue;\n      }\n\n      if (!options.fuzzy) continue;\n      const fuzzyRanges = findSubsequenceRanges(line, fuzzyQuery, caseSensitive);\n      if (!fuzzyRanges) continue;\n      if (matches.length < maxResults) {\n        matches.push({\n          path: file.path,\n          lineNumber: lineIndex + 1,\n          line,\n          ranges: fuzzyRanges,\n          fuzzy: true,\n        });\n      } else {\n        truncated = true;\n      }\n    }\n  }\n\n  return { matches, truncated, skippedFiles };\n}\n\nfunction findLiteralRanges(line: string, expression: RegExp): ContentMatchRange[] {\n  const ranges: ContentMatchRange[] = [];\n  expression.lastIndex = 0;\n  for (let match = expression.exec(line); match; match = expression.exec(line)) {\n    const start = match.index;\n    ranges.push({ start, end: start + match[0].length });\n  }\n  return ranges;\n}\n\nfunction findSubsequenceRanges(\n  line: string,\n  queryCharacters: readonly IndexedCharacter[],\n  caseSensitive: boolean,\n): ContentMatchRange[] | undefined {\n  const lineCharacters = indexedCharacters(line, caseSensitive);\n  const positions: Array<{ start: number; end: number }> = [];\n  let queryIndex = 0;\n  for (let lineIndex = 0; lineIndex < lineCharacters.length && queryIndex < queryCharacters.length; lineIndex += 1) {\n    const lineCharacter = lineCharacters[lineIndex];\n    const queryCharacter = queryCharacters[queryIndex];\n    if (!lineCharacter || !queryCharacter || lineCharacter.comparable !== queryCharacter.comparable) {\n      continue;\n    }\n    positions.push({ start: lineCharacter.start, end: lineCharacter.end });\n    queryIndex += 1;\n  }\n  if (queryIndex !== queryCharacters.length) return undefined;\n\n  const ranges: ContentMatchRange[] = [];\n  for (const position of positions) {\n    const previous = ranges.at(-1);\n    if (previous?.end === position.start) previous.end = position.end;\n    else ranges.push(position);\n  }\n  return ranges;\n}\n\nfunction indexedCharacters(value: string, caseSensitive: boolean): IndexedCharacter[] {\n  const characters: IndexedCharacter[] = [];\n  for (let start = 0; start < value.length; ) {\n    const codePoint = value.codePointAt(start);\n    if (codePoint === undefined) break;\n    const character = String.fromCodePoint(codePoint);\n    const end = start + character.length;\n    characters.push({\n      start,\n      end,\n      comparable: caseSensitive ? character : character.toLowerCase(),\n    });\n    start = end;\n  }\n  return characters;\n}\n\nfunction escapeRegExp(value: string): string {\n  return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction isAbortError(error: unknown): boolean {\n  return error instanceof Error && error.name === \"AbortError\";\n}\n", "import type { Theme } from \"@earendil-works/pi-coding-agent\";\nimport { truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { ContentMatchRange, ContentSearchMatch } from \"./content-search.js\";\n\nexport const CONTENT_SEARCH_CARD_ROWS = 3;\n\ninterface ContentSearchScreenOptions {\n  theme: Theme;\n  width: number;\n  availableRows: number;\n  queryLine: string;\n  query: string;\n  cwd?: string;\n  matches: readonly ContentSearchMatch[];\n  selectedIndex: number;\n  scrollOffset: number;\n  caseSensitive: boolean;\n  fuzzy: boolean;\n  loading: boolean;\n  opening: boolean;\n  truncated: boolean;\n  skippedFiles: number;\n  error?: string;\n}\n\nexport function contentSearchCardCapacity(availableRows: number): number {\n  return Math.max(1, Math.floor((availableRows - 4) / CONTENT_SEARCH_CARD_ROWS));\n}\n\nexport function renderContentSearchScreen(options: ContentSearchScreenOptions): string[] {\n  const { theme, width, availableRows } = options;\n  const capacity = contentSearchCardCapacity(availableRows);\n  const cwdLabel = options.cwd ? ` \u00B7 cwd: ${escapeTerminalControls(options.cwd)}` : \"\";\n  const title = theme.fg(\"accent\", theme.bold(`File Context \u00B7 Content Search${cwdLabel}`));\n  const modes = theme.fg(\n    \"muted\",\n    `Case: ${options.caseSensitive ? \"on\" : \"off\"} \u00B7 Fuzzy: ${options.fuzzy ? \"on\" : \"off\"} \u00B7 Alt+C case \u00B7 Alt+F fuzzy`,\n  );\n  const body: string[] = [];\n\n  if (options.error) {\n    body.push(theme.fg(\"error\", `  Search failed: ${escapeTerminalControls(options.error)}`));\n  } else if (options.loading) {\n    body.push(theme.fg(\"warning\", \"  Searching\u2026\"));\n  } else if (!options.query.trim()) {\n    body.push(theme.fg(\"muted\", \"  Type text to search project contents\"));\n  } else if (options.matches.length === 0) {\n    body.push(\n      theme.fg(\n        \"muted\",\n        `  No matches for \"${escapeTerminalControls(options.query)}\"${options.fuzzy ? \"\" : \" \u00B7 Alt+F enables fuzzy matching\"}`,\n      ),\n    );\n  } else {\n    const visible = options.matches.slice(options.scrollOffset, options.scrollOffset + capacity);\n    for (let visibleIndex = 0; visibleIndex < visible.length; visibleIndex += 1) {\n      const index = options.scrollOffset + visibleIndex;\n      const match = visible[visibleIndex];\n      if (match) {\n        body.push(...renderContentSearchCard(match, index === options.selectedIndex, width, theme));\n      }\n    }\n  }\n\n  const count = `${options.matches.length}${options.truncated ? \"+\" : \"\"} matches`;\n  const skipped = options.skippedFiles > 0 ? ` \u00B7 ${options.skippedFiles} skipped` : \"\";\n  const action = options.opening\n    ? \"Opening\u2026\"\n    : `${count}${skipped} \u00B7 \u2191\u2193 navigate \u00B7 Enter preview \u00B7 Tab reference \u00B7 Ctrl+F files \u00B7 Esc cancel`;\n  return fitRows(\n    [\n      truncateToWidth(title, width, \"\"),\n      truncateToWidth(options.queryLine, width, \"\"),\n      truncateToWidth(modes, width, \"\"),\n      ...body.map((line) => truncateToWidth(line, width, \"\")),\n      truncateToWidth(theme.fg(options.opening ? \"warning\" : \"muted\", action), width, \"\"),\n    ],\n    availableRows,\n  );\n}\n\nexport function highlightContentRanges(line: string, ranges: readonly ContentMatchRange[], theme: Theme): string {\n  let result = \"\";\n  let index = 0;\n  for (const range of ranges) {\n    const start = Math.max(index, Math.min(line.length, range.start));\n    const end = Math.max(start, Math.min(line.length, range.end));\n    result += escapeTerminalControls(line.slice(index, start));\n    result += theme.fg(\"warning\", theme.bold(escapeTerminalControls(line.slice(start, end))));\n    index = end;\n  }\n  return result + escapeTerminalControls(line.slice(index));\n}\n\nfunction renderContentSearchCard(match: ContentSearchMatch, selected: boolean, width: number, theme: Theme): string[] {\n  if (width < 8) {\n    return [truncateToWidth(`${selected ? \">\" : \" \"}${escapeTerminalControls(match.path)}`, width, \"\")];\n  }\n  const prefix = selected ? theme.fg(\"accent\", \"> \") : \"  \";\n  const cardWidth = Math.max(4, width - visibleWidth(prefix));\n  const innerWidth = Math.max(1, cardWidth - 2);\n  const borderColor = selected ? \"borderAccent\" : \"borderMuted\";\n  const border = (text: string) => theme.fg(borderColor, text);\n  const rawTitle = ` ${escapeTerminalControls(match.path)} \u00B7 L${match.lineNumber} `;\n  const title = truncateToWidth(rawTitle, innerWidth, \"\");\n  const titleFill = \"\u2500\".repeat(Math.max(0, innerWidth - visibleWidth(title)));\n  const context = clipMatchContext(match, Math.max(1, innerWidth - 1));\n  const highlighted = highlightContentRanges(context.line, context.ranges, theme);\n  const content = truncateToWidth(` ${highlighted}`, innerWidth, \"\");\n  const contentFill = \" \".repeat(Math.max(0, innerWidth - visibleWidth(content)));\n  const contentLine = `${border(\"\u2502\")}${content}${contentFill}${border(\"\u2502\")}`;\n  return [\n    `${prefix}${border(\"\u256D\")}${title}${border(`${titleFill}\u256E`)}`,\n    `${\" \".repeat(visibleWidth(prefix))}${selected ? theme.bg(\"selectedBg\", contentLine) : contentLine}`,\n    `${\" \".repeat(visibleWidth(prefix))}${border(`\u2570${\"\u2500\".repeat(innerWidth)}\u256F`)}`,\n  ];\n}\n\nfunction clipMatchContext(\n  match: ContentSearchMatch,\n  maxCharacters: number,\n): { line: string; ranges: ContentMatchRange[] } {\n  const firstStart = match.ranges[0]?.start ?? 0;\n  const lastEnd = match.ranges.at(-1)?.end ?? firstStart;\n  const matchSpan = Math.max(1, lastEnd - firstStart);\n  const before = Math.max(0, Math.floor((maxCharacters - Math.min(matchSpan, maxCharacters)) / 3));\n  const rawStart = Math.max(0, firstStart - before);\n  const prefix = rawStart > 0 ? \"\u2026\" : \"\";\n  const availableRawCharacters = Math.max(1, maxCharacters - prefix.length - 1);\n  let rawEnd = Math.min(match.line.length, rawStart + availableRawCharacters);\n  if (rawEnd < lastEnd) rawEnd = Math.min(match.line.length, lastEnd);\n  const suffix = rawEnd < match.line.length ? \"\u2026\" : \"\";\n  const line = `${prefix}${match.line.slice(rawStart, rawEnd)}${suffix}`;\n  const ranges = match.ranges.flatMap((range): ContentMatchRange[] => {\n    const start = Math.max(rawStart, range.start);\n    const end = Math.min(rawEnd, range.end);\n    return end > start ? [{ start: prefix.length + start - rawStart, end: prefix.length + end - rawStart }] : [];\n  });\n  return { line, ranges };\n}\n\nfunction fitRows(lines: string[], height: number): string[] {\n  if (lines.length <= height) return lines;\n  if (height <= 1) return lines.slice(0, 1);\n  return [...lines.slice(0, height - 1), lines.at(-1) ?? \"\"];\n}\n\nfunction escapeTerminalControls(text: string): string {\n  return [...text]\n    .map((character) => {\n      if (character === \"\\t\") return \"    \";\n      const code = character.charCodeAt(0);\n      if (code <= 31 || (code >= 127 && code <= 159)) {\n        return `\\\\x${code.toString(16).padStart(2, \"0\")}`;\n      }\n      return character;\n    })\n    .join(\"\");\n}\n", "interface IndexedProjectFile {\n  path: string;\n  displayPath: string;\n  segments: readonly string[];\n}\n\nexport type ProjectBrowserItem =\n  | { kind: \"directory\"; path: string; label: string }\n  | { kind: \"file\"; path: string; label: string };\n\nexport class ProjectFileBrowser {\n  private readonly files: readonly IndexedProjectFile[];\n  private readonly filesByPath: ReadonlyMap<string, IndexedProjectFile>;\n\n  constructor(paths: readonly string[]) {\n    this.files = paths.map((path) => {\n      const displayPath = safeTerminalText(path);\n      return { path, displayPath, segments: displayPath.split(\"/\") };\n    });\n    this.filesByPath = new Map(this.files.map((file) => [file.path, file]));\n  }\n\n  list(directory: string): ProjectBrowserItem[] {\n    const directorySegments = directory ? directory.split(\"/\") : [];\n    const directories = new Map<string, ProjectBrowserItem>();\n    const files: ProjectBrowserItem[] = [];\n\n    for (const file of this.files) {\n      if (!startsWithSegments(file.segments, directorySegments)) continue;\n      const childIndex = directorySegments.length;\n      const label = file.segments[childIndex];\n      if (!label) continue;\n      if (file.segments.length > childIndex + 1) {\n        const path = [...directorySegments, label].join(\"/\");\n        directories.set(path, { kind: \"directory\", path, label });\n        continue;\n      }\n      files.push({ kind: \"file\", path: file.path, label });\n    }\n\n    return [...[...directories.values()].sort(compareBrowserItems), ...files.sort(compareBrowserItems)];\n  }\n\n  searchResults(paths: readonly string[]): ProjectBrowserItem[] {\n    return paths.flatMap((path) => {\n      const file = this.filesByPath.get(path);\n      return file ? [{ kind: \"file\" as const, path: file.path, label: file.displayPath }] : [];\n    });\n  }\n}\n\nexport function parentProjectDirectory(directory: string): string {\n  const separator = directory.lastIndexOf(\"/\");\n  return separator < 0 ? \"\" : directory.slice(0, separator);\n}\n\nexport function safeTerminalText(text: string): string {\n  return [...text]\n    .map((character) => {\n      if (character === \"\\t\") return \"    \";\n      const code = character.charCodeAt(0);\n      if (code <= 31 || (code >= 127 && code <= 159)) {\n        return `\\\\x${code.toString(16).padStart(2, \"0\")}`;\n      }\n      return character;\n    })\n    .join(\"\");\n}\n\nfunction startsWithSegments(path: readonly string[], prefix: readonly string[]): boolean {\n  return prefix.every((segment, index) => path[index] === segment);\n}\n\nfunction compareBrowserItems(left: ProjectBrowserItem, right: ProjectBrowserItem): number {\n  return left.label < right.label ? -1 : left.label > right.label ? 1 : 0;\n}\n", "import type { KeybindingsManager, Theme } from \"@earendil-works/pi-coding-agent\";\nimport { truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { ProjectBrowserItem } from \"./file-browser.js\";\nimport { safeTerminalText } from \"./file-browser.js\";\n\ninterface FileBrowserRenderOptions {\n  theme: Theme;\n  keybindings: KeybindingsManager;\n  width: number;\n  height: number;\n  items: readonly ProjectBrowserItem[];\n  selectedIndex: number;\n  scrollOffset: number;\n  currentDirectory: string;\n  searchLine: string;\n  searchActive: boolean;\n  repositoryLabel: string;\n  statuses?: ReadonlyMap<string, { code: string }>;\n  loading: boolean;\n  error?: string;\n}\n\nexport function renderFileBrowser(options: FileBrowserRenderOptions): string[] {\n  const location = options.currentDirectory ? `/${options.currentDirectory}` : \"/\";\n  const title = options.theme.fg(\n    \"accent\",\n    options.theme.bold(`File Context \u00B7 files \u00B7 ${location}${options.repositoryLabel}`),\n  );\n  const visibleItems = options.items.slice(options.scrollOffset, options.scrollOffset + options.height);\n  const itemLines = visibleItems.map((item, visibleIndex) => {\n    const index = options.scrollOffset + visibleIndex;\n    const prefix = index === options.selectedIndex ? \"> \" : \"  \";\n    const status = item.kind === \"file\" ? (options.statuses?.get(item.path)?.code ?? \"  \") : \"  \";\n    const suffix = item.kind === \"directory\" ? \"/\" : \"\";\n    const line = `${prefix}${status} ${item.label}${suffix}`;\n    return truncateToWidth(\n      index === options.selectedIndex ? options.theme.bg(\"selectedBg\", options.theme.fg(\"text\", line)) : line,\n      options.width,\n      \"\",\n    );\n  });\n  if (itemLines.length === 0) {\n    itemLines.push(truncateToWidth(options.theme.fg(\"muted\", \"  No matching files\"), options.width, \"\"));\n  }\n  const state = options.loading\n    ? options.theme.fg(\"warning\", \"Loading\u2026\")\n    : options.error\n      ? options.theme.fg(\"error\", safeTerminalText(options.error))\n      : options.theme.fg(\"muted\", formatFileBrowserHint(options));\n  return [\n    truncateToWidth(title, options.width, \"\"),\n    truncateToWidth(options.searchLine, options.width, \"\"),\n    ...itemLines,\n    truncateToWidth(state, options.width, \"\"),\n  ];\n}\n\nfunction formatFileBrowserHint(options: FileBrowserRenderOptions): string {\n  const selected = options.items[options.selectedIndex];\n  const countLabel = options.searchActive\n    ? `${options.items.length} matching ${options.items.length === 1 ? \"file\" : \"files\"}`\n    : `${options.items.length} ${options.items.length === 1 ? \"item\" : \"items\"}`;\n  const navigation = navigationHint(options.keybindings);\n  const confirm = bindingHint(options.keybindings, \"tui.select.confirm\", [\"enter\"]);\n  const tab = bindingHint(options.keybindings, \"tui.input.tab\", [\"tab\"]);\n  const cancel = uniqueKeys([\n    ...bindingKeys(options.keybindings, \"tui.select.cancel\", [\"escape\"]),\n    formatHintKey(\"ctrl+c\"),\n  ]).join(\"/\");\n  return [\n    countLabel,\n    `${navigation} navigate`,\n    `${confirm} ${selected?.kind === \"directory\" ? \"open folder\" : \"preview\"}`,\n    ...(selected?.kind === \"file\" ? [`${tab} reference`] : []),\n    \"Ctrl+F contents\",\n    `${cancel} ${options.currentDirectory && !options.searchActive ? \"back\" : \"cancel\"}`,\n  ].join(\" \u00B7 \");\n}\n\nfunction navigationHint(keybindings: KeybindingsManager): string {\n  const up = bindingKeys(keybindings, \"tui.select.up\", [\"up\"]);\n  const down = bindingKeys(keybindings, \"tui.select.down\", [\"down\"]);\n  if (up.includes(\"\u2191\") && down.includes(\"\u2193\")) {\n    return uniqueKeys([\"\u2191\u2193\", ...up.filter((key) => key !== \"\u2191\"), ...down.filter((key) => key !== \"\u2193\")]).join(\"/\");\n  }\n  return uniqueKeys([...up, ...down]).join(\"/\");\n}\n\nexport function bindingHint(\n  keybindings: KeybindingsManager,\n  binding: Parameters<KeybindingsManager[\"getKeys\"]>[0],\n  fallback: readonly string[],\n): string {\n  return bindingKeys(keybindings, binding, fallback).join(\"/\");\n}\n\nfunction bindingKeys(\n  keybindings: KeybindingsManager,\n  binding: Parameters<KeybindingsManager[\"getKeys\"]>[0],\n  fallback: readonly string[],\n): string[] {\n  const getKeys = keybindings.getKeys?.bind(keybindings);\n  const keys = getKeys?.(binding) ?? fallback;\n  return uniqueKeys(keys.map(formatHintKey));\n}\n\nfunction uniqueKeys(keys: readonly string[]): string[] {\n  return [...new Set(keys.filter(Boolean))];\n}\n\nfunction formatHintKey(key: string): string {\n  const normalized = safeTerminalText(key).toLowerCase();\n  if (normalized === \"up\") return \"\u2191\";\n  if (normalized === \"down\") return \"\u2193\";\n  if (normalized === \"left\") return \"\u2190\";\n  if (normalized === \"right\") return \"\u2192\";\n  if (normalized === \"return\" || normalized === \"enter\") return \"Enter\";\n  if (normalized === \"escape\" || normalized === \"esc\") return \"Esc\";\n  if (normalized === \"tab\") return \"Tab\";\n  return normalized\n    .split(\"+\")\n    .map((part, index) =>\n      part === \"ctrl\" || part === \"alt\" || part === \"shift\" || (index > 0 && part.length === 1)\n        ? `${part[0]?.toUpperCase()}${part.slice(1)}`\n        : part,\n    )\n    .join(\"+\");\n}\n", "import type { KeybindingsManager, Theme } from \"@earendil-works/pi-coding-agent\";\nimport { truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { ContentSearchMatch } from \"./content-search.js\";\nimport { highlightContentRanges } from \"./content-search-ui.js\";\nimport { bindingHint } from \"./file-browser-ui.js\";\nimport type { LoadedProjectTextFile } from \"./file-context.js\";\nimport type { GitBlameInfo, GitFileContext, GitProjectInfo, GitRevisionFile } from \"./git-context.js\";\n\nexport interface SelectedContextState {\n  count: number;\n  totalBytes: number;\n  maximumCount: number;\n  maximumBytes: number;\n  maximumSnippetLines?: number;\n  maximumSnippetBytes?: number;\n}\n\ninterface FilePreviewRenderOptions {\n  theme: Theme;\n  keybindings: KeybindingsManager;\n  width: number;\n  availableRows: number;\n  file: LoadedProjectTextFile;\n  fileGit?: GitFileContext;\n  project?: GitProjectInfo;\n  revision?: GitRevisionFile;\n  contentMatch?: ContentSearchMatch;\n  blame?: GitBlameInfo;\n  cursor: number;\n  anchor?: number;\n  scrollOffset: number;\n  error?: string;\n  selectedContext?: SelectedContextState;\n  canContinue: boolean;\n  canEdit: boolean;\n}\n\nexport function renderFilePreview(options: FilePreviewRenderOptions): string[] {\n  const { file, theme, width } = options;\n  const range = selectionRange(options.anchor, options.cursor);\n  const selectedText = file.lines.slice(range.start, range.end + 1).join(\"\\n\");\n  const selectedBytes = Buffer.byteLength(selectedText, \"utf8\");\n  const estimatedTokens = Math.max(1, Math.ceil(selectedBytes / 4));\n  const externalEditorKey = bindingHint(options.keybindings, \"app.editor.external\", []);\n  const footer = options.error\n    ? { lines: [escapeTerminalControls(options.error)], primaryIndexes: [0] }\n    : previewFooterLines(\n        width,\n        range.start + 1,\n        range.end + 1,\n        estimatedTokens,\n        selectedBytes,\n        options.selectedContext,\n        options.canContinue,\n        options.canEdit ? externalEditorKey : \"\",\n      );\n  const previewHeight = Math.max(1, options.availableRows - 1 - (options.blame ? 1 : 0) - footer.lines.length);\n  const scrollOffset = visiblePreviewOffset(options.scrollOffset, options.cursor, previewHeight);\n  const digits = String(Math.max(1, file.lines.length)).length;\n  const changedLines = new Set(options.fileGit?.hunks.flatMap((hunk) => hunk.changedLines) ?? []);\n  const deletedAtLines = new Set(\n    (options.fileGit?.hunks ?? [])\n      .filter((hunk) => hunk.changedLines.length === 0 && hunk.oldCount > 0)\n      .map((hunk) => Math.max(1, hunk.newStart)),\n  );\n  const previewLines = file.lines.slice(scrollOffset, scrollOffset + previewHeight).map((rawLine, visibleIndex) => {\n    const index = scrollOffset + visibleIndex;\n    const selected = index >= range.start && index <= range.end;\n    const cursor = index === options.cursor ? \">\" : \" \";\n    const marker = changedLines.has(index + 1) ? \"+\" : deletedAtLines.has(index + 1) ? \"-\" : \" \";\n    const number = String(index + 1).padStart(digits, \" \");\n    const contentMatch =\n      options.contentMatch?.path === file.path &&\n      options.contentMatch.lineNumber === index + 1 &&\n      options.contentMatch.line === rawLine\n        ? options.contentMatch\n        : undefined;\n    const content = contentMatch\n      ? highlightContentRanges(rawLine, contentMatch.ranges, theme)\n      : escapeTerminalControls(rawLine);\n    const line = `${cursor}${marker}${number} \u2502 ${content}`;\n    const styled = selected\n      ? theme.bg(\"selectedBg\", theme.fg(\"text\", line))\n      : index === options.cursor\n        ? theme.fg(\"accent\", line)\n        : line;\n    return truncateToWidth(styled, width, \"\");\n  });\n  if (previewLines.length === 0) {\n    previewLines.push(truncateToWidth(theme.fg(\"muted\", \"  Empty file\"), width, \"\"));\n  }\n  const gitLabel = options.revision\n    ? `${escapeTerminalControls(options.revision.revision)}@${options.revision.commit.slice(0, 12)} \u00B7 historical`\n    : options.project\n      ? `${escapeTerminalControls(options.project.branch)}@${options.project.head.slice(0, 12)}${options.project.dirty ? \" \u00B7 dirty\" : \"\"}${options.fileGit?.status ? ` \u00B7 ${options.fileGit.status.label}` : \" \u00B7 clean\"}`\n      : \"\";\n  const blameLabel = options.blame\n    ? `L${options.cursor + 1} \u00B7 ${options.blame.committed ? options.blame.commit.slice(0, 12) : \"uncommitted\"} \u00B7 ${escapeTerminalControls(options.blame.author)} \u00B7 ${escapeTerminalControls(options.blame.summary)}`\n    : \"\";\n  const titleLine = truncateToWidth(\n    theme.fg(\"accent\", theme.bold(`${escapeTerminalControls(file.path)}${gitLabel ? ` \u00B7 ${gitLabel}` : \"\"}`)),\n    width,\n    \"\",\n  );\n  const blameLine = blameLabel ? truncateToWidth(theme.fg(\"muted\", blameLabel), width, \"\") : undefined;\n  const renderedFooter = footer.lines.map((line) =>\n    truncateToWidth(theme.fg(options.error ? \"error\" : \"muted\", line), width, \"\"),\n  );\n  return fitPreviewRows(\n    titleLine,\n    blameLine,\n    previewLines,\n    renderedFooter,\n    footer.primaryIndexes,\n    options.availableRows,\n  );\n}\n\nexport function renderFilePreviewHelp(\n  theme: Theme,\n  keybindings: KeybindingsManager,\n  width: number,\n  availableRows: number,\n  canEdit: boolean,\n): string[] {\n  const externalEditorKey = bindingHint(keybindings, \"app.editor.external\", []);\n  const editDetailed = canEdit\n    ? externalEditorKey\n      ? `${externalEditorKey.padEnd(6, \" \")} Edit the current worktree file in the external editor`\n      : \"Edit   External editor action is unbound\"\n    : \"Edit   Historical revisions are read-only\";\n  const editCompact = canEdit\n    ? externalEditorKey\n      ? `${externalEditorKey} edit worktree`\n      : \"External editor unbound\"\n    : \"Historical revision \u00B7 read-only\";\n  const detailed = [\n    theme.fg(\"accent\", theme.bold(\"Preview actions\")),\n    \"Enter  Add selected lines and close File Context\",\n    \"A      Add selected lines and keep browsing\",\n    \"Space  Set or clear the range anchor; arrows extend the range\",\n    \"[ / ]  Select the previous or next changed hunk\",\n    \"B      Blame: show ownership for the current line when Git is available\",\n    \"H      History: browse earlier versions of this file\",\n    \"R      Revision: open a commit, branch, or tag\",\n    \"D      Git diff: review and add one explicit changed hunk\",\n    editDetailed,\n    \"Esc    Return to the preview without changing selected context\",\n  ];\n  const compact = [\n    theme.fg(\"accent\", theme.bold(\"Preview actions\")),\n    \"Enter add \u00B7 A keep browsing \u00B7 Space range\",\n    \"\u2191\u2193 extend \u00B7 [/] hunk \u00B7 B blame\",\n    \"H history \u00B7 R revision \u00B7 D Git diff\",\n    editCompact,\n    \"Esc back without changing context\",\n  ];\n  const lines = availableRows < detailed.length ? compact : detailed;\n  return fitRows(\n    lines.map((line) => truncateToWidth(line, width, \"\")),\n    availableRows,\n  );\n}\n\nfunction previewFooterLines(\n  width: number,\n  startLine: number,\n  endLine: number,\n  tokens: number,\n  selectedBytes: number,\n  state: SelectedContextState | undefined,\n  canContinue: boolean,\n  externalEditorKey: string,\n): { lines: string[]; primaryIndexes: number[] } {\n  const nextCount = state ? state.count + 1 : undefined;\n  const nextBytes = state ? state.totalBytes + selectedBytes : undefined;\n  const selectedLines = endLine - startLine + 1;\n  const snippetOverLimit =\n    state !== undefined &&\n    ((state.maximumSnippetLines !== undefined && selectedLines > state.maximumSnippetLines) ||\n      (state.maximumSnippetBytes !== undefined && selectedBytes > state.maximumSnippetBytes));\n  const aggregateOverLimit =\n    state !== undefined &&\n    nextCount !== undefined &&\n    (nextCount > state.maximumCount || (nextBytes ?? 0) > state.maximumBytes);\n  const warning = snippetOverLimit\n    ? \"Snippet limit exceeded\"\n    : aggregateOverLimit\n      ? \"Next prompt limit exceeded\"\n      : undefined;\n  if (width < 74) {\n    const selection = `L${startLine}-${endLine} \u00B7 ~${tokens} tok`;\n    const capacity = state ? (warning ?? `Next ${nextCount}/${state.maximumCount}`) : undefined;\n    const lines = [\n      [selection, capacity].filter(Boolean).join(\" \u00B7 \"),\n      canContinue ? \"Enter add \u00B7 A keep browsing\" : \"Enter add & close\",\n      \"\u2191\u2193 move \u00B7 Space range \u00B7 Esc back\",\n      [externalEditorKey ? `${externalEditorKey} edit` : \"\", \"? actions\"].filter(Boolean).join(\" \u00B7 \"),\n      \"B blame \u00B7 H history \u00B7 R revision\",\n      \"D diff \u00B7 [/] hunk\",\n    ];\n    return { lines, primaryIndexes: [1, 3] };\n  }\n  const selection = `Lines ${startLine}-${endLine} \u00B7 ~${tokens} tokens`;\n  const capacity = state\n    ? snippetOverLimit\n      ? \"Snippet limit exceeded; shorten the range before adding\"\n      : aggregateOverLimit\n        ? \"Next prompt limit exceeded; shorten the range or review selected context\"\n        : `Next prompt: ${nextCount}/${state.maximumCount} snippets \u00B7 ~${estimateTokens(nextBytes ?? 0)} tokens`\n    : undefined;\n  const primaryActions = canContinue\n    ? \"Enter add & close \u00B7 A add & continue \u00B7 \u2191\u2193 move \u00B7 Space range \u00B7 Esc back\"\n    : \"Enter add & close \u00B7 \u2191\u2193 move \u00B7 Space range \u00B7 Esc back\";\n  const editActions = [externalEditorKey ? `${externalEditorKey} edit` : \"\", \"? actions\"].filter(Boolean).join(\" \u00B7 \");\n  return {\n    lines: [\n      [selection, capacity].filter(Boolean).join(\" \u00B7 \"),\n      primaryActions,\n      editActions,\n      \"B blame \u00B7 H history \u00B7 R revision \u00B7 D diff \u00B7 [/] hunk\",\n    ],\n    primaryIndexes: [1, 2],\n  };\n}\n\nfunction selectionRange(anchor: number | undefined, cursor: number) {\n  const rangeAnchor = anchor ?? cursor;\n  return {\n    start: Math.min(rangeAnchor, cursor),\n    end: Math.max(rangeAnchor, cursor),\n  };\n}\n\nfunction visiblePreviewOffset(current: number, cursor: number, height: number): number {\n  if (cursor < current) return cursor;\n  if (cursor >= current + height) return cursor - height + 1;\n  return current;\n}\n\nfunction estimateTokens(bytes: number): number {\n  return bytes === 0 ? 0 : Math.max(1, Math.ceil(bytes / 4));\n}\n\nfunction fitPreviewRows(\n  title: string,\n  blame: string | undefined,\n  previewLines: readonly string[],\n  footerLines: readonly string[],\n  primaryFooterIndexes: readonly number[],\n  height: number,\n): string[] {\n  let visibleTitle: string | undefined = title;\n  let visibleBlame = blame;\n  const visiblePreview = [...previewLines];\n  const visibleFooter = footerLines.map((line, index) => ({\n    line,\n    primary: primaryFooterIndexes.includes(index),\n  }));\n  const rowCount = () => (visibleTitle ? 1 : 0) + (visibleBlame ? 1 : 0) + visiblePreview.length + visibleFooter.length;\n\n  while (rowCount() > height) {\n    if (visibleBlame) {\n      visibleBlame = undefined;\n      continue;\n    }\n    if (visiblePreview.length > 1) {\n      visiblePreview.pop();\n      continue;\n    }\n    let optionalFooter = -1;\n    for (let index = visibleFooter.length - 1; index >= 0; index -= 1) {\n      if (!visibleFooter[index]?.primary) {\n        optionalFooter = index;\n        break;\n      }\n    }\n    if (optionalFooter >= 0) {\n      visibleFooter.splice(optionalFooter, 1);\n      continue;\n    }\n    if (visibleTitle) {\n      visibleTitle = undefined;\n      continue;\n    }\n    if (visiblePreview.length > 0) {\n      visiblePreview.pop();\n      continue;\n    }\n    break;\n  }\n\n  return [\n    ...(visibleTitle ? [visibleTitle] : []),\n    ...(visibleBlame ? [visibleBlame] : []),\n    ...visiblePreview,\n    ...visibleFooter.map(({ line }) => line),\n  ];\n}\n\nfunction fitRows(lines: string[], height: number): string[] {\n  if (lines.length <= height) return lines;\n  if (height <= 1) return lines.slice(0, 1);\n  return [...lines.slice(0, height - 1), lines.at(-1) ?? \"\"];\n}\n\nfunction escapeTerminalControls(text: string): string {\n  return [...text]\n    .map((character) => {\n      if (character === \"\\t\") return \"    \";\n      const code = character.charCodeAt(0);\n      if (code <= 31 || (code >= 127 && code <= 159)) {\n        return `\\\\x${code.toString(16).padStart(2, \"0\")}`;\n      }\n      return character;\n    })\n    .join(\"\");\n}\n", "import { safeTerminalText } from \"./file-browser.js\";\n\nconst MAX_SEARCH_QUERY_LENGTH = 256;\nconst MAX_SEARCH_QUERY_PARTS = 8;\nconst PATH_SCORE_PENALTY = 50;\nconst PREFIX_SCORE = 100;\nconst SUBSTRING_SCORE = 200;\nconst TYPO_SCORE = 300;\nconst SUBSEQUENCE_SCORE = 400;\nconst TOKENIZED_SCORE = 500;\nconst NO_MATCH = Number.POSITIVE_INFINITY;\nconst PATH_PART_SEPARATOR = /[/._\\-\\s]+/u;\n\ninterface ProjectFileEntry {\n  path: string;\n  normalizedPath: string;\n  normalizedBasename: string;\n  basenameParts: readonly string[];\n  pathParts: readonly string[];\n  originalIndex: number;\n}\n\ninterface RankedProjectFile {\n  path: string;\n  score: number;\n  originalIndex: number;\n}\n\ntype TypoDistanceCache = Map<string, Map<string, number | undefined>>;\n\nexport class ProjectFileSearch {\n  private readonly files: readonly string[];\n  private readonly entries: readonly ProjectFileEntry[];\n\n  constructor(files: readonly string[]) {\n    this.files = [...files];\n    this.entries = this.files.map((path, originalIndex) => {\n      const normalizedPath = safeTerminalText(path).toLowerCase();\n      const normalizedBasename = normalizedPath.slice(normalizedPath.lastIndexOf(\"/\") + 1);\n      return {\n        path,\n        normalizedPath,\n        normalizedBasename,\n        basenameParts: splitPathParts(normalizedBasename),\n        pathParts: splitPathParts(normalizedPath),\n        originalIndex,\n      };\n    });\n  }\n\n  search(query: string): string[] {\n    const trimmedQuery = safeTerminalText(query).trim();\n    if (!trimmedQuery) return [...this.files];\n    if (trimmedQuery.length > MAX_SEARCH_QUERY_LENGTH) return [];\n    const normalizedQuery = trimmedQuery.toLowerCase();\n    const queryParts = splitPathParts(normalizedQuery);\n    const typoDistanceCache: TypoDistanceCache = new Map();\n\n    return this.entries\n      .flatMap((entry): RankedProjectFile[] => {\n        const score = scoreEntry(normalizedQuery, queryParts, entry, typoDistanceCache);\n        return Number.isFinite(score) ? [{ path: entry.path, score, originalIndex: entry.originalIndex }] : [];\n      })\n      .sort((left, right) => left.score - right.score || left.originalIndex - right.originalIndex)\n      .map((result) => result.path);\n  }\n}\n\nfunction scoreEntry(\n  query: string,\n  queryParts: readonly string[],\n  entry: ProjectFileEntry,\n  typoDistanceCache: TypoDistanceCache,\n): number {\n  const basenameScore = scoreField(query, queryParts, entry.normalizedBasename, entry.basenameParts, typoDistanceCache);\n  const pathScore = scoreField(query, queryParts, entry.normalizedPath, entry.pathParts, typoDistanceCache);\n  return Math.min(basenameScore, pathScore + PATH_SCORE_PENALTY);\n}\n\nfunction scoreField(\n  query: string,\n  queryParts: readonly string[],\n  text: string,\n  textParts: readonly string[],\n  typoDistanceCache: TypoDistanceCache,\n): number {\n  const directScore = scoreText(query, text);\n  if (directScore < TYPO_SCORE) return directScore;\n  const typoScore = scoreTypo(query, textParts, typoDistanceCache);\n  if (Number.isFinite(typoScore)) return Math.min(directScore, typoScore);\n  if (Number.isFinite(directScore)) return directScore;\n  return scoreTokenized(queryParts, textParts, typoDistanceCache);\n}\n\nfunction scoreTokenized(\n  queryParts: readonly string[],\n  candidateParts: readonly string[],\n  typoDistanceCache: TypoDistanceCache,\n): number {\n  if (queryParts.length < 2 || queryParts.length > MAX_SEARCH_QUERY_PARTS) return NO_MATCH;\n\n  let totalScore = TOKENIZED_SCORE;\n  for (const queryPart of queryParts) {\n    let bestDirectScore = NO_MATCH;\n    for (let index = 0; index < candidateParts.length; index += 1) {\n      bestDirectScore = Math.min(bestDirectScore, scoreText(queryPart, candidateParts[index] ?? \"\") + index * 2);\n    }\n    const bestPartScore =\n      bestDirectScore < TYPO_SCORE\n        ? bestDirectScore\n        : Math.min(bestDirectScore, scoreTypo(queryPart, candidateParts, typoDistanceCache));\n    if (!Number.isFinite(bestPartScore)) return NO_MATCH;\n    totalScore += bestPartScore;\n  }\n  return totalScore;\n}\n\nfunction scoreText(query: string, text: string): number {\n  if (query === text) return 0;\n  if (text.startsWith(query)) return PREFIX_SCORE + lengthPenalty(query, text);\n\n  const substringIndex = text.indexOf(query);\n  if (substringIndex >= 0) {\n    return SUBSTRING_SCORE + substringIndex * 2 + lengthPenalty(query, text);\n  }\n\n  return scoreSubsequence(query, text);\n}\n\nfunction scoreSubsequence(query: string, text: string): number {\n  let queryIndex = 0;\n  let firstMatch = -1;\n  let previousMatch = -1;\n  let gaps = 0;\n  let boundaryMatches = 0;\n  let consecutiveMatches = 0;\n\n  for (let textIndex = 0; textIndex < text.length && queryIndex < query.length; textIndex += 1) {\n    if (text[textIndex] !== query[queryIndex]) continue;\n    if (firstMatch < 0) firstMatch = textIndex;\n    if (previousMatch >= 0) {\n      const gap = textIndex - previousMatch - 1;\n      gaps += gap;\n      if (gap === 0) consecutiveMatches += 1;\n    }\n    if (textIndex === 0 || PATH_PART_SEPARATOR.test(text[textIndex - 1] ?? \"\")) {\n      boundaryMatches += 1;\n    }\n    previousMatch = textIndex;\n    queryIndex += 1;\n  }\n\n  if (queryIndex !== query.length) return NO_MATCH;\n  return (\n    SUBSEQUENCE_SCORE +\n    gaps * 3 +\n    firstMatch * 2 +\n    lengthPenalty(query, text) -\n    boundaryMatches * 8 -\n    consecutiveMatches\n  );\n}\n\nfunction scoreTypo(query: string, parts: readonly string[], typoDistanceCache: TypoDistanceCache): number {\n  const maxDistance = allowedTypoDistance(query.length);\n  if (maxDistance === 0) return NO_MATCH;\n\n  let bestScore = NO_MATCH;\n  for (let index = 0; index < parts.length; index += 1) {\n    const part = parts[index] ?? \"\";\n    if (Math.abs(query.length - part.length) > maxDistance) continue;\n    const distance = cachedTypoDistance(query, part, maxDistance, typoDistanceCache);\n    if (distance === undefined || distance === 0) continue;\n    bestScore = Math.min(bestScore, TYPO_SCORE + distance * 20 + index * 2 + Math.abs(query.length - part.length));\n  }\n  return bestScore;\n}\n\nfunction cachedTypoDistance(\n  query: string,\n  part: string,\n  maxDistance: number,\n  cache: TypoDistanceCache,\n): number | undefined {\n  let queryCache = cache.get(query);\n  if (!queryCache) {\n    queryCache = new Map();\n    cache.set(query, queryCache);\n  }\n  if (queryCache.has(part)) return queryCache.get(part);\n  const distance = boundedDamerauLevenshtein(query, part, maxDistance);\n  queryCache.set(part, distance);\n  return distance;\n}\n\nfunction boundedDamerauLevenshtein(left: string, right: string, maxDistance: number): number | undefined {\n  if (Math.abs(left.length - right.length) > maxDistance) return undefined;\n\n  const unreachable = maxDistance + 1;\n  let previousPrevious = Array.from({ length: left.length + 1 }, () => unreachable);\n  let previous = Array.from({ length: left.length + 1 }, (_, index) => (index <= maxDistance ? index : unreachable));\n\n  for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) {\n    const current = Array.from({ length: left.length + 1 }, () => unreachable);\n    if (rightIndex <= maxDistance) current[0] = rightIndex;\n    const start = Math.max(1, rightIndex - maxDistance);\n    const end = Math.min(left.length, rightIndex + maxDistance);\n    for (let leftIndex = start; leftIndex <= end; leftIndex += 1) {\n      const substitutionCost = left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1;\n      current[leftIndex] = Math.min(\n        (previous[leftIndex] ?? unreachable) + 1,\n        (current[leftIndex - 1] ?? unreachable) + 1,\n        (previous[leftIndex - 1] ?? unreachable) + substitutionCost,\n      );\n      if (\n        leftIndex > 1 &&\n        rightIndex > 1 &&\n        left[leftIndex - 1] === right[rightIndex - 2] &&\n        left[leftIndex - 2] === right[rightIndex - 1]\n      ) {\n        current[leftIndex] = Math.min(\n          current[leftIndex] ?? unreachable,\n          (previousPrevious[leftIndex - 2] ?? unreachable) + 1,\n        );\n      }\n    }\n    previousPrevious = previous;\n    previous = current;\n  }\n\n  const distance = previous[left.length] ?? unreachable;\n  return distance <= maxDistance ? distance : undefined;\n}\n\nfunction allowedTypoDistance(queryLength: number): number {\n  if (queryLength < 5) return 0;\n  return queryLength < 10 ? 1 : 2;\n}\n\nfunction splitPathParts(value: string): string[] {\n  return value.split(PATH_PART_SEPARATOR).filter(Boolean);\n}\n\nfunction lengthPenalty(query: string, text: string): number {\n  return Math.max(0, text.length - query.length) / 100;\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport { mkdir, open, rename, rm, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\nimport type { KeyId } from \"@earendil-works/pi-tui\";\n\nexport const FILE_CONTEXT_SETTINGS_FILE = \"pi-file-context.json\";\nconst MAX_SETTINGS_BYTES = 64 * 1024;\n\nexport interface FileContextSettings {\n  openShortcut: KeyId | null;\n}\n\nexport interface LoadedFileContextSettings {\n  settings: FileContextSettings;\n  warning?: string;\n  invalidReason?: string;\n}\n\nexport interface UpdateFileContextSettingsOptions {\n  settingsPath?: string;\n  signal?: AbortSignal;\n  beforeRename?: (temporaryPath: string, settingsPath: string) => Promise<void>;\n}\n\nexport const DEFAULT_FILE_CONTEXT_SETTINGS: FileContextSettings = {\n  openShortcut: \"ctrl+shift+x\",\n};\n\nconst MODIFIERS = new Set([\"ctrl\", \"shift\", \"alt\", \"super\"]);\nconst BASE_KEYS = new Set([\n  ...\"abcdefghijklmnopqrstuvwxyz0123456789\",\n  \"`\",\n  \"-\",\n  \"=\",\n  \"[\",\n  \"]\",\n  \"\\\\\",\n  \";\",\n  \"'\",\n  \",\",\n  \".\",\n  \"/\",\n  \"!\",\n  \"@\",\n  \"#\",\n  \"$\",\n  \"%\",\n  \"^\",\n  \"&\",\n  \"*\",\n  \"(\",\n  \")\",\n  \"_\",\n  \"+\",\n  \"|\",\n  \"~\",\n  \"{\",\n  \"}\",\n  \":\",\n  \"<\",\n  \">\",\n  \"?\",\n  \"escape\",\n  \"esc\",\n  \"enter\",\n  \"return\",\n  \"tab\",\n  \"space\",\n  \"backspace\",\n  \"delete\",\n  \"insert\",\n  \"clear\",\n  \"home\",\n  \"end\",\n  \"pageup\",\n  \"pagedown\",\n  \"up\",\n  \"down\",\n  \"left\",\n  \"right\",\n  ...Array.from({ length: 12 }, (_unused, index) => `f${index + 1}`),\n]);\n\ntype SettingsDocument = Record<string, unknown>;\ntype SettingsSnapshot =\n  | { kind: \"missing\" }\n  | { kind: \"invalid\"; reason: string; warning: string }\n  | { kind: \"loaded\"; document: SettingsDocument; settings: FileContextSettings };\n\nconst mutationQueues = new Map<string, Promise<void>>();\n\nexport function fileContextSettingsPath(): string {\n  return join(getAgentDir(), FILE_CONTEXT_SETTINGS_FILE);\n}\n\nexport async function loadFileContextSettings(\n  settingsPath = fileContextSettingsPath(),\n): Promise<LoadedFileContextSettings> {\n  await awaitFileContextSettingsWrites(settingsPath);\n  const snapshot = await readSettingsSnapshot(settingsPath);\n  if (snapshot.kind === \"loaded\") return { settings: snapshot.settings };\n  if (snapshot.kind === \"missing\") {\n    return { settings: { ...DEFAULT_FILE_CONTEXT_SETTINGS } };\n  }\n  return {\n    settings: { ...DEFAULT_FILE_CONTEXT_SETTINGS },\n    warning: snapshot.warning,\n    invalidReason: snapshot.reason,\n  };\n}\n\nexport function updateFileContextSettings(\n  openShortcut: KeyId | null,\n  options: UpdateFileContextSettingsOptions = {},\n): Promise<FileContextSettings> {\n  const settingsPath = options.settingsPath ?? fileContextSettingsPath();\n  return enqueueMutation(settingsPath, async () => {\n    options.signal?.throwIfAborted();\n    const snapshot = await readSettingsSnapshot(settingsPath);\n    if (snapshot.kind === \"invalid\") {\n      throw new Error(`File Context settings are invalid: ${snapshot.reason}`);\n    }\n    const updated: SettingsDocument = {\n      ...(snapshot.kind === \"loaded\" ? snapshot.document : {}),\n      openShortcut,\n    };\n    const settings = normalizeFileContextSettings(updated);\n    if (!settings) throw new Error(\"File Context settings update is invalid\");\n    await publishSettings(settingsPath, updated, options);\n    return settings;\n  });\n}\n\nexport async function awaitFileContextSettingsWrites(settingsPath = fileContextSettingsPath()): Promise<void> {\n  await mutationQueues.get(settingsPath);\n}\n\nexport function normalizeKeyId(value: unknown): KeyId | undefined {\n  if (typeof value !== \"string\") return undefined;\n  const normalized = value.trim().toLowerCase();\n  const base = [...BASE_KEYS]\n    .sort((left, right) => right.length - left.length)\n    .find((candidate) => normalized === candidate || normalized.endsWith(`+${candidate}`));\n  if (!base) return undefined;\n  const prefix = normalized.slice(0, normalized.length - base.length);\n  if (!prefix) return base as KeyId;\n  if (/^f(?:[1-9]|1[0-2])$/.test(base) || !prefix.endsWith(\"+\")) return undefined;\n  const modifiers = prefix.slice(0, -1).split(\"+\");\n  if (\n    modifiers.length === 0 ||\n    modifiers.some((modifier) => !MODIFIERS.has(modifier)) ||\n    new Set(modifiers).size !== modifiers.length\n  ) {\n    return undefined;\n  }\n  return normalized as KeyId;\n}\n\nfunction normalizeFileContextSettings(value: unknown): FileContextSettings | undefined {\n  if (!isSettingsDocument(value)) return undefined;\n  if (!Object.hasOwn(value, \"openShortcut\")) {\n    return { ...DEFAULT_FILE_CONTEXT_SETTINGS };\n  }\n  const openShortcut = Reflect.get(value, \"openShortcut\");\n  if (openShortcut === null) return { openShortcut: null };\n  const normalized = normalizeKeyId(openShortcut);\n  return normalized ? { openShortcut: normalized } : undefined;\n}\n\nfunction enqueueMutation<T>(settingsPath: string, mutation: () => Promise<T>): Promise<T> {\n  const previous = mutationQueues.get(settingsPath) ?? Promise.resolve();\n  const result = previous.then(mutation, mutation);\n  const settled = result.then(\n    () => undefined,\n    () => undefined,\n  );\n  mutationQueues.set(settingsPath, settled);\n  void settled.finally(() => {\n    if (mutationQueues.get(settingsPath) === settled) mutationQueues.delete(settingsPath);\n  });\n  return result;\n}\n\nasync function readSettingsSnapshot(settingsPath: string): Promise<SettingsSnapshot> {\n  let source: string;\n  try {\n    source = await readSettingsContents(settingsPath);\n  } catch (error: unknown) {\n    if (isNodeError(error) && error.code === \"ENOENT\") return { kind: \"missing\" };\n    const reason = safeReadError(error);\n    return {\n      kind: \"invalid\",\n      reason,\n      warning: `Cannot read File Context settings: ${reason}`,\n    };\n  }\n\n  let document: unknown;\n  try {\n    document = JSON.parse(source) as unknown;\n  } catch (error: unknown) {\n    return {\n      kind: \"invalid\",\n      reason: \"invalid JSON\",\n      warning: `Cannot parse File Context settings: ${formatError(error)}`,\n    };\n  }\n  if (!isSettingsDocument(document)) {\n    return {\n      kind: \"invalid\",\n      reason: \"settings must contain a JSON object\",\n      warning: \"File Context settings must contain a JSON object.\",\n    };\n  }\n  const settings = normalizeFileContextSettings(document);\n  if (!settings) {\n    return {\n      kind: \"invalid\",\n      reason: 'setting \"openShortcut\" must be a valid Pi key string or null',\n      warning: 'File Context setting \"openShortcut\" must be a valid Pi key string or null.',\n    };\n  }\n  return { kind: \"loaded\", document, settings };\n}\n\nasync function readSettingsContents(settingsPath: string): Promise<string> {\n  const flags = constants.O_RDONLY | (constants.O_NONBLOCK ?? 0) | (constants.O_NOFOLLOW ?? 0);\n  const handle = await open(settingsPath, flags);\n  try {\n    const stats = await handle.stat();\n    if (!stats.isFile()) throw new Error(\"settings path is not a regular file\");\n    if (stats.size > MAX_SETTINGS_BYTES) {\n      throw new Error(`settings file exceeds ${MAX_SETTINGS_BYTES} bytes`);\n    }\n    const buffer = Buffer.alloc(MAX_SETTINGS_BYTES + 1);\n    let offset = 0;\n    while (offset < buffer.byteLength) {\n      const { bytesRead } = await handle.read(buffer, offset, buffer.byteLength - offset, offset);\n      if (bytesRead === 0) break;\n      offset += bytesRead;\n    }\n    if (offset > MAX_SETTINGS_BYTES) {\n      throw new Error(`settings file exceeds ${MAX_SETTINGS_BYTES} bytes`);\n    }\n    try {\n      return new TextDecoder(\"utf-8\", { fatal: true }).decode(buffer.subarray(0, offset));\n    } catch {\n      throw new Error(\"settings file is not valid UTF-8\");\n    }\n  } finally {\n    await handle.close();\n  }\n}\n\nasync function publishSettings(\n  settingsPath: string,\n  document: SettingsDocument,\n  options: UpdateFileContextSettingsOptions,\n): Promise<void> {\n  options.signal?.throwIfAborted();\n  const contents = `${JSON.stringify(document, null, 2)}\\n`;\n  if (Buffer.byteLength(contents, \"utf8\") > MAX_SETTINGS_BYTES) {\n    throw new Error(`settings document exceeds ${MAX_SETTINGS_BYTES} bytes`);\n  }\n  const directory = dirname(settingsPath);\n  await mkdir(directory, { recursive: true });\n  options.signal?.throwIfAborted();\n  const temporaryPath = join(directory, `.${basename(settingsPath)}.${process.pid}.${randomUUID()}.tmp`);\n  try {\n    await writeFile(temporaryPath, contents, {\n      encoding: \"utf8\",\n      flag: \"wx\",\n      mode: 0o600,\n      signal: options.signal,\n    });\n    await options.beforeRename?.(temporaryPath, settingsPath);\n    options.signal?.throwIfAborted();\n    await rename(temporaryPath, settingsPath);\n  } finally {\n    await rm(temporaryPath, { force: true }).catch(() => undefined);\n  }\n}\n\nfunction isSettingsDocument(value: unknown): value is SettingsDocument {\n  return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n  return error instanceof Error && \"code\" in error;\n}\n\nfunction safeReadError(error: unknown): string {\n  if (isNodeError(error) && error.code === \"ELOOP\") return \"settings path is not a regular file\";\n  return formatError(error);\n}\n\nfunction formatError(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { KeyId } from \"@earendil-works/pi-tui\";\nimport type { RunMenuResult } from \"@narumitw/pi-tui-kit\";\nimport { normalizeKeyId } from \"./file-context-settings.js\";\n\nexport interface FileContextMenuQuote {\n  id: string;\n  path: string;\n  startLine: number;\n  endLine: number;\n  text: string;\n}\n\nexport interface FileContextMenuState {\n  quotes: readonly FileContextMenuQuote[];\n  shortcut: string | null;\n  maximumQuotes: number;\n  maximumBytes: number;\n  totalBytes: number;\n  settingsPath: string;\n  settingsInvalidReason?: string;\n}\n\nexport type FileContextMenuAddResult = \"stay\" | \"close\";\n\nexport type FileContextMenuRemovalResult =\n  | { kind: \"removed\"; quote: FileContextMenuQuote; remaining: number }\n  | { kind: \"missing\" };\n\nexport interface FileContextMenuOptions {\n  start?: \"main\" | \"remove\";\n  signal: AbortSignal;\n  isCurrent(): boolean;\n  getState(): FileContextMenuState | Promise<FileContextMenuState>;\n  addQuote(signal: AbortSignal): FileContextMenuAddResult | Promise<FileContextMenuAddResult>;\n  removeQuote(id: string, signal: AbortSignal): FileContextMenuRemovalResult | Promise<FileContextMenuRemovalResult>;\n  saveShortcut(shortcut: KeyId | null, signal: AbortSignal): void | Promise<void>;\n}\n\ntype Screen = \"main\" | \"selected\" | \"quote\" | \"settings\" | \"shortcut\" | \"status\" | \"help\";\ntype Action = \"add\" | \"review\" | \"remove\" | \"open-shortcut\" | \"set-shortcut\";\n\nexport async function showFileContextMenu(\n  ctx: ExtensionCommandContext,\n  options: FileContextMenuOptions,\n): Promise<RunMenuResult> {\n  const { defineMenu, runMenu } = await import(\"@narumitw/pi-tui-kit\");\n  if (!options.isCurrent() || options.signal.aborted) return { kind: \"stale\" };\n\n  let addRequested = false;\n  let selectedQuoteId: string | undefined;\n  const menu = defineMenu<FileContextMenuState, Screen, Action, ExtensionCommandContext>({\n    start: options.start === \"remove\" ? \"selected\" : \"main\",\n    screens: {\n      main: ({ state }) => ({\n        kind: \"actions\",\n        title: \"File Context\",\n        lines: [\n          `Next prompt context: ${state.quotes.length}/${state.maximumQuotes} snippets \u00B7 ~${estimateTokens(state.totalBytes)} tokens`,\n          `Shortcut: ${formatShortcut(state.shortcut)}`,\n        ],\n        items: [\n          {\n            id: \"add\",\n            label: \"Add context snippet\",\n            description: \"Browse project files and select lines\",\n            action: \"add\",\n            busyLabel: \"Scanning project files\",\n            disabled: addDisabledReason(state) !== undefined,\n            disabledReason: addDisabledReason(state),\n          },\n          {\n            id: \"selected\",\n            label: `Review selected context (${state.quotes.length})`,\n            description: \"Preview exact snapshots before removing them\",\n            to: \"selected\",\n            disabled: state.quotes.length === 0,\n            disabledReason: state.quotes.length === 0 ? \"No context selected for the next prompt\" : undefined,\n          },\n          {\n            id: \"settings\",\n            label: \"Settings\",\n            description: \"Configure the shortcut used to open File Context\",\n            to: \"settings\",\n            disabled: state.quotes.length > 0,\n            disabledReason:\n              state.quotes.length > 0\n                ? \"Submit or remove selected context first; applying a shortcut reloads Pi\"\n                : undefined,\n          },\n          {\n            id: \"status\",\n            label: \"Status\",\n            description: \"Review selected context, limits, and active settings\",\n            to: \"status\",\n          },\n          {\n            id: \"help\",\n            label: \"Help\",\n            description: \"Review shortcuts and attachment behavior\",\n            to: \"help\",\n          },\n        ],\n        hint: \"close\",\n      }),\n      selected: ({ state }) =>\n        state.quotes.length === 0\n          ? {\n              kind: \"detail\",\n              title: \"Selected context\",\n              lines: [\"No context selected for the next prompt.\"],\n              hint: \"back\",\n            }\n          : {\n              kind: \"choice\",\n              title: \"Selected context\",\n              lines: [`${state.quotes.length} snippets \u00B7 Enter reviews the exact snapshot before removal`],\n              items: state.quotes.map((quote, index) => ({\n                id: quote.id,\n                label: `${index + 1}. ${quote.path}`,\n                description: `lines ${quote.startLine}-${quote.endLine} \u00B7 ~${estimateTokens(Buffer.byteLength(quote.text, \"utf8\"))} tokens`,\n                details: [`Lines ${quote.startLine}-${quote.endLine} \u00B7 Preview: ${singleLinePreview(quote.text)}`],\n              })),\n              action: \"review\",\n              viewportSize: 8,\n              hint: \"back\",\n            },\n      quote: ({ state }) => {\n        const quote = state.quotes.find((candidate) => candidate.id === selectedQuoteId);\n        if (!quote) {\n          return {\n            kind: \"detail\",\n            title: \"Review context snippet\",\n            lines: [\"That snippet is no longer selected. Go back to refresh the list.\"],\n            hint: \"back\",\n          };\n        }\n        return {\n          kind: \"review\",\n          title: \"Review context snippet\",\n          lines: [\n            quote.path,\n            `Lines ${quote.startLine}-${quote.endLine} \u00B7 ~${estimateTokens(Buffer.byteLength(quote.text, \"utf8\"))} tokens`,\n          ],\n          content: quote.text,\n          format: { kind: \"text\" },\n          viewportSize: \"adaptive\",\n          confirm: {\n            id: \"remove\",\n            label: \"Remove from next prompt\",\n            action: \"remove\",\n          },\n          hint: \"back\",\n        };\n      },\n      settings: ({ state }) =>\n        state.settingsInvalidReason\n          ? {\n              kind: \"detail\",\n              title: \"File Context Settings \u00B7 Read only\",\n              lines: [\n                `Invalid settings file. Fix ${safeTerminalText(state.settingsPath)} before saving.`,\n                safeTerminalText(state.settingsInvalidReason),\n              ],\n              hint: \"back\",\n            }\n          : {\n              kind: \"settings\",\n              title: \"File Context Settings\",\n              lines: [\n                `User settings \u00B7 ${safeTerminalText(state.settingsPath)}`,\n                \"Saving reloads Pi so the new shortcut becomes active.\",\n              ],\n              items: [\n                {\n                  id: \"openShortcut\",\n                  label: \"Open shortcut\",\n                  description: \"Set the global shortcut used to open the file browser.\",\n                  currentValue: state.shortcut ?? \"none\",\n                  action: \"open-shortcut\",\n                },\n              ],\n              hint: \"back\",\n            },\n      shortcut: ({ state }) => ({\n        kind: \"input\",\n        title: \"File Context shortcut\",\n        lines: [\n          `Configured: ${state.shortcut ?? \"none\"}`,\n          \"Use a Pi key identifier such as ctrl+shift+x or f8.\",\n          \"Submit an empty value to disable the shortcut.\",\n        ],\n        placeholder: state.shortcut ?? \"\",\n        action: \"set-shortcut\",\n        hint: \"back\",\n      }),\n      status: ({ state }) => ({\n        kind: \"detail\",\n        title: \"File Context Status\",\n        lines: [\n          `Next prompt context: ${state.quotes.length}/${state.maximumQuotes} snippets`,\n          `Estimated context: ~${estimateTokens(state.totalBytes)} tokens \u00B7 ${state.totalBytes}/${state.maximumBytes} bytes`,\n          `Open shortcut: ${state.shortcut ?? \"none\"}`,\n          `User settings: ${safeTerminalText(state.settingsPath)}`,\n          ...(state.settingsInvalidReason\n            ? [`Settings warning: ${safeTerminalText(state.settingsInvalidReason)}`]\n            : []),\n        ],\n        hint: \"back\",\n      }),\n      help: () => ({\n        kind: \"detail\",\n        title: \"File Context help\",\n        lines: [\n          \"Add context snippet opens the project browser. Select lines and press Enter to add and close, or A to add and keep browsing.\",\n          \"Selected context is attached in order to your next prompt, then cleared together.\",\n          \"Review selected context opens each exact snapshot before offering removal.\",\n          \"The configured shortcut and /file-context browse open the browser directly.\",\n          \"Settings saves the shortcut and reloads Pi; Status shows active limits and configuration.\",\n          \"Escape goes back. Ctrl+C closes File Context. Cancelling never changes selected context.\",\n        ],\n        hint: \"back\",\n      }),\n    },\n    actions: {\n      add: () => {\n        addRequested = true;\n        return { kind: \"close\" };\n      },\n      review: ({ itemId }) => {\n        selectedQuoteId = itemId;\n        return { kind: \"to\", screen: \"quote\" };\n      },\n      \"open-shortcut\": async () => ({ kind: \"to\", screen: \"shortcut\" }),\n      \"set-shortcut\": async ({ ctx: actionCtx, value, signal }) => {\n        const raw = value?.trim() || null;\n        const normalized = raw ? normalizeKeyId(raw) : undefined;\n        if (raw && !normalized) {\n          actionCtx.ui.notify(\n            `Invalid key identifier: ${safeTerminalText(raw)}. Use a Pi key identifier like ctrl+shift+x.`,\n            \"warning\",\n          );\n          return { kind: \"stay\" };\n        }\n        const shortcut = normalized ?? null;\n        try {\n          await options.saveShortcut(shortcut, signal);\n        } catch (error: unknown) {\n          if (!signal.aborted && options.isCurrent()) {\n            actionCtx.ui.notify(\n              `Could not save File Context settings; the previous shortcut remains: ${safeTerminalText(formatError(error))}`,\n              \"error\",\n            );\n          }\n          return { kind: \"stay\" };\n        }\n        if (signal.aborted || !options.isCurrent()) return { kind: \"close\" };\n        actionCtx.ui.notify(\n          shortcut\n            ? `Saved File Context shortcut ${safeTerminalText(shortcut)}. Reloading Pi\u2026`\n            : \"Disabled the File Context shortcut. Reloading Pi\u2026\",\n          \"info\",\n        );\n        try {\n          await actionCtx.reload();\n          return { kind: \"close\" };\n        } catch (error: unknown) {\n          if (!signal.aborted && options.isCurrent()) {\n            actionCtx.ui.notify(\n              `File Context settings were saved, but Pi could not reload; run /reload to apply them: ${safeTerminalText(formatError(error))}`,\n              \"error\",\n            );\n          }\n          return { kind: \"close\" };\n        }\n      },\n      remove: async ({ signal }) => {\n        const itemId = selectedQuoteId;\n        if (!itemId) return { kind: \"back\" };\n        const result = await options.removeQuote(itemId, signal);\n        if (signal.aborted || !options.isCurrent()) return { kind: \"close\" };\n        if (result.kind === \"missing\") {\n          ctx.ui.notify(\"That snippet is no longer selected. The list was refreshed.\", \"warning\");\n          return { kind: \"stay\" };\n        }\n        ctx.ui.notify(\n          `Removed from next prompt context: ${safeTerminalText(result.quote.path)} \u00B7 lines ${result.quote.startLine}-${result.quote.endLine}.`,\n          \"info\",\n        );\n        selectedQuoteId = undefined;\n        return { kind: \"back\" };\n      },\n    },\n  });\n\n  while (options.isCurrent() && !options.signal.aborted) {\n    addRequested = false;\n    const result = await runMenu(ctx, menu, {\n      getState: () => options.getState(),\n      signal: options.signal,\n      isCurrent: options.isCurrent,\n      onError: (_menuContext, error) => {\n        ctx.ui.notify(\n          `File Context menu failed: ${safeTerminalText(formatError(error))}. Selected context was kept; try again.`,\n          \"error\",\n        );\n      },\n      onUnsupportedMode: (_menuContext, mode) => {\n        ctx.ui.notify(`File Context is unavailable in ${mode} mode.`, \"warning\");\n      },\n    });\n    if (!addRequested || result.kind !== \"closed\") return result;\n    const addResult = await options.addQuote(options.signal);\n    if (!options.isCurrent() || options.signal.aborted) return { kind: \"stale\" };\n    if (addResult === \"close\") return { kind: \"closed\", reason: \"close\" };\n  }\n  return { kind: \"stale\" };\n}\n\nfunction addDisabledReason(state: FileContextMenuState): string | undefined {\n  if (state.quotes.length >= state.maximumQuotes) {\n    return `The ${state.maximumQuotes}-snippet limit is reached; review selected context first`;\n  }\n  if (state.totalBytes >= state.maximumBytes) {\n    return `The ${formatBytes(state.maximumBytes)} context limit is reached; review selected context first`;\n  }\n  return undefined;\n}\n\nfunction formatShortcut(shortcut: string | null): string {\n  return shortcut ? shortcut.toUpperCase() : \"Disabled (use /file-context browse)\";\n}\n\nfunction singleLinePreview(text: string): string {\n  const normalized = text.replaceAll(\"\\r\\n\", \"\\n\").replaceAll(\"\\r\", \"\\n\").split(\"\\n\").join(\" \u21B5 \");\n  const characters = [...normalized];\n  if (characters.length === 0) return \"(empty)\";\n  return characters.length <= 200 ? normalized : `${characters.slice(0, 199).join(\"\")}\u2026`;\n}\n\nfunction estimateTokens(bytes: number): number {\n  return bytes === 0 ? 0 : Math.max(1, Math.ceil(bytes / 4));\n}\n\nfunction formatBytes(bytes: number): string {\n  return bytes % 1_000 === 0 ? `${bytes / 1_000} KB` : `${bytes} bytes`;\n}\n\nfunction safeTerminalText(text: string): string {\n  return [...text]\n    .map((character) => {\n      const code = character.charCodeAt(0);\n      return code <= 31 || (code >= 127 && code <= 159) ? `\\\\x${code.toString(16).padStart(2, \"0\")}` : character;\n    })\n    .join(\"\");\n}\n\nfunction formatError(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n", "import { execFile } from \"node:child_process\";\nimport { realpath } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\nconst GIT_TIMEOUT_MS = 5_000;\nconst GIT_MAX_BUFFER = 1_100_000;\nconst MAX_HISTORY_ENTRIES = 20;\n\nexport interface GitProjectInfo {\n  repositoryRoot: string;\n  projectPrefix: string;\n  branch: string;\n  head: string;\n  dirty: boolean;\n}\n\nexport interface GitFileStatus {\n  code: string;\n  label: string;\n  staged: boolean;\n  unstaged: boolean;\n  untracked: boolean;\n  ignored: boolean;\n  conflicted: boolean;\n}\n\nexport interface GitDiffHunk {\n  header: string;\n  oldStart: number;\n  oldCount: number;\n  newStart: number;\n  newCount: number;\n  lines: string[];\n  changedLines: number[];\n}\n\nexport interface GitFileContext {\n  status: GitFileStatus | undefined;\n  blob: string | undefined;\n  hunks: GitDiffHunk[];\n}\n\nexport interface GitBlameInfo {\n  commit: string;\n  author: string;\n  authorTime: number | undefined;\n  summary: string;\n  committed: boolean;\n}\n\nexport interface GitHistoryEntry {\n  commit: string;\n  author: string;\n  authorTime: number;\n  summary: string;\n  path: string;\n}\n\nexport interface GitRevisionFile {\n  path: string;\n  lines: string[];\n  revision: string;\n  commit: string;\n  blob: string | undefined;\n}\n\nexport class GitContext {\n  private readonly statusMap: Map<string, GitFileStatus>;\n\n  constructor(\n    readonly projectRoot: string,\n    readonly project: GitProjectInfo,\n    statuses: ReadonlyMap<string, GitFileStatus>,\n  ) {\n    this.statusMap = new Map(statuses);\n  }\n\n  get statuses(): ReadonlyMap<string, GitFileStatus> {\n    return this.statusMap;\n  }\n\n  async getFileContext(projectPath: string, signal?: AbortSignal): Promise<GitFileContext> {\n    this.assertProjectPath(projectPath);\n    const [blobResult, diffResult] = await Promise.all([\n      this.run([\"rev-parse\", \"--verify\", `HEAD:${this.repositoryPath(projectPath)}`], true, signal),\n      this.run([\"diff\", \"--no-ext-diff\", \"--no-textconv\", \"--unified=3\", \"HEAD\", \"--\", projectPath], true, signal),\n    ]);\n    signal?.throwIfAborted();\n    return {\n      status: this.statusMap.get(projectPath),\n      blob: blobResult.ok ? blobResult.stdout.trim() || undefined : undefined,\n      hunks: diffResult.ok ? parseUnifiedDiff(diffResult.stdout) : [],\n    };\n  }\n\n  async refreshFileContext(projectPath: string, signal?: AbortSignal): Promise<GitFileContext> {\n    const [fileContext, statusResult] = await Promise.all([\n      this.getFileContext(projectPath, signal),\n      this.run(\n        [\n          \"-c\",\n          \"status.relativePaths=true\",\n          \"status\",\n          \"--porcelain=v1\",\n          \"-z\",\n          \"--untracked-files=all\",\n          \"--ignored=traditional\",\n          \"--\",\n          \".\",\n        ],\n        true,\n        signal,\n      ),\n    ]);\n    signal?.throwIfAborted();\n    if (!statusResult.ok) return fileContext;\n    const statuses = parseStatuses(statusResult.stdout, this.project.projectPrefix);\n    this.statusMap.clear();\n    for (const [path, status] of statuses) this.statusMap.set(path, status);\n    this.project.dirty = [...statuses.values()].some((status) => !status.ignored);\n    return { ...fileContext, status: this.statusMap.get(projectPath) };\n  }\n\n  async getBlame(\n    projectPath: string,\n    line: number,\n    revision?: string,\n    signal?: AbortSignal,\n  ): Promise<GitBlameInfo | undefined> {\n    this.assertProjectPath(projectPath);\n    if (!Number.isSafeInteger(line) || line < 1) throw new Error(\"Blame line must be positive\");\n    if (revision && !/^[0-9a-f]{40}$/i.test(revision)) throw new Error(\"Invalid blame revision\");\n    const result = await this.run(\n      [\n        \"blame\",\n        \"--no-textconv\",\n        \"--line-porcelain\",\n        \"-L\",\n        `${line},${line}`,\n        ...(revision ? [revision] : []),\n        \"--\",\n        projectPath,\n      ],\n      true,\n      signal,\n    );\n    signal?.throwIfAborted();\n    if (!result.ok) return undefined;\n    return parseBlame(result.stdout);\n  }\n\n  async getHistory(projectPath: string, signal?: AbortSignal): Promise<GitHistoryEntry[]> {\n    this.assertProjectPath(projectPath);\n    const result = await this.run(\n      [\n        \"log\",\n        `--max-count=${MAX_HISTORY_ENTRIES}`,\n        \"--format=%x1e%H%x1f%an%x1f%at%x1f%s\",\n        \"--name-only\",\n        \"-z\",\n        \"--follow\",\n        \"--\",\n        projectPath,\n      ],\n      true,\n      signal,\n    );\n    signal?.throwIfAborted();\n    return result.ok ? parseHistory(result.stdout) : [];\n  }\n\n  async loadRevision(\n    projectPath: string,\n    revision: string,\n    historicalPath?: string,\n    signal?: AbortSignal,\n  ): Promise<GitRevisionFile> {\n    this.assertProjectPath(projectPath);\n    const normalizedRevision = revision.trim();\n    if (!normalizedRevision || /[\\0\\r\\n]/.test(normalizedRevision)) {\n      throw new Error(\"Revision is required\");\n    }\n    const resolved = await this.run(\n      [\"rev-parse\", \"--verify\", \"--end-of-options\", `${normalizedRevision}^{commit}`],\n      true,\n      signal,\n    );\n    if (!resolved.ok || !/^[0-9a-f]{40}$/i.test(resolved.stdout.trim())) {\n      throw new Error(`Unknown Git revision: ${normalizedRevision}`);\n    }\n    signal?.throwIfAborted();\n    const commit = resolved.stdout.trim().toLowerCase();\n    const repositoryPath = historicalPath\n      ? this.assertRepositoryPath(historicalPath)\n      : this.repositoryPath(projectPath);\n    const [contentsResult, blobResult] = await Promise.all([\n      this.run([\"show\", `${commit}:${repositoryPath}`], true, signal),\n      this.run([\"rev-parse\", \"--verify\", `${commit}:${repositoryPath}`], true, signal),\n    ]);\n    signal?.throwIfAborted();\n    if (!contentsResult.ok) {\n      throw new Error(`${projectPath} does not exist at ${normalizedRevision}`);\n    }\n    if (Buffer.byteLength(contentsResult.stdout, \"utf8\") > 1_000_000) {\n      throw new Error(`${projectPath} exceeds 1000000 bytes at ${normalizedRevision}`);\n    }\n    if (contentsResult.stdout.includes(\"\\0\")) {\n      throw new Error(`${projectPath} appears to be binary at ${normalizedRevision}`);\n    }\n    return {\n      path: historicalPath ?? projectPath,\n      lines: normalizeLines(contentsResult.stdout),\n      revision: normalizedRevision,\n      commit,\n      blob: blobResult.ok ? blobResult.stdout.trim() || undefined : undefined,\n    };\n  }\n\n  private async run(args: string[], allowFailure = false, signal?: AbortSignal): Promise<GitResult> {\n    return runGit(this.projectRoot, args, allowFailure, signal);\n  }\n\n  private repositoryPath(projectPath: string): string {\n    return `${this.project.projectPrefix}${projectPath}`.replaceAll(\"\\\\\", \"/\");\n  }\n\n  private assertRepositoryPath(repositoryPath: string): string {\n    const normalized = repositoryPath.replaceAll(\"\\\\\", \"/\");\n    if (!normalized || isAbsolute(normalized) || normalized.includes(\"\\0\")) {\n      throw new Error(\"Invalid historical Git path\");\n    }\n    const candidate = resolve(this.project.repositoryRoot, normalized);\n    const result = relative(this.project.repositoryRoot, candidate);\n    if (result === \"..\" || result.startsWith(`..${sep}`)) {\n      throw new Error(\"Historical Git path is outside the repository\");\n    }\n    return normalized;\n  }\n\n  private assertProjectPath(projectPath: string): void {\n    if (!projectPath || isAbsolute(projectPath) || projectPath.includes(\"\\0\")) {\n      throw new Error(\"Invalid project path\");\n    }\n    const candidate = resolve(this.projectRoot, projectPath);\n    const result = relative(this.projectRoot, candidate);\n    if (result === \"..\" || result.startsWith(`..${sep}`)) {\n      throw new Error(\"Git path is outside the project\");\n    }\n  }\n}\n\nexport async function createGitContext(root: string, signal?: AbortSignal): Promise<GitContext | undefined> {\n  signal?.throwIfAborted();\n  const projectRoot = await realpath(root);\n  signal?.throwIfAborted();\n  const repositoryResult = await runGit(projectRoot, [\"rev-parse\", \"--show-toplevel\"], true, signal);\n  if (!repositoryResult.ok) return undefined;\n  const repositoryRoot = stripLineEnding(repositoryResult.stdout);\n  if (!repositoryRoot) return undefined;\n  const [prefixResult, headResult, branchResult, statusResult] = await Promise.all([\n    runGit(projectRoot, [\"rev-parse\", \"--show-prefix\"], true, signal),\n    runGit(projectRoot, [\"rev-parse\", \"--verify\", \"HEAD\"], true, signal),\n    runGit(projectRoot, [\"symbolic-ref\", \"--quiet\", \"--short\", \"HEAD\"], true, signal),\n    runGit(\n      projectRoot,\n      [\n        \"-c\",\n        \"status.relativePaths=true\",\n        \"status\",\n        \"--porcelain=v1\",\n        \"-z\",\n        \"--untracked-files=all\",\n        \"--ignored=traditional\",\n        \"--\",\n        \".\",\n      ],\n      true,\n      signal,\n    ),\n  ]);\n  signal?.throwIfAborted();\n  const head = headResult.ok ? headResult.stdout.trim().toLowerCase() : \"unborn\";\n  const branch = branchResult.ok ? branchResult.stdout.trim() : head === \"unborn\" ? \"unborn\" : head.slice(0, 12);\n  const projectPrefix = prefixResult.ok ? stripLineEnding(prefixResult.stdout) : \"\";\n  const statuses = statusResult.ok ? parseStatuses(statusResult.stdout, projectPrefix) : new Map();\n  return new GitContext(\n    projectRoot,\n    {\n      repositoryRoot,\n      projectPrefix,\n      branch,\n      head,\n      dirty: [...statuses.values()].some((status) => !status.ignored),\n    },\n    statuses,\n  );\n}\n\ninterface GitResult {\n  ok: boolean;\n  stdout: string;\n}\n\nasync function runGit(cwd: string, args: string[], allowFailure: boolean, signal?: AbortSignal): Promise<GitResult> {\n  try {\n    const { stdout } = await execFileAsync(\n      \"git\",\n      [\"--no-pager\", \"-c\", \"core.pager=cat\", \"-c\", \"core.fsmonitor=false\", ...args],\n      {\n        cwd,\n        encoding: \"utf8\",\n        timeout: GIT_TIMEOUT_MS,\n        maxBuffer: GIT_MAX_BUFFER,\n        signal,\n        env: {\n          ...process.env,\n          GIT_OPTIONAL_LOCKS: \"0\",\n          GIT_PAGER: \"cat\",\n          PAGER: \"cat\",\n        },\n      },\n    );\n    return { ok: true, stdout };\n  } catch (error: unknown) {\n    if (signal?.aborted) throw error;\n    if (allowFailure) return { ok: false, stdout: \"\" };\n    throw error;\n  }\n}\n\nfunction parseStatuses(output: string, projectPrefix: string): Map<string, GitFileStatus> {\n  const statuses = new Map<string, GitFileStatus>();\n  const records = output.split(\"\\0\");\n  for (let index = 0; index < records.length; index += 1) {\n    const record = records[index];\n    if (!record || record.length < 4) continue;\n    const code = record.slice(0, 2);\n    const repositoryPath = record.slice(3).replaceAll(\"\\\\\", \"/\");\n    const projectPath = projectPrefix\n      ? repositoryPath.startsWith(projectPrefix)\n        ? repositoryPath.slice(projectPrefix.length)\n        : undefined\n      : repositoryPath;\n    if (projectPath) statuses.set(projectPath, statusFromCode(code));\n    if (code.includes(\"R\") || code.includes(\"C\")) index += 1;\n  }\n  return new Map([...statuses].sort(([left], [right]) => compareStrings(left, right)));\n}\n\nfunction statusFromCode(code: string): GitFileStatus {\n  const conflicted = /^(DD|AU|UD|UA|DU|AA|UU)$/.test(code);\n  const untracked = code === \"??\";\n  const ignored = code === \"!!\";\n  const staged = !untracked && !ignored && code[0] !== \" \";\n  const unstaged = !untracked && !ignored && code[1] !== \" \";\n  let label: string;\n  if (conflicted) label = \"conflicted\";\n  else if (untracked) label = \"untracked\";\n  else if (ignored) label = \"ignored\";\n  else {\n    const character = unstaged ? code[1] : code[0];\n    const action =\n      character === \"A\"\n        ? \"added\"\n        : character === \"D\"\n          ? \"deleted\"\n          : character === \"R\"\n            ? \"renamed\"\n            : character === \"C\"\n              ? \"copied\"\n              : character === \"T\"\n                ? \"type changed\"\n                : \"modified\";\n    const location = staged && unstaged ? \"staged + unstaged\" : staged ? \"staged\" : \"unstaged\";\n    label = `${action} (${location})`;\n  }\n  return { code, label, staged, unstaged, untracked, ignored, conflicted };\n}\n\nfunction parseUnifiedDiff(output: string): GitDiffHunk[] {\n  const hunks: GitDiffHunk[] = [];\n  let current: GitDiffHunk | undefined;\n  let newLine = 0;\n  for (const line of output.replaceAll(\"\\r\\n\", \"\\n\").split(\"\\n\")) {\n    const match = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@(.*)$/.exec(line);\n    if (match) {\n      current = {\n        header: line,\n        oldStart: Number(match[1]),\n        oldCount: Number(match[2] ?? 1),\n        newStart: Number(match[3]),\n        newCount: Number(match[4] ?? 1),\n        lines: [line],\n        changedLines: [],\n      };\n      newLine = current.newStart;\n      hunks.push(current);\n      continue;\n    }\n    if (!current) continue;\n    current.lines.push(line);\n    if (line.startsWith(\"+\") && !line.startsWith(\"+++\")) {\n      current.changedLines.push(newLine);\n      newLine += 1;\n    } else if (!line.startsWith(\"-\") && !line.startsWith(\"\\\\\")) {\n      newLine += 1;\n    }\n  }\n  for (const hunk of hunks) {\n    while (hunk.lines.at(-1) === \"\") hunk.lines.pop();\n  }\n  return hunks;\n}\n\nfunction parseBlame(output: string): GitBlameInfo | undefined {\n  const lines = output.split(\"\\n\");\n  const commit = lines[0]?.split(\" \")[0];\n  if (!commit) return undefined;\n  const field = (name: string) => lines.find((line) => line.startsWith(`${name} `))?.slice(name.length + 1);\n  const authorTime = Number(field(\"author-time\"));\n  return {\n    commit,\n    author: field(\"author\") ?? \"Unknown\",\n    authorTime: Number.isFinite(authorTime) ? authorTime : undefined,\n    summary: field(\"summary\") ?? \"\",\n    committed: !/^0+$/.test(commit),\n  };\n}\n\nfunction parseHistory(output: string): GitHistoryEntry[] {\n  return output\n    .split(\"\\x1e\")\n    .filter(Boolean)\n    .flatMap((record) => {\n      const [metadata = \"\", ...pathRecords] = record.split(\"\\0\");\n      const [commit, author, authorTime, ...summaryParts] = metadata.replace(/^\\n+/, \"\").split(\"\\x1f\");\n      const path = pathRecords.map((value) => value.replace(/^\\n+/, \"\")).find(Boolean);\n      const time = Number(authorTime);\n      return commit && author && path && Number.isFinite(time)\n        ? [{ commit, author, authorTime: time, summary: summaryParts.join(\"\\x1f\"), path }]\n        : [];\n    });\n}\n\nfunction compareStrings(left: string, right: string): number {\n  return left < right ? -1 : left > right ? 1 : 0;\n}\n\nfunction stripLineEnding(value: string): string {\n  return value.endsWith(\"\\r\\n\") ? value.slice(0, -2) : value.endsWith(\"\\n\") ? value.slice(0, -1) : value;\n}\n\nfunction normalizeLines(contents: string): string[] {\n  if (contents === \"\") return [];\n  const lines = contents.replaceAll(\"\\r\\n\", \"\\n\").replaceAll(\"\\r\", \"\\n\").split(\"\\n\");\n  if (lines.at(-1) === \"\") lines.pop();\n  return lines;\n}\n"],
  "mappings": "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",
  "names": ["constants", "lstat", "open", "realpath", "isAbsolute", "relative", "resolve", "sep", "Input", "Key", "matchesKey", "truncateToWidth", "visibleWidth", "visibleWidth", "visibleWidth", "isAbortError", "truncateToWidth", "truncateToWidth", "truncateToWidth", "escapeTerminalControls", "truncateToWidth", "fitRows", "selection", "capacity", "Input", "matchesKey", "Key", "visibleWidth", "fitRows", "truncateToWidth", "formatError", "isAbortError", "getAgentDir", "formatError", "estimateTokens", "safeTerminalText", "formatError", "realpath", "isAbsolute", "relative", "resolve", "sep", "realpath", "compareStrings", "resolve", "isAbsolute", "isInside", "formatError", "lstat", "open", "constants", "estimateTokens", "escapeTerminalControls", "formatError", "isAbortError", "compareStrings", "isInside", "relative", "sep", "isAbsolute"]
}
